LCOV - code coverage report
Current view: top level - sc/source/core/data - column2.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 638 898 71.0 %
Date: 2012-08-25 Functions: 44 52 84.6 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 597 1364 43.8 %

           Branch data     Line data    Source code
       1                 :            : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 :            : /*************************************************************************
       3                 :            :  *
       4                 :            :  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       5                 :            :  *
       6                 :            :  * Copyright 2000, 2010 Oracle and/or its affiliates.
       7                 :            :  *
       8                 :            :  * OpenOffice.org - a multi-platform office productivity suite
       9                 :            :  *
      10                 :            :  * This file is part of OpenOffice.org.
      11                 :            :  *
      12                 :            :  * OpenOffice.org is free software: you can redistribute it and/or modify
      13                 :            :  * it under the terms of the GNU Lesser General Public License version 3
      14                 :            :  * only, as published by the Free Software Foundation.
      15                 :            :  *
      16                 :            :  * OpenOffice.org is distributed in the hope that it will be useful,
      17                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      18                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      19                 :            :  * GNU Lesser General Public License version 3 for more details
      20                 :            :  * (a copy is included in the LICENSE file that accompanied this code).
      21                 :            :  *
      22                 :            :  * You should have received a copy of the GNU Lesser General Public License
      23                 :            :  * version 3 along with OpenOffice.org.  If not, see
      24                 :            :  * <http://www.openoffice.org/license.html>
      25                 :            :  * for a copy of the LGPLv3 License.
      26                 :            :  *
      27                 :            :  ************************************************************************/
      28                 :            : 
      29                 :            : #include "scitems.hxx"
      30                 :            : #include <editeng/eeitem.hxx>
      31                 :            : 
      32                 :            : #include <svx/algitem.hxx>
      33                 :            : #include <editeng/editobj.hxx>
      34                 :            : #include <editeng/editstat.hxx>
      35                 :            : #include <editeng/emphitem.hxx>
      36                 :            : #include <editeng/fhgtitem.hxx>
      37                 :            : #include <editeng/forbiddencharacterstable.hxx>
      38                 :            : #include <svx/rotmodit.hxx>
      39                 :            : #include <editeng/scripttypeitem.hxx>
      40                 :            : #include <editeng/unolingu.hxx>
      41                 :            : #include <editeng/justifyitem.hxx>
      42                 :            : #include <svl/zforlist.hxx>
      43                 :            : #include <svl/broadcast.hxx>
      44                 :            : #include <svl/listeneriter.hxx>
      45                 :            : #include <vcl/outdev.hxx>
      46                 :            : 
      47                 :            : #include "column.hxx"
      48                 :            : #include "cell.hxx"
      49                 :            : #include "document.hxx"
      50                 :            : #include "docpool.hxx"
      51                 :            : #include "attarray.hxx"
      52                 :            : #include "patattr.hxx"
      53                 :            : #include "cellform.hxx"
      54                 :            : #include "stlsheet.hxx"
      55                 :            : #include "rechead.hxx"
      56                 :            : #include "brdcst.hxx"
      57                 :            : #include "editutil.hxx"
      58                 :            : #include "subtotal.hxx"
      59                 :            : #include "markdata.hxx"
      60                 :            : #include "compiler.hxx"         // ScTokenArray GetCodeLen
      61                 :            : #include "dbdata.hxx"
      62                 :            : #include "fillinfo.hxx"
      63                 :            : #include "segmenttree.hxx"
      64                 :            : #include "docparam.hxx"
      65                 :            : 
      66                 :            : #include <math.h>
      67                 :            : 
      68                 :            : // -----------------------------------------------------------------------
      69                 :            : 
      70                 :            : // factor from font size to optimal cell height (text width)
      71                 :            : #define SC_ROT_BREAK_FACTOR     6
      72                 :            : 
      73                 :            : // -----------------------------------------------------------------------
      74                 :            : 
      75                 :      21020 : inline bool IsAmbiguousScript( sal_uInt8 nScript )
      76                 :            : {
      77                 :            :     //! move to a header file
      78                 :            :     return ( nScript != SCRIPTTYPE_LATIN &&
      79                 :            :              nScript != SCRIPTTYPE_ASIAN &&
      80 [ -  + ][ #  # ]:      21020 :              nScript != SCRIPTTYPE_COMPLEX );
                 [ #  # ]
      81                 :            : }
      82                 :            : 
      83                 :            : // -----------------------------------------------------------------------------------------
      84                 :            : 
      85                 :            : //
      86                 :            : //  Datei-Operationen
      87                 :            : //
      88                 :            : 
      89                 :            : // -----------------------------------------------------------------------------------------
      90                 :            : 
      91                 :            : 
      92                 :      10854 : long ScColumn::GetNeededSize( SCROW nRow, OutputDevice* pDev,
      93                 :            :                               double nPPTX, double nPPTY,
      94                 :            :                               const Fraction& rZoomX, const Fraction& rZoomY,
      95                 :            :                               bool bWidth, const ScNeededSizeOptions& rOptions )
      96                 :            : {
      97                 :      10854 :     long nValue=0;
      98                 :            :     SCSIZE nIndex;
      99         [ +  + ]:      10854 :     double nPPT = bWidth ? nPPTX : nPPTY;
     100 [ +  - ][ +  - ]:      10854 :     if (Search(nRow,nIndex))
     101                 :            :     {
     102                 :      10854 :         ScBaseCell* pCell = maItems[nIndex].pCell;
     103                 :      10854 :         const ScPatternAttr* pPattern = rOptions.pPattern;
     104         [ +  + ]:      10854 :         if (!pPattern)
     105         [ +  - ]:       7935 :             pPattern = pAttrArray->GetPattern( nRow );
     106                 :            : 
     107                 :            :         //      zusammengefasst?
     108                 :            :         //      Merge nicht in bedingter Formatierung
     109                 :            : 
     110         [ +  - ]:      10854 :         const ScMergeAttr*      pMerge = (const ScMergeAttr*)&pPattern->GetItem(ATTR_MERGE);
     111         [ +  - ]:      10854 :         const ScMergeFlagAttr*  pFlag = (const ScMergeFlagAttr*)&pPattern->GetItem(ATTR_MERGE_FLAG);
     112                 :            : 
     113         [ +  + ]:      10854 :         if ( bWidth )
     114                 :            :         {
     115         [ -  + ]:       7939 :             if ( pFlag->IsHorOverlapped() )
     116                 :          0 :                 return 0;
     117 [ +  + ][ -  + ]:       7939 :             if ( rOptions.bSkipMerged && pMerge->GetColMerge() > 1 )
                 [ -  + ]
     118                 :          0 :                 return 0;
     119                 :            :         }
     120                 :            :         else
     121                 :            :         {
     122         [ -  + ]:       2915 :             if ( pFlag->IsVerOverlapped() )
     123                 :          0 :                 return 0;
     124 [ +  - ][ -  + ]:       2915 :             if ( rOptions.bSkipMerged && pMerge->GetRowMerge() > 1 )
                 [ -  + ]
     125                 :          0 :                 return 0;
     126                 :            :         }
     127                 :            : 
     128                 :            :         //      bedingte Formatierung
     129                 :      10854 :         const SfxItemSet* pCondSet = NULL;
     130 [ +  - ][ +  + ]:      10854 :         if ( ((const SfxUInt32Item&)pPattern->GetItem(ATTR_CONDITIONAL)).GetValue() )
     131         [ +  - ]:       2550 :             pCondSet = pDocument->GetCondResult( nCol, nRow, nTab );
     132                 :            : 
     133                 :            :         //  Zeilenumbruch?
     134                 :            : 
     135                 :            :         const SfxPoolItem* pCondItem;
     136                 :            :         SvxCellHorJustify eHorJust;
     137 [ +  + ][ -  + ]:      10856 :         if (pCondSet &&
                 [ -  + ]
     138         [ +  - ]:          2 :                 pCondSet->GetItemState(ATTR_HOR_JUSTIFY, true, &pCondItem) == SFX_ITEM_SET)
     139                 :          0 :             eHorJust = (SvxCellHorJustify)((const SvxHorJustifyItem*)pCondItem)->GetValue();
     140                 :            :         else
     141                 :            :             eHorJust = (SvxCellHorJustify)((const SvxHorJustifyItem&)
     142         [ +  - ]:      10854 :                                             pPattern->GetItem( ATTR_HOR_JUSTIFY )).GetValue();
     143                 :            :         bool bBreak;
     144         [ +  + ]:      10854 :         if ( eHorJust == SVX_HOR_JUSTIFY_BLOCK )
     145                 :        983 :             bBreak = true;
     146 [ +  + ][ -  + ]:       9873 :         else if ( pCondSet &&
                 [ -  + ]
     147         [ +  - ]:          2 :                     pCondSet->GetItemState(ATTR_LINEBREAK, true, &pCondItem) == SFX_ITEM_SET)
     148                 :          0 :             bBreak = ((const SfxBoolItem*)pCondItem)->GetValue();
     149                 :            :         else
     150         [ +  - ]:       9871 :             bBreak = ((const SfxBoolItem&)pPattern->GetItem(ATTR_LINEBREAK)).GetValue();
     151                 :            : 
     152 [ +  - ][ +  + ]:      10854 :         if (pCell->HasValueData())
     153                 :            :             // Cell has a value.  Disable line break.
     154                 :       9191 :             bBreak = false;
     155                 :            : 
     156                 :            :         //  get other attributes from pattern and conditional formatting
     157                 :            : 
     158         [ +  - ]:      10854 :         SvxCellOrientation eOrient = pPattern->GetCellOrientation( pCondSet );
     159                 :            :         bool bAsianVertical = ( eOrient == SVX_ORIENTATION_STACKED &&
     160 [ -  + ][ #  # ]:      10854 :                 ((const SfxBoolItem&)pPattern->GetItem( ATTR_VERTICAL_ASIAN, pCondSet )).GetValue() );
                 [ #  # ]
     161         [ -  + ]:      10854 :         if ( bAsianVertical )
     162                 :          0 :             bBreak = false;
     163                 :            : 
     164 [ +  + ][ +  + ]:      10854 :         if ( bWidth && bBreak )     // after determining bAsianVertical (bBreak may be reset)
     165                 :          3 :             return 0;
     166                 :            : 
     167                 :      10851 :         long nRotate = 0;
     168                 :      10851 :         SvxRotateMode eRotMode = SVX_ROTATE_MODE_STANDARD;
     169         [ +  + ]:      10851 :         if ( eOrient == SVX_ORIENTATION_STANDARD )
     170                 :            :         {
     171 [ +  + ][ -  + ]:       9915 :             if (pCondSet &&
                 [ -  + ]
     172         [ +  - ]:          2 :                     pCondSet->GetItemState(ATTR_ROTATE_VALUE, true, &pCondItem) == SFX_ITEM_SET)
     173                 :          0 :                 nRotate = ((const SfxInt32Item*)pCondItem)->GetValue();
     174                 :            :             else
     175         [ +  - ]:       9913 :                 nRotate = ((const SfxInt32Item&)pPattern->GetItem(ATTR_ROTATE_VALUE)).GetValue();
     176         [ +  + ]:       9913 :             if ( nRotate )
     177                 :            :             {
     178 [ -  + ][ #  # ]:       1514 :                 if (pCondSet &&
                 [ -  + ]
     179         [ #  # ]:          0 :                         pCondSet->GetItemState(ATTR_ROTATE_MODE, true, &pCondItem) == SFX_ITEM_SET)
     180                 :          0 :                     eRotMode = (SvxRotateMode)((const SvxRotateModeItem*)pCondItem)->GetValue();
     181                 :            :                 else
     182                 :            :                     eRotMode = (SvxRotateMode)((const SvxRotateModeItem&)
     183         [ +  - ]:       1514 :                                                 pPattern->GetItem(ATTR_ROTATE_MODE)).GetValue();
     184                 :            : 
     185         [ -  + ]:       1514 :                 if ( nRotate == 18000 )
     186                 :          0 :                     eRotMode = SVX_ROTATE_MODE_STANDARD;    // keinen Ueberlauf
     187                 :            :             }
     188                 :            :         }
     189                 :            : 
     190         [ -  + ]:      10851 :         if ( eHorJust == SVX_HOR_JUSTIFY_REPEAT )
     191                 :            :         {
     192                 :            :             // ignore orientation/rotation if "repeat" is active
     193                 :          0 :             eOrient = SVX_ORIENTATION_STANDARD;
     194                 :          0 :             nRotate = 0;
     195                 :          0 :             bAsianVertical = false;
     196                 :            :         }
     197                 :            : 
     198                 :            :         const SvxMarginItem* pMargin;
     199 [ +  + ][ -  + ]:      10853 :         if (pCondSet &&
                 [ -  + ]
     200         [ +  - ]:          2 :                 pCondSet->GetItemState(ATTR_MARGIN, true, &pCondItem) == SFX_ITEM_SET)
     201                 :          0 :             pMargin = (const SvxMarginItem*) pCondItem;
     202                 :            :         else
     203         [ +  - ]:      10851 :             pMargin = (const SvxMarginItem*) &pPattern->GetItem(ATTR_MARGIN);
     204                 :      10851 :         sal_uInt16 nIndent = 0;
     205         [ +  + ]:      10851 :         if ( eHorJust == SVX_HOR_JUSTIFY_LEFT )
     206                 :            :         {
     207 [ -  + ][ #  # ]:         10 :             if (pCondSet &&
                 [ -  + ]
     208         [ #  # ]:          0 :                     pCondSet->GetItemState(ATTR_INDENT, true, &pCondItem) == SFX_ITEM_SET)
     209                 :          0 :                 nIndent = ((const SfxUInt16Item*)pCondItem)->GetValue();
     210                 :            :             else
     211         [ +  - ]:         10 :                 nIndent = ((const SfxUInt16Item&)pPattern->GetItem(ATTR_INDENT)).GetValue();
     212                 :            :         }
     213                 :            : 
     214         [ +  - ]:      10851 :         sal_uInt8 nScript = pDocument->GetScriptType( nCol, nRow, nTab, pCell );
     215 [ +  + ][ +  - ]:      10851 :         if (nScript == 0) nScript = ScGlobal::GetDefaultScriptType();
     216                 :            : 
     217                 :            :         //  also call SetFont for edit cells, because bGetFont may be set only once
     218                 :            :         //  bGetFont is set also if script type changes
     219         [ +  - ]:      10851 :         if (rOptions.bGetFont)
     220                 :            :         {
     221 [ +  + ][ +  - ]:      10851 :             Fraction aFontZoom = ( eOrient == SVX_ORIENTATION_STANDARD ) ? rZoomX : rZoomY;
     222         [ +  - ]:      10851 :             Font aFont;
     223                 :            :             // font color doesn't matter here
     224         [ +  - ]:      10851 :             pPattern->GetFont( aFont, SC_AUTOCOL_BLACK, pDev, &aFontZoom, pCondSet, nScript );
     225 [ +  - ][ +  - ]:      10851 :             pDev->SetFont(aFont);
     226                 :            :         }
     227                 :            : 
     228                 :      10851 :         bool bAddMargin = true;
     229                 :      10851 :         CellType eCellType = pCell->GetCellType();
     230                 :            : 
     231                 :            :         bool bEditEngine = ( eCellType == CELLTYPE_EDIT ||
     232                 :            :                                 eOrient == SVX_ORIENTATION_STACKED ||
     233                 :      10111 :                                 IsAmbiguousScript( nScript ) ||
     234   [ +  -  +  - ]:      20962 :                                 ((eCellType == CELLTYPE_FORMULA) && ((ScFormulaCell*)pCell)->IsMultilineResult()) );
         [ -  + ][ #  # ]
         [ #  # ][ #  # ]
                 [ +  + ]
     235                 :            : 
     236         [ +  + ]:      10851 :         if (!bEditEngine)                                   // direkte Ausgabe
     237                 :            :         {
     238                 :      10111 :             rtl::OUString aValStr;
     239                 :            :             Color* pColor;
     240         [ +  - ]:      10111 :             SvNumberFormatter* pFormatter = pDocument->GetFormatTable();
     241         [ +  - ]:      10111 :             sal_uInt32 nFormat = pPattern->GetNumberFormat( pFormatter, pCondSet );
     242                 :            :             ScCellFormat::GetString( pCell, nFormat, aValStr, &pColor,
     243                 :            :                                         *pFormatter,
     244         [ +  - ]:      10111 :                                         true, rOptions.bFormula, ftCheck );
     245         [ +  - ]:      10111 :             if (!aValStr.isEmpty())
     246                 :            :             {
     247                 :            :                 //  SetFont ist nach oben verschoben
     248                 :            : 
     249 [ +  - ][ +  - ]:      10111 :                 Size aSize( pDev->GetTextWidth( aValStr ), pDev->GetTextHeight() );
         [ +  - ][ +  - ]
     250         [ +  + ]:      10111 :                 if ( eOrient != SVX_ORIENTATION_STANDARD )
     251                 :            :                 {
     252                 :        804 :                     long nTemp = aSize.Width();
     253                 :        804 :                     aSize.Width() = aSize.Height();
     254                 :        804 :                     aSize.Height() = nTemp;
     255                 :            :                 }
     256         [ +  + ]:       9307 :                 else if ( nRotate )
     257                 :            :                 {
     258                 :            :                     //! unterschiedliche Skalierung X/Y beruecksichtigen
     259                 :            : 
     260                 :       1297 :                     double nRealOrient = nRotate * F_PI18000;   // nRotate sind 1/100 Grad
     261                 :       1297 :                     double nCosAbs = fabs( cos( nRealOrient ) );
     262                 :       1297 :                     double nSinAbs = fabs( sin( nRealOrient ) );
     263                 :       1297 :                     long nHeight = (long)( aSize.Height() * nCosAbs + aSize.Width() * nSinAbs );
     264                 :            :                     long nWidth;
     265         [ +  - ]:       1297 :                     if ( eRotMode == SVX_ROTATE_MODE_STANDARD )
     266                 :       1297 :                         nWidth  = (long)( aSize.Width() * nCosAbs + aSize.Height() * nSinAbs );
     267         [ #  # ]:          0 :                     else if ( rOptions.bTotalSize )
     268                 :            :                     {
     269         [ #  # ]:          0 :                         nWidth = (long) ( pDocument->GetColWidth( nCol,nTab ) * nPPT );
     270                 :          0 :                         bAddMargin = false;
     271                 :            :                         //  nur nach rechts:
     272                 :            :                         //! unterscheiden nach Ausrichtung oben/unten (nur Text/ganze Hoehe)
     273 [ #  # ][ #  # ]:          0 :                         if ( pPattern->GetRotateDir( pCondSet ) == SC_ROTDIR_RIGHT )
     274         [ #  # ]:          0 :                             nWidth += (long)( pDocument->GetRowHeight( nRow,nTab ) *
     275                 :          0 :                                                 nPPT * nCosAbs / nSinAbs );
     276                 :            :                     }
     277                 :            :                     else
     278                 :          0 :                         nWidth  = (long)( aSize.Height() / nSinAbs );   //! begrenzen?
     279                 :            : 
     280 [ +  + ][ +  - ]:       1297 :                     if ( bBreak && !rOptions.bTotalSize )
     281                 :            :                     {
     282                 :            :                         //  limit size for line break
     283         [ +  - ]:        361 :                         long nCmp = pDev->GetFont().GetSize().Height() * SC_ROT_BREAK_FACTOR;
     284         [ -  + ]:        361 :                         if ( nHeight > nCmp )
     285                 :          0 :                             nHeight = nCmp;
     286                 :            :                     }
     287                 :            : 
     288                 :       1297 :                     aSize = Size( nWidth, nHeight );
     289                 :            :                 }
     290         [ +  + ]:      10111 :                 nValue = bWidth ? aSize.Width() : aSize.Height();
     291                 :            : 
     292         [ +  - ]:      10111 :                 if ( bAddMargin )
     293                 :            :                 {
     294         [ +  + ]:      10111 :                     if (bWidth)
     295                 :            :                     {
     296                 :       7928 :                         nValue += (long) ( pMargin->GetLeftMargin() * nPPT ) +
     297                 :       7928 :                                   (long) ( pMargin->GetRightMargin() * nPPT );
     298         [ -  + ]:       7928 :                         if ( nIndent )
     299                 :          0 :                             nValue += (long) ( nIndent * nPPT );
     300                 :            :                     }
     301                 :            :                     else
     302                 :       2183 :                         nValue += (long) ( pMargin->GetTopMargin() * nPPT ) +
     303                 :       2183 :                                   (long) ( pMargin->GetBottomMargin() * nPPT );
     304                 :            :                 }
     305                 :            : 
     306                 :            :                                                 //  Zeilenumbruch ausgefuehrt ?
     307                 :            : 
     308 [ +  + ][ +  - ]:      10111 :                 if ( bBreak && !bWidth )
     309                 :            :                 {
     310                 :            :                     //  Test mit EditEngine zur Sicherheit schon bei 90%
     311                 :            :                     //  (wegen Rundungsfehlern und weil EditEngine teilweise anders formatiert)
     312                 :            : 
     313         [ +  - ]:        597 :                     long nDocPixel = (long) ( ( pDocument->GetColWidth( nCol,nTab ) -
     314                 :        597 :                                         pMargin->GetLeftMargin() - pMargin->GetRightMargin() -
     315                 :            :                                         nIndent )
     316                 :       1791 :                                         * nPPT );
     317                 :        597 :                     nDocPixel = (nDocPixel * 9) / 10;           // zur Sicherheit
     318         [ +  + ]:        597 :                     if ( aSize.Width() > nDocPixel )
     319                 :      10111 :                         bEditEngine = true;
     320                 :            :                 }
     321                 :      10111 :             }
     322                 :            :         }
     323                 :            : 
     324         [ +  + ]:      10851 :         if (bEditEngine)
     325                 :            :         {
     326                 :            :             //  der Font wird bei !bEditEngine nicht jedesmal neu gesetzt
     327         [ +  - ]:       1065 :             Font aOldFont = pDev->GetFont();
     328                 :            : 
     329         [ +  - ]:       1065 :             MapMode aHMMMode( MAP_100TH_MM, Point(), rZoomX, rZoomY );
     330                 :            : 
     331                 :            :             // am Dokument speichern ?
     332         [ +  - ]:       1065 :             ScFieldEditEngine* pEngine = pDocument->CreateFieldEditEngine();
     333                 :            : 
     334         [ +  - ]:       1065 :             pEngine->SetUpdateMode( false );
     335                 :       1065 :             bool bTextWysiwyg = ( pDev->GetOutDevType() == OUTDEV_PRINTER );
     336         [ +  - ]:       1065 :             sal_uLong nCtrl = pEngine->GetControlWord();
     337         [ +  + ]:       1065 :             if ( bTextWysiwyg )
     338                 :          7 :                 nCtrl |= EE_CNTRL_FORMAT100;
     339                 :            :             else
     340                 :       1058 :                 nCtrl &= ~EE_CNTRL_FORMAT100;
     341         [ +  - ]:       1065 :             pEngine->SetControlWord( nCtrl );
     342         [ +  - ]:       1065 :             MapMode aOld = pDev->GetMapMode();
     343         [ +  - ]:       1065 :             pDev->SetMapMode( aHMMMode );
     344         [ +  - ]:       1065 :             pEngine->SetRefDevice( pDev );
     345         [ +  - ]:       1065 :             pDocument->ApplyAsianEditSettings( *pEngine );
     346 [ +  - ][ +  - ]:       1065 :             SfxItemSet* pSet = new SfxItemSet( pEngine->GetEmptyItemSet() );
                 [ +  - ]
     347         [ +  - ]:       1065 :             pPattern->FillEditItemSet( pSet, pCondSet );
     348                 :            : 
     349                 :            : //          no longer needed, are setted with the text (is faster)
     350                 :            : //          pEngine->SetDefaults( pSet );
     351                 :            : 
     352 [ +  - ][ +  + ]:       1065 :             if ( ((const SfxBoolItem&)pSet->Get(EE_PARA_HYPHENATE)).GetValue() ) {
     353                 :            : 
     354         [ +  - ]:        430 :                 com::sun::star::uno::Reference<com::sun::star::linguistic2::XHyphenator> xXHyphenator( LinguMgr::GetHyphenator() );
     355         [ +  - ]:        430 :                 pEngine->SetHyphenator( xXHyphenator );
     356                 :            :             }
     357                 :            : 
     358                 :       1065 :             Size aPaper = Size( 1000000, 1000000 );
     359 [ #  # ][ -  + ]:       1065 :             if ( eOrient==SVX_ORIENTATION_STACKED && !bAsianVertical )
     360                 :          0 :                 aPaper.Width() = 1;
     361         [ +  + ]:       1065 :             else if (bBreak)
     362                 :            :             {
     363                 :        624 :                 double fWidthFactor = nPPTX;
     364         [ -  + ]:        624 :                 if ( bTextWysiwyg )
     365                 :            :                 {
     366                 :            :                     //  if text is formatted for printer, don't use PixelToLogic,
     367                 :            :                     //  to ensure the exact same paper width (and same line breaks) as in
     368                 :            :                     //  ScEditUtil::GetEditArea, used for output.
     369                 :            : 
     370                 :          0 :                     fWidthFactor = HMM_PER_TWIPS;
     371                 :            :                 }
     372                 :            : 
     373                 :            :                 // use original width for hidden columns:
     374         [ +  - ]:        624 :                 long nDocWidth = (long) ( pDocument->GetOriginalWidth(nCol,nTab) * fWidthFactor );
     375                 :        624 :                 SCCOL nColMerge = pMerge->GetColMerge();
     376         [ -  + ]:        624 :                 if (nColMerge > 1)
     377         [ #  # ]:          0 :                     for (SCCOL nColAdd=1; nColAdd<nColMerge; nColAdd++)
     378         [ #  # ]:          0 :                         nDocWidth += (long) ( pDocument->GetColWidth(nCol+nColAdd,nTab) * fWidthFactor );
     379                 :        624 :                 nDocWidth -= (long) ( pMargin->GetLeftMargin() * fWidthFactor )
     380                 :        624 :                            + (long) ( pMargin->GetRightMargin() * fWidthFactor )
     381                 :       1248 :                            + 1;     // Ausgabebereich ist Breite-1 Pixel (wegen Gitterlinien)
     382         [ -  + ]:        624 :                 if ( nIndent )
     383                 :          0 :                     nDocWidth -= (long) ( nIndent * fWidthFactor );
     384                 :            : 
     385                 :            :                 // space for AutoFilter button:  20 * nZoom/100
     386 [ -  + ][ #  # ]:        624 :                 if ( pFlag->HasAutoFilter() && !bTextWysiwyg )
                 [ -  + ]
     387                 :          0 :                     nDocWidth -= (rZoomX.GetNumerator()*20)/rZoomX.GetDenominator();
     388                 :            : 
     389                 :        624 :                 aPaper.Width() = nDocWidth;
     390                 :            : 
     391         [ +  - ]:        624 :                 if ( !bTextWysiwyg )
     392         [ +  - ]:        624 :                     aPaper = pDev->PixelToLogic( aPaper, aHMMMode );
     393                 :            :             }
     394         [ +  - ]:       1065 :             pEngine->SetPaperSize(aPaper);
     395                 :            : 
     396         [ +  + ]:       1065 :             if ( pCell->GetCellType() == CELLTYPE_EDIT )
     397                 :            :             {
     398                 :            :                 const EditTextObject* pData;
     399         [ +  - ]:        740 :                 ((ScEditCell*)pCell)->GetData(pData);
     400         [ +  - ]:        740 :                 pEngine->SetTextNewDefaults(*pData, pSet);
     401                 :            :             }
     402                 :            :             else
     403                 :            :             {
     404                 :            :                 Color* pColor;
     405         [ +  - ]:        325 :                 SvNumberFormatter* pFormatter = pDocument->GetFormatTable();
     406         [ +  - ]:        325 :                 sal_uInt32 nFormat = pPattern->GetNumberFormat( pFormatter, pCondSet );
     407                 :        325 :                 rtl::OUString aString;
     408                 :            :                 ScCellFormat::GetString( pCell, nFormat, aString, &pColor,
     409                 :            :                                             *pFormatter,
     410         [ +  - ]:        325 :                                             true, rOptions.bFormula, ftCheck );
     411         [ +  - ]:        325 :                 if (!aString.isEmpty())
     412 [ +  - ][ +  - ]:        325 :                     pEngine->SetTextNewDefaults(aString, pSet);
                 [ +  - ]
     413                 :            :                 else
     414         [ #  # ]:        325 :                     pEngine->SetDefaults(pSet);
     415                 :            :             }
     416                 :            : 
     417         [ +  - ]:       1065 :             bool bEngineVertical = pEngine->IsVertical();
     418         [ +  - ]:       1065 :             pEngine->SetVertical( bAsianVertical );
     419         [ +  - ]:       1065 :             pEngine->SetUpdateMode( true );
     420                 :            : 
     421                 :       1065 :             bool bEdWidth = bWidth;
     422 [ +  + ][ +  - ]:       1065 :             if ( eOrient != SVX_ORIENTATION_STANDARD && eOrient != SVX_ORIENTATION_STACKED )
     423                 :        234 :                 bEdWidth = !bEdWidth;
     424         [ +  + ]:       1065 :             if ( nRotate )
     425                 :            :             {
     426                 :            :                 //! unterschiedliche Skalierung X/Y beruecksichtigen
     427                 :            : 
     428 [ +  - ][ +  - ]:        442 :                 Size aSize( pEngine->CalcTextWidth(), pEngine->GetTextHeight() );
     429                 :        442 :                 double nRealOrient = nRotate * F_PI18000;   // nRotate sind 1/100 Grad
     430                 :        442 :                 double nCosAbs = fabs( cos( nRealOrient ) );
     431                 :        442 :                 double nSinAbs = fabs( sin( nRealOrient ) );
     432                 :        442 :                 long nHeight = (long)( aSize.Height() * nCosAbs + aSize.Width() * nSinAbs );
     433                 :            :                 long nWidth;
     434         [ +  - ]:        442 :                 if ( eRotMode == SVX_ROTATE_MODE_STANDARD )
     435                 :        442 :                     nWidth  = (long)( aSize.Width() * nCosAbs + aSize.Height() * nSinAbs );
     436         [ #  # ]:          0 :                 else if ( rOptions.bTotalSize )
     437                 :            :                 {
     438         [ #  # ]:          0 :                     nWidth = (long) ( pDocument->GetColWidth( nCol,nTab ) * nPPT );
     439                 :          0 :                     bAddMargin = false;
     440 [ #  # ][ #  # ]:          0 :                     if ( pPattern->GetRotateDir( pCondSet ) == SC_ROTDIR_RIGHT )
     441         [ #  # ]:          0 :                         nWidth += (long)( pDocument->GetRowHeight( nRow,nTab ) *
     442                 :          0 :                                             nPPT * nCosAbs / nSinAbs );
     443                 :            :                 }
     444                 :            :                 else
     445                 :          0 :                     nWidth  = (long)( aSize.Height() / nSinAbs );   //! begrenzen?
     446                 :        442 :                 aSize = Size( nWidth, nHeight );
     447                 :            : 
     448         [ +  - ]:        442 :                 Size aPixSize = pDev->LogicToPixel( aSize, aHMMMode );
     449         [ -  + ]:        442 :                 if ( bEdWidth )
     450                 :          0 :                     nValue = aPixSize.Width();
     451                 :            :                 else
     452                 :            :                 {
     453                 :        442 :                     nValue = aPixSize.Height();
     454                 :            : 
     455 [ +  - ][ +  + ]:        442 :                     if ( bBreak && !rOptions.bTotalSize )
     456                 :            :                     {
     457                 :            :                         //  limit size for line break
     458         [ +  - ]:        406 :                         long nCmp = aOldFont.GetSize().Height() * SC_ROT_BREAK_FACTOR;
     459         [ +  + ]:        406 :                         if ( nValue > nCmp )
     460                 :        442 :                             nValue = nCmp;
     461                 :            :                     }
     462                 :            :                 }
     463                 :            :             }
     464         [ +  + ]:        623 :             else if ( bEdWidth )
     465                 :            :             {
     466         [ +  + ]:        242 :                 if (bBreak)
     467                 :        218 :                     nValue = 0;
     468                 :            :                 else
     469         [ +  - ]:         24 :                     nValue = pDev->LogicToPixel(Size( pEngine->CalcTextWidth(), 0 ),
     470         [ +  - ]:         24 :                                         aHMMMode).Width();
     471                 :            :             }
     472                 :            :             else            // Hoehe
     473                 :            :             {
     474         [ +  - ]:        381 :                 nValue = pDev->LogicToPixel(Size( 0, pEngine->GetTextHeight() ),
     475         [ +  - ]:        381 :                                     aHMMMode).Height();
     476                 :            : 
     477                 :            :                 // With non-100% zoom and several lines or paragraphs, don't shrink below the result with FORMAT100 set
     478 [ +  - ][ -  + ]:        381 :                 if ( !bTextWysiwyg && ( rZoomY.GetNumerator() != 1 || rZoomY.GetDenominator() != 1 ) &&
         [ #  # ][ #  # ]
         [ #  # ][ -  + ]
                 [ +  - ]
     479 [ #  # ][ #  # ]:          0 :                      ( pEngine->GetParagraphCount() > 1 || ( bBreak && pEngine->GetLineCount(0) > 1 ) ) )
     480                 :            :                 {
     481         [ #  # ]:          0 :                     pEngine->SetControlWord( nCtrl | EE_CNTRL_FORMAT100 );
     482         [ #  # ]:          0 :                     pEngine->QuickFormatDoc( sal_True );
     483 [ #  # ][ #  # ]:          0 :                     long nSecondValue = pDev->LogicToPixel(Size( 0, pEngine->GetTextHeight() ), aHMMMode).Height();
     484         [ #  # ]:          0 :                     if ( nSecondValue > nValue )
     485                 :          0 :                         nValue = nSecondValue;
     486                 :            :                 }
     487                 :            :             }
     488                 :            : 
     489 [ +  + ][ +  - ]:       1065 :             if ( nValue && bAddMargin )
     490                 :            :             {
     491         [ +  + ]:        847 :                 if (bWidth)
     492                 :            :                 {
     493                 :          8 :                     nValue += (long) ( pMargin->GetLeftMargin() * nPPT ) +
     494                 :          8 :                               (long) ( pMargin->GetRightMargin() * nPPT );
     495         [ -  + ]:          8 :                     if (nIndent)
     496                 :          0 :                         nValue += (long) ( nIndent * nPPT );
     497                 :            :                 }
     498                 :            :                 else
     499                 :            :                 {
     500                 :        839 :                     nValue += (long) ( pMargin->GetTopMargin() * nPPT ) +
     501                 :        839 :                               (long) ( pMargin->GetBottomMargin() * nPPT );
     502                 :            : 
     503 [ #  # ][ -  + ]:        839 :                     if ( bAsianVertical && pDev->GetOutDevType() != OUTDEV_PRINTER )
                 [ -  + ]
     504                 :            :                     {
     505                 :            :                         //  add 1pt extra (default margin value) for line breaks with SetVertical
     506                 :          0 :                         nValue += (long) ( 20 * nPPT );
     507                 :            :                     }
     508                 :            :                 }
     509                 :            :             }
     510                 :            : 
     511                 :            :             //  EditEngine is cached and re-used, so the old vertical flag must be restored
     512         [ +  - ]:       1065 :             pEngine->SetVertical( bEngineVertical );
     513                 :            : 
     514         [ +  - ]:       1065 :             pDocument->DisposeFieldEditEngine(pEngine);
     515                 :            : 
     516         [ +  - ]:       1065 :             pDev->SetMapMode( aOld );
     517 [ +  - ][ +  - ]:       1065 :             pDev->SetFont( aOldFont );
         [ +  - ][ +  - ]
     518                 :            :         }
     519                 :            : 
     520         [ +  + ]:      10851 :         if (bWidth)
     521                 :            :         {
     522                 :            :             //      Platz fuer Autofilter-Button
     523                 :            :             //      20 * nZoom/100
     524                 :            :             //      bedingte Formatierung hier nicht interessant
     525                 :            : 
     526         [ +  - ]:       7936 :             sal_Int16 nFlags = ((const ScMergeFlagAttr&)pPattern->GetItem(ATTR_MERGE_FLAG)).GetValue();
     527         [ +  + ]:       7936 :             if (nFlags & SC_MF_AUTO)
     528                 :      10854 :                 nValue += (rZoomX.GetNumerator()*20)/rZoomX.GetDenominator();
     529                 :            :         }
     530                 :            :     }
     531                 :      10854 :     return nValue;
     532                 :            : }
     533                 :            : 
     534                 :            : 
     535                 :        214 : sal_uInt16 ScColumn::GetOptimalColWidth( OutputDevice* pDev, double nPPTX, double nPPTY,
     536                 :            :                                      const Fraction& rZoomX, const Fraction& rZoomY,
     537                 :            :                                      bool bFormula, sal_uInt16 nOldWidth,
     538                 :            :                                      const ScMarkData* pMarkData,
     539                 :            :                                      const ScColWidthParam* pParam )
     540                 :            : {
     541         [ +  + ]:        214 :     if ( maItems.empty() )
     542                 :         18 :         return nOldWidth;
     543                 :            : 
     544                 :        196 :     sal_uInt16  nWidth = (sal_uInt16) (nOldWidth * nPPTX);
     545                 :        196 :     bool    bFound = false;
     546                 :            : 
     547                 :            :     SCSIZE nIndex;
     548         [ +  - ]:        196 :     ScMarkedDataIter aDataIter(this, pMarkData, true);
     549 [ +  + ][ +  - ]:        196 :     if ( pParam && pParam->mbSimpleText )
     550                 :            :     {   // alles eins bis auf NumberFormate
     551         [ +  - ]:        192 :         const ScPatternAttr* pPattern = GetPattern( 0 );
     552         [ +  - ]:        192 :         Font aFont;
     553                 :            :         // font color doesn't matter here
     554         [ +  - ]:        192 :         pPattern->GetFont( aFont, SC_AUTOCOL_BLACK, pDev, &rZoomX, NULL );
     555         [ +  - ]:        192 :         pDev->SetFont( aFont );
     556         [ +  - ]:        192 :         const SvxMarginItem* pMargin = (const SvxMarginItem*) &pPattern->GetItem(ATTR_MARGIN);
     557                 :        192 :         long nMargin = (long) ( pMargin->GetLeftMargin() * nPPTX ) +
     558                 :        192 :                         (long) ( pMargin->GetRightMargin() * nPPTX );
     559                 :            : 
     560                 :            :         // Try to find the row that has the longest string, and measure the width of that string.
     561         [ +  - ]:        192 :         SvNumberFormatter* pFormatter = pDocument->GetFormatTable();
     562         [ +  - ]:        192 :         sal_uInt32 nFormat = pPattern->GetNumberFormat( pFormatter );
     563                 :        192 :         rtl::OUString aLongStr;
     564                 :            :         Color* pColor;
     565         [ -  + ]:        192 :         if (pParam->mnMaxTextRow >= 0)
     566                 :            :         {
     567         [ #  # ]:          0 :             ScBaseCell* pCell = GetCell(pParam->mnMaxTextRow);
     568                 :            :             ScCellFormat::GetString(
     569         [ #  # ]:          0 :                 pCell, nFormat, aLongStr, &pColor, *pFormatter, true, false, ftCheck );
     570                 :            :         }
     571                 :            :         else
     572                 :            :         {
     573                 :        192 :             xub_StrLen nLongLen = 0;
     574 [ +  - ][ +  + ]:       7983 :             while (aDataIter.Next(nIndex))
     575                 :            :             {
     576         [ +  - ]:       7791 :                 if (nIndex >= maItems.size())
     577                 :            :                     // Out-of-bound reached.  No need to keep going.
     578                 :            :                     break;
     579                 :            : 
     580                 :       7791 :                 ScBaseCell* pCell = maItems[nIndex].pCell;
     581                 :       7791 :                 rtl::OUString aValStr;
     582                 :            :                 ScCellFormat::GetString(
     583         [ +  - ]:       7791 :                     pCell, nFormat, aValStr, &pColor, *pFormatter, true, false, ftCheck );
     584                 :            : 
     585         [ +  + ]:       7791 :                 if (aValStr.getLength() > nLongLen)
     586                 :            :                 {
     587                 :        357 :                     nLongLen = aValStr.getLength();
     588                 :        357 :                     aLongStr = aValStr;
     589                 :            :                 }
     590                 :       7791 :             }
     591                 :            :         }
     592                 :            : 
     593         [ +  - ]:        192 :         if (!aLongStr.isEmpty())
     594                 :            :         {
     595 [ +  - ][ +  - ]:        192 :             nWidth = pDev->GetTextWidth(aLongStr) + static_cast<sal_uInt16>(nMargin);
                 [ +  - ]
     596                 :        192 :             bFound = true;
     597         [ +  - ]:        192 :         }
     598                 :            :     }
     599                 :            :     else
     600                 :            :     {
     601                 :          4 :         ScNeededSizeOptions aOptions;
     602                 :          4 :         aOptions.bFormula = bFormula;
     603                 :          4 :         const ScPatternAttr* pOldPattern = NULL;
     604                 :          4 :         sal_uInt8 nOldScript = 0;
     605                 :            : 
     606 [ +  - ][ +  + ]:          8 :         while (aDataIter.Next( nIndex ))
     607                 :            :         {
     608                 :          4 :             SCROW nRow = maItems[nIndex].nRow;
     609                 :            : 
     610         [ +  - ]:          4 :             sal_uInt8 nScript = pDocument->GetScriptType( nCol, nRow, nTab, maItems[nIndex].pCell );
     611 [ -  + ][ #  # ]:          4 :             if (nScript == 0) nScript = ScGlobal::GetDefaultScriptType();
     612                 :            : 
     613         [ +  - ]:          4 :             const ScPatternAttr* pPattern = GetPattern( nRow );
     614                 :          4 :             aOptions.pPattern = pPattern;
     615 [ -  + ][ #  # ]:          4 :             aOptions.bGetFont = (pPattern != pOldPattern || nScript != nOldScript);
     616                 :            :             sal_uInt16 nThis = (sal_uInt16) GetNeededSize( nRow, pDev, nPPTX, nPPTY,
     617         [ +  - ]:          4 :                 rZoomX, rZoomY, true, aOptions );
     618                 :          4 :             pOldPattern = pPattern;
     619         [ +  - ]:          4 :             if (nThis)
     620                 :            :             {
     621 [ -  + ][ #  # ]:          4 :                 if (nThis>nWidth || !bFound)
     622                 :            :                 {
     623                 :          4 :                     nWidth = nThis;
     624                 :          4 :                     bFound = true;
     625                 :            :                 }
     626                 :            :             }
     627                 :            :         }
     628                 :            :     }
     629                 :            : 
     630         [ +  - ]:        196 :     if (bFound)
     631                 :            :     {
     632                 :        196 :         nWidth += 2;
     633                 :        196 :         sal_uInt16 nTwips = (sal_uInt16) (nWidth / nPPTX);
     634                 :        196 :         return nTwips;
     635                 :            :     }
     636                 :            :     else
     637         [ +  - ]:        214 :         return nOldWidth;
     638                 :            : }
     639                 :            : 
     640                 :    1843277 : sal_uInt16 lcl_GetAttribHeight( const ScPatternAttr& rPattern, sal_uInt16 nFontHeightId )
     641                 :            : {
     642                 :    1843277 :     sal_uInt16 nHeight = (sal_uInt16) ((const SvxFontHeightItem&) rPattern.GetItem(nFontHeightId)).GetHeight();
     643                 :    1843277 :     const SvxMarginItem* pMargin = (const SvxMarginItem*) &rPattern.GetItem(ATTR_MARGIN);
     644                 :    1843277 :     nHeight += nHeight / 5;
     645                 :            :     //  gibt bei 10pt 240
     646                 :            : 
     647         [ +  + ]:    1843277 :     if ( ((const SvxEmphasisMarkItem&)rPattern.
     648                 :    1843277 :             GetItem(ATTR_FONT_EMPHASISMARK)).GetEmphasisMark() != EMPHASISMARK_NONE )
     649                 :            :     {
     650                 :            :         //  add height for emphasis marks
     651                 :            :         //! font metrics should be used instead
     652                 :        898 :         nHeight += nHeight / 4;
     653                 :            :     }
     654                 :            : 
     655         [ +  - ]:    1843277 :     if ( nHeight + 240 > ScGlobal::nDefFontHeight )
     656                 :            :     {
     657                 :    1843277 :         nHeight = sal::static_int_cast<sal_uInt16>( nHeight + ScGlobal::nDefFontHeight );
     658                 :    1843277 :         nHeight -= 240;
     659                 :            :     }
     660                 :            : 
     661                 :            :     //  Standard-Hoehe: TextHeight + Raender - 23
     662                 :            :     //  -> 257 unter Windows
     663                 :            : 
     664         [ +  - ]:    1843277 :     if (nHeight > STD_ROWHEIGHT_DIFF)
     665                 :    1843277 :         nHeight -= STD_ROWHEIGHT_DIFF;
     666                 :            : 
     667                 :    1843277 :     nHeight += pMargin->GetTopMargin() + pMargin->GetBottomMargin();
     668                 :            : 
     669                 :    1843277 :     return nHeight;
     670                 :            : }
     671                 :            : 
     672                 :            : //  pHeight in Twips
     673                 :            : //  nMinHeight, nMinStart zur Optimierung: ab nRow >= nMinStart ist mindestens nMinHeight
     674                 :            : //  (wird nur bei bStdAllowed ausgewertet)
     675                 :            : 
     676                 :    1843200 : void ScColumn::GetOptimalHeight( SCROW nStartRow, SCROW nEndRow, sal_uInt16* pHeight,
     677                 :            :                                 OutputDevice* pDev,
     678                 :            :                                 double nPPTX, double nPPTY,
     679                 :            :                                 const Fraction& rZoomX, const Fraction& rZoomY,
     680                 :            :                                 bool bShrink, sal_uInt16 nMinHeight, SCROW nMinStart )
     681                 :            : {
     682         [ +  - ]:    1843200 :     ScAttrIterator aIter( pAttrArray, nStartRow, nEndRow );
     683                 :            : 
     684                 :    1843200 :     SCROW nStart = -1;
     685                 :    1843200 :     SCROW nEnd = -1;
     686                 :    1843200 :     SCROW nEditPos = 0;
     687                 :    1843200 :     SCROW nNextEnd = 0;
     688                 :            : 
     689                 :            :     //  bei bedingter Formatierung werden immer die einzelnen Zellen angesehen
     690                 :            : 
     691         [ +  - ]:    1843200 :     const ScPatternAttr* pPattern = aIter.Next(nStart,nEnd);
     692         [ +  + ]:    3687426 :     while ( pPattern )
     693                 :            :     {
     694         [ +  - ]:    1844226 :         const ScMergeAttr*      pMerge = (const ScMergeAttr*)&pPattern->GetItem(ATTR_MERGE);
     695         [ +  - ]:    1844226 :         const ScMergeFlagAttr*  pFlag = (const ScMergeFlagAttr*)&pPattern->GetItem(ATTR_MERGE_FLAG);
     696 [ +  + ][ +  + ]:    1844226 :         if ( pMerge->GetRowMerge() > 1 || pFlag->IsOverlapped() )
                 [ +  + ]
     697                 :            :         {
     698                 :            :             //  nix - vertikal bei der zusammengefassten und den ueberdeckten,
     699                 :            :             //        horizontal nur bei den ueberdeckten (unsichtbaren) -
     700                 :            :             //        eine nur horizontal zusammengefasste wird aber beruecksichtigt
     701                 :            :         }
     702                 :            :         else
     703                 :            :         {
     704                 :    1844179 :             SCROW nRow = 0;
     705         [ +  - ]:    1844179 :             bool bStdAllowed = (pPattern->GetCellOrientation() == SVX_ORIENTATION_STANDARD);
     706                 :    1844179 :             bool bStdOnly = false;
     707         [ +  + ]:    1844179 :             if (bStdAllowed)
     708                 :            :             {
     709         [ +  - ]:    1843643 :                 bool bBreak = ((SfxBoolItem&)pPattern->GetItem(ATTR_LINEBREAK)).GetValue() ||
     710                 :            :                                 ((SvxCellHorJustify)((const SvxHorJustifyItem&)pPattern->
     711         [ +  - ]:    1843121 :                                     GetItem( ATTR_HOR_JUSTIFY )).GetValue() ==
     712   [ +  +  +  + ]:    3686764 :                                     SVX_HOR_JUSTIFY_BLOCK);
     713                 :    1843643 :                 bStdOnly = !bBreak;
     714                 :            : 
     715                 :            :                 // bedingte Formatierung: Zellen durchgehen
     716   [ +  +  +  + ]:    3686564 :                 if ( bStdOnly && ((const SfxUInt32Item&)pPattern->
                 [ +  + ]
     717         [ +  - ]:    1842921 :                                     GetItem(ATTR_CONDITIONAL)).GetValue() )
     718                 :       2247 :                     bStdOnly = false;
     719                 :            : 
     720                 :            :                 // gedrehter Text: Zellen durchgehen
     721   [ +  +  -  + ]:    3684317 :                 if ( bStdOnly && ((const SfxInt32Item&)pPattern->
                 [ -  + ]
     722         [ +  - ]:    1840674 :                                     GetItem(ATTR_ROTATE_VALUE)).GetValue() )
     723                 :          0 :                     bStdOnly = false;
     724                 :            :             }
     725                 :            : 
     726         [ +  + ]:    1844179 :             if (bStdOnly)
     727 [ +  - ][ +  + ]:    1840674 :                 if (HasEditCells(nStart,nEnd,nEditPos))     // includes mixed script types
     728                 :            :                 {
     729         [ +  + ]:        441 :                     if (nEditPos == nStart)
     730                 :            :                     {
     731                 :        366 :                         bStdOnly = false;
     732         [ +  + ]:        366 :                         if (nEnd > nEditPos)
     733                 :         75 :                             nNextEnd = nEnd;
     734                 :        366 :                         nEnd = nEditPos;                // einzeln ausrechnen
     735                 :        366 :                         bStdAllowed = false;            // wird auf jeden Fall per Zelle berechnet
     736                 :            :                     }
     737                 :            :                     else
     738                 :            :                     {
     739                 :         75 :                         nNextEnd = nEnd;
     740                 :         75 :                         nEnd = nEditPos - 1;            // Standard - Teil
     741                 :            :                     }
     742                 :            :                 }
     743                 :            : 
     744         [ +  + ]:    1844179 :             if (bStdAllowed)
     745                 :            :             {
     746                 :    1843277 :                 sal_uInt16 nLatHeight = 0;
     747                 :    1843277 :                 sal_uInt16 nCjkHeight = 0;
     748                 :    1843277 :                 sal_uInt16 nCtlHeight = 0;
     749                 :            :                 sal_uInt16 nDefHeight;
     750         [ +  - ]:    1843277 :                 sal_uInt8 nDefScript = ScGlobal::GetDefaultScriptType();
     751         [ -  + ]:    1843277 :                 if ( nDefScript == SCRIPTTYPE_ASIAN )
     752         [ #  # ]:          0 :                     nDefHeight = nCjkHeight = lcl_GetAttribHeight( *pPattern, ATTR_CJK_FONT_HEIGHT );
     753         [ -  + ]:    1843277 :                 else if ( nDefScript == SCRIPTTYPE_COMPLEX )
     754         [ #  # ]:          0 :                     nDefHeight = nCtlHeight = lcl_GetAttribHeight( *pPattern, ATTR_CTL_FONT_HEIGHT );
     755                 :            :                 else
     756         [ +  - ]:    1843277 :                     nDefHeight = nLatHeight = lcl_GetAttribHeight( *pPattern, ATTR_FONT_HEIGHT );
     757                 :            : 
     758                 :            :                 //  if everything below is already larger, the loop doesn't have to
     759                 :            :                 //  be run again
     760                 :    1843277 :                 SCROW nStdEnd = nEnd;
     761 [ +  + ][ +  - ]:    1843277 :                 if ( nDefHeight <= nMinHeight && nStdEnd >= nMinStart )
     762         [ +  + ]:    1840499 :                     nStdEnd = (nMinStart>0) ? nMinStart-1 : 0;
     763                 :            : 
     764         [ +  + ]:  951258501 :                 for (nRow=nStart; nRow<=nStdEnd; nRow++)
     765         [ +  + ]:  949415224 :                     if (nDefHeight > pHeight[nRow-nStartRow])
     766                 :  947917910 :                         pHeight[nRow-nStartRow] = nDefHeight;
     767                 :            : 
     768         [ +  + ]:    1843277 :                 if ( bStdOnly )
     769                 :            :                 {
     770                 :            :                     //  if cells are not handled individually below,
     771                 :            :                     //  check for cells with different script type
     772                 :            : 
     773                 :            :                     SCSIZE nIndex;
     774         [ +  - ]:    1840308 :                     Search(nStart,nIndex);
     775 [ +  + ][ +  + ]:    1879006 :                     while ( nIndex < maItems.size() && (nRow=maItems[nIndex].nRow) <= nEnd )
                 [ +  + ]
     776                 :            :                     {
     777         [ +  - ]:      38698 :                         sal_uInt8 nScript = pDocument->GetScriptType( nCol, nRow, nTab, maItems[nIndex].pCell );
     778         [ +  + ]:      38698 :                         if ( nScript != nDefScript )
     779                 :            :                         {
     780         [ -  + ]:        172 :                             if ( nScript == SCRIPTTYPE_ASIAN )
     781                 :            :                             {
     782         [ #  # ]:          0 :                                 if ( nCjkHeight == 0 )
     783         [ #  # ]:          0 :                                     nCjkHeight = lcl_GetAttribHeight( *pPattern, ATTR_CJK_FONT_HEIGHT );
     784         [ #  # ]:          0 :                                 if (nCjkHeight > pHeight[nRow-nStartRow])
     785                 :          0 :                                     pHeight[nRow-nStartRow] = nCjkHeight;
     786                 :            :                             }
     787         [ -  + ]:        172 :                             else if ( nScript == SCRIPTTYPE_COMPLEX )
     788                 :            :                             {
     789         [ #  # ]:          0 :                                 if ( nCtlHeight == 0 )
     790         [ #  # ]:          0 :                                     nCtlHeight = lcl_GetAttribHeight( *pPattern, ATTR_CTL_FONT_HEIGHT );
     791         [ #  # ]:          0 :                                 if (nCtlHeight > pHeight[nRow-nStartRow])
     792                 :          0 :                                     pHeight[nRow-nStartRow] = nCtlHeight;
     793                 :            :                             }
     794                 :            :                             else
     795                 :            :                             {
     796         [ -  + ]:        172 :                                 if ( nLatHeight == 0 )
     797         [ #  # ]:          0 :                                     nLatHeight = lcl_GetAttribHeight( *pPattern, ATTR_FONT_HEIGHT );
     798         [ -  + ]:        172 :                                 if (nLatHeight > pHeight[nRow-nStartRow])
     799                 :          0 :                                     pHeight[nRow-nStartRow] = nLatHeight;
     800                 :            :                             }
     801                 :            :                         }
     802                 :      38698 :                         ++nIndex;
     803                 :            :                     }
     804                 :            :                 }
     805                 :            :             }
     806                 :            : 
     807         [ +  + ]:    1844179 :             if (!bStdOnly)                      // belegte Zellen suchen
     808                 :            :             {
     809                 :       3871 :                 ScNeededSizeOptions aOptions;
     810                 :            : 
     811                 :            :                 SCSIZE nIndex;
     812         [ +  - ]:       3871 :                 Search(nStart,nIndex);
     813 [ +  + ][ +  + ]:       6786 :                 while ( (nIndex < maItems.size()) ? ((nRow=maItems[nIndex].nRow) <= nEnd) : false )
                 [ +  + ]
     814                 :            :                 {
     815                 :            :                     //  Zellhoehe nur berechnen, wenn sie spaeter auch gebraucht wird (#37928#)
     816                 :            : 
     817 [ +  - ][ +  - ]:       2915 :                     if ( bShrink || !(pDocument->GetRowFlags(nRow, nTab) & CR_MANUALSIZE) )
         [ +  - ][ +  - ]
     818                 :            :                     {
     819                 :       2915 :                         aOptions.pPattern = pPattern;
     820                 :            :                         sal_uInt16 nHeight = (sal_uInt16)
     821                 :            :                                 ( GetNeededSize( nRow, pDev, nPPTX, nPPTY,
     822         [ +  - ]:       2915 :                                                     rZoomX, rZoomY, false, aOptions ) / nPPTY );
     823         [ +  + ]:       2915 :                         if (nHeight > pHeight[nRow-nStartRow])
     824                 :       1870 :                             pHeight[nRow-nStartRow] = nHeight;
     825                 :            :                     }
     826                 :       2915 :                     ++nIndex;
     827                 :            :                 }
     828                 :            :             }
     829                 :            :         }
     830                 :            : 
     831         [ +  + ]:    1844226 :         if (nNextEnd > 0)
     832                 :            :         {
     833                 :        150 :             nStart = nEnd + 1;
     834                 :        150 :             nEnd = nNextEnd;
     835                 :        150 :             nNextEnd = 0;
     836                 :            :         }
     837                 :            :         else
     838         [ +  - ]:    1844076 :             pPattern = aIter.Next(nStart,nEnd);
     839                 :            :     }
     840                 :    1843200 : }
     841                 :            : 
     842                 :          0 : bool ScColumn::GetNextSpellingCell(SCROW& nRow, bool bInSel, const ScMarkData& rData) const
     843                 :            : {
     844                 :          0 :     bool bStop = false;
     845                 :            :     CellType eCellType;
     846                 :            :     SCSIZE nIndex;
     847 [ #  # ][ #  # ]:          0 :     if (!bInSel && Search(nRow, nIndex))
         [ #  # ][ #  # ]
     848                 :            :     {
     849         [ #  # ]:          0 :         eCellType = GetCellType(nRow);
     850 [ #  # ][ #  # ]:          0 :         if ( (eCellType == CELLTYPE_STRING || eCellType == CELLTYPE_EDIT) &&
         [ #  # ][ #  # ]
     851         [ #  # ]:          0 :              !(HasAttrib( nRow, nRow, HASATTR_PROTECTED) &&
     852 [ #  # ][ #  # ]:          0 :                pDocument->IsTabProtected(nTab)) )
     853                 :          0 :                 return true;
     854                 :            :     }
     855         [ #  # ]:          0 :     while (!bStop)
     856                 :            :     {
     857         [ #  # ]:          0 :         if (bInSel)
     858                 :            :         {
     859         [ #  # ]:          0 :             nRow = rData.GetNextMarked(nCol, nRow, false);
     860         [ #  # ]:          0 :             if (!ValidRow(nRow))
     861                 :            :             {
     862                 :          0 :                 nRow = MAXROW+1;
     863                 :          0 :                 bStop = true;
     864                 :            :             }
     865                 :            :             else
     866                 :            :             {
     867         [ #  # ]:          0 :                 eCellType = GetCellType(nRow);
     868 [ #  # ][ #  # ]:          0 :                 if ( (eCellType == CELLTYPE_STRING || eCellType == CELLTYPE_EDIT) &&
         [ #  # ][ #  # ]
     869         [ #  # ]:          0 :                      !(HasAttrib( nRow, nRow, HASATTR_PROTECTED) &&
     870 [ #  # ][ #  # ]:          0 :                        pDocument->IsTabProtected(nTab)) )
     871                 :          0 :                         return true;
     872                 :            :                 else
     873                 :          0 :                     nRow++;
     874                 :            :             }
     875                 :            :         }
     876 [ #  # ][ #  # ]:          0 :         else if (GetNextDataPos(nRow))
     877                 :            :         {
     878         [ #  # ]:          0 :             eCellType = GetCellType(nRow);
     879 [ #  # ][ #  # ]:          0 :             if ( (eCellType == CELLTYPE_STRING || eCellType == CELLTYPE_EDIT) &&
         [ #  # ][ #  # ]
     880         [ #  # ]:          0 :                  !(HasAttrib( nRow, nRow, HASATTR_PROTECTED) &&
     881 [ #  # ][ #  # ]:          0 :                    pDocument->IsTabProtected(nTab)) )
     882                 :          0 :                     return true;
     883                 :            :             else
     884                 :          0 :                 nRow++;
     885                 :            :         }
     886                 :            :         else
     887                 :            :         {
     888                 :          0 :             nRow = MAXROW+1;
     889                 :          0 :             bStop = true;
     890                 :            :         }
     891                 :            :     }
     892                 :          0 :     return false;
     893                 :            : }
     894                 :            : 
     895                 :            : // =========================================================================================
     896                 :            : 
     897                 :          0 : void ScColumn::RemoveAutoSpellObj()
     898                 :            : {
     899                 :          0 :     ScTabEditEngine* pEngine = NULL;
     900                 :            : 
     901         [ #  # ]:          0 :     for (SCSIZE i=0; i<maItems.size(); i++)
     902         [ #  # ]:          0 :         if ( maItems[i].pCell->GetCellType() == CELLTYPE_EDIT )
     903                 :            :         {
     904                 :          0 :             ScEditCell* pOldCell = (ScEditCell*) maItems[i].pCell;
     905                 :          0 :             const EditTextObject* pData = pOldCell->GetData();
     906                 :            :             //  keine Abfrage auf HasOnlineSpellErrors, damit es auch
     907                 :            :             //  nach dem Laden funktioniert
     908                 :            : 
     909                 :            :             //  Fuer den Test auf harte Formatierung (ScEditAttrTester) sind die Defaults
     910                 :            :             //  in der EditEngine unwichtig. Wenn der Tester spaeter einmal gleiche
     911                 :            :             //  Attribute in Default und harter Formatierung erkennen und weglassen sollte,
     912                 :            :             //  muessten an der EditEngine zu jeder Zelle die richtigen Defaults gesetzt
     913                 :            :             //  werden!
     914                 :            : 
     915                 :            :             //  auf Attribute testen
     916         [ #  # ]:          0 :             if ( !pEngine )
     917 [ #  # ][ #  # ]:          0 :                 pEngine = new ScTabEditEngine(pDocument);
     918         [ #  # ]:          0 :             pEngine->SetText( *pData );
     919         [ #  # ]:          0 :             ScEditAttrTester aTester( pEngine );
     920         [ #  # ]:          0 :             if ( aTester.NeedsObject() )                    // nur Spell-Errors entfernen
     921                 :            :             {
     922         [ #  # ]:          0 :                 EditTextObject* pNewData = pEngine->CreateTextObject(); // ohne BIGOBJ
     923 [ #  # ][ #  # ]:          0 :                 pOldCell->SetData( pNewData, pEngine->GetEditTextObjectPool() );
     924 [ #  # ][ #  # ]:          0 :                 delete pNewData;
     925                 :            :             }
     926                 :            :             else                                            // String erzeugen
     927                 :            :             {
     928         [ #  # ]:          0 :                 String aText = ScEditUtil::GetSpaceDelimitedString( *pEngine );
     929 [ #  # ][ #  # ]:          0 :                 ScBaseCell* pNewCell = new ScStringCell( aText );
                 [ #  # ]
     930 [ #  # ][ #  # ]:          0 :                 pNewCell->TakeBroadcaster( pOldCell->ReleaseBroadcaster() );
     931                 :          0 :                 maItems[i].pCell = pNewCell;
     932 [ #  # ][ #  # ]:          0 :                 delete pOldCell;
         [ #  # ][ #  # ]
     933         [ #  # ]:          0 :             }
     934                 :            :         }
     935                 :            : 
     936         [ #  # ]:          0 :     delete pEngine;
     937                 :          0 : }
     938                 :            : 
     939                 :          0 : void ScColumn::RemoveEditAttribs( SCROW nStartRow, SCROW nEndRow )
     940                 :            : {
     941                 :          0 :     ScFieldEditEngine* pEngine = NULL;
     942                 :            : 
     943                 :            :     SCSIZE i;
     944         [ #  # ]:          0 :     Search( nStartRow, i );
     945 [ #  # ][ #  # ]:          0 :     for (; i<maItems.size() && maItems[i].nRow <= nEndRow; i++)
                 [ #  # ]
     946         [ #  # ]:          0 :         if ( maItems[i].pCell->GetCellType() == CELLTYPE_EDIT )
     947                 :            :         {
     948                 :          0 :             ScEditCell* pOldCell = (ScEditCell*) maItems[i].pCell;
     949                 :          0 :             const EditTextObject* pData = pOldCell->GetData();
     950                 :            : 
     951                 :            :             //  Fuer den Test auf harte Formatierung (ScEditAttrTester) sind die Defaults
     952                 :            :             //  in der EditEngine unwichtig. Wenn der Tester spaeter einmal gleiche
     953                 :            :             //  Attribute in Default und harter Formatierung erkennen und weglassen sollte,
     954                 :            :             //  muessten an der EditEngine zu jeder Zelle die richtigen Defaults gesetzt
     955                 :            :             //  werden!
     956                 :            : 
     957                 :            :             //  auf Attribute testen
     958         [ #  # ]:          0 :             if ( !pEngine )
     959                 :            :             {
     960 [ #  # ][ #  # ]:          0 :                 pEngine = new ScFieldEditEngine(pDocument, pDocument->GetEditPool());
                 [ #  # ]
     961                 :            :                 //  EE_CNTRL_ONLINESPELLING falls schon Fehler drin sind
     962 [ #  # ][ #  # ]:          0 :                 pEngine->SetControlWord( pEngine->GetControlWord() | EE_CNTRL_ONLINESPELLING );
     963         [ #  # ]:          0 :                 pDocument->ApplyAsianEditSettings( *pEngine );
     964                 :            :             }
     965         [ #  # ]:          0 :             pEngine->SetText( *pData );
     966         [ #  # ]:          0 :             sal_uInt16 nParCount = pEngine->GetParagraphCount();
     967         [ #  # ]:          0 :             for (sal_uInt16 nPar=0; nPar<nParCount; nPar++)
     968                 :            :             {
     969         [ #  # ]:          0 :                 pEngine->QuickRemoveCharAttribs( nPar );
     970         [ #  # ]:          0 :                 const SfxItemSet& rOld = pEngine->GetParaAttribs( nPar );
     971         [ #  # ]:          0 :                 if ( rOld.Count() )
     972                 :            :                 {
     973         [ #  # ]:          0 :                     SfxItemSet aNew( *rOld.GetPool(), rOld.GetRanges() );   // leer
     974 [ #  # ][ #  # ]:          0 :                     pEngine->SetParaAttribs( nPar, aNew );
     975                 :            :                 }
     976                 :            :             }
     977                 :            :             //  URL-Felder in Text wandeln (andere gibt's nicht, darum pType=0)
     978         [ #  # ]:          0 :             pEngine->RemoveFields( true );
     979                 :            : 
     980         [ #  # ]:          0 :             bool bSpellErrors = pEngine->HasOnlineSpellErrors();
     981 [ #  # ][ #  # ]:          0 :             bool bNeedObject = bSpellErrors || nParCount>1;         // Errors/Absaetze behalten
     982                 :            :             //  ScEditAttrTester nicht mehr noetig, Felder sind raus
     983                 :            : 
     984         [ #  # ]:          0 :             if ( bNeedObject )                                      // bleibt Edit-Zelle
     985                 :            :             {
     986         [ #  # ]:          0 :                 sal_uInt32 nCtrl = pEngine->GetControlWord();
     987         [ #  # ]:          0 :                 sal_uInt32 nWantBig = bSpellErrors ? EE_CNTRL_ALLOWBIGOBJS : 0;
     988         [ #  # ]:          0 :                 if ( ( nCtrl & EE_CNTRL_ALLOWBIGOBJS ) != nWantBig )
     989         [ #  # ]:          0 :                     pEngine->SetControlWord( (nCtrl & ~EE_CNTRL_ALLOWBIGOBJS) | nWantBig );
     990         [ #  # ]:          0 :                 EditTextObject* pNewData = pEngine->CreateTextObject();
     991 [ #  # ][ #  # ]:          0 :                 pOldCell->SetData( pNewData, pEngine->GetEditTextObjectPool() );
     992 [ #  # ][ #  # ]:          0 :                 delete pNewData;
     993                 :            :             }
     994                 :            :             else                                            // String erzeugen
     995                 :            :             {
     996         [ #  # ]:          0 :                 String aText = ScEditUtil::GetSpaceDelimitedString( *pEngine );
     997 [ #  # ][ #  # ]:          0 :                 ScBaseCell* pNewCell = new ScStringCell( aText );
                 [ #  # ]
     998 [ #  # ][ #  # ]:          0 :                 pNewCell->TakeBroadcaster( pOldCell->ReleaseBroadcaster() );
     999                 :          0 :                 maItems[i].pCell = pNewCell;
    1000 [ #  # ][ #  # ]:          0 :                 delete pOldCell;
         [ #  # ][ #  # ]
    1001                 :            :             }
    1002                 :            :         }
    1003                 :            : 
    1004 [ #  # ][ #  # ]:          0 :     delete pEngine;
    1005                 :          0 : }
    1006                 :            : 
    1007                 :            : // =========================================================================================
    1008                 :            : 
    1009                 :          8 : bool ScColumn::TestTabRefAbs(SCTAB nTable) const
    1010                 :            : {
    1011                 :          8 :     bool bRet = false;
    1012         [ +  - ]:          8 :     if ( !maItems.empty() )
    1013         [ +  + ]:         28 :         for (SCSIZE i = 0; i < maItems.size(); i++)
    1014         [ +  + ]:         20 :             if ( maItems[i].pCell->GetCellType() == CELLTYPE_FORMULA )
    1015 [ +  - ][ +  + ]:          4 :                 if (((ScFormulaCell*)maItems[i].pCell)->TestTabRefAbs(nTable))
    1016                 :          2 :                     bRet = true;
    1017                 :          8 :     return bRet;
    1018                 :            : }
    1019                 :            : 
    1020                 :            : // =========================================================================================
    1021                 :            : 
    1022                 :     478444 : ScColumnIterator::ScColumnIterator( const ScColumn* pCol, SCROW nStart, SCROW nEnd ) :
    1023                 :            :     pColumn( pCol ),
    1024                 :            :     nTop( nStart ),
    1025                 :     478444 :     nBottom( nEnd )
    1026                 :            : {
    1027                 :     478444 :     pColumn->Search( nTop, nPos );
    1028                 :     478444 : }
    1029                 :            : 
    1030                 :     478444 : ScColumnIterator::~ScColumnIterator()
    1031                 :            : {
    1032                 :     478444 : }
    1033                 :            : 
    1034                 :     490075 : bool ScColumnIterator::Next( SCROW& rRow, ScBaseCell*& rpCell )
    1035                 :            : {
    1036         [ +  + ]:     490075 :     if ( nPos < pColumn->maItems.size() )
    1037                 :            :     {
    1038                 :      12816 :         rRow = pColumn->maItems[nPos].nRow;
    1039         [ +  + ]:      12816 :         if ( rRow <= nBottom )
    1040                 :            :         {
    1041                 :      12108 :             rpCell = pColumn->maItems[nPos].pCell;
    1042                 :      12108 :             ++nPos;
    1043                 :      12108 :             return true;
    1044                 :            :         }
    1045                 :            :     }
    1046                 :            : 
    1047                 :     477967 :     rRow = 0;
    1048                 :     477967 :     rpCell = NULL;
    1049                 :     490075 :     return false;
    1050                 :            : }
    1051                 :            : 
    1052                 :          0 : SCSIZE ScColumnIterator::GetIndex() const           // Index zur letzen abgefragten Zelle
    1053                 :            : {
    1054                 :          0 :     return nPos - 1;        // bei Next ist Pos hochgezaehlt worden
    1055                 :            : }
    1056                 :            : 
    1057                 :            : // -----------------------------------------------------------------------------------------
    1058                 :            : 
    1059                 :       2244 : ScMarkedDataIter::ScMarkedDataIter( const ScColumn* pCol, const ScMarkData* pMarkData,
    1060                 :            :                                     bool bAllIfNone ) :
    1061                 :            :     pColumn( pCol ),
    1062                 :            :     pMarkIter( NULL ),
    1063                 :            :     bNext( true ),
    1064                 :       2244 :     bAll( bAllIfNone )
    1065                 :            : {
    1066 [ +  + ][ +  - ]:       2244 :     if (pMarkData && pMarkData->IsMultiMarked())
                 [ +  + ]
    1067         [ +  - ]:       2240 :         pMarkIter = new ScMarkArrayIter( pMarkData->GetArray() + pCol->GetCol() );
    1068                 :       2244 : }
    1069                 :            : 
    1070                 :       2244 : ScMarkedDataIter::~ScMarkedDataIter()
    1071                 :            : {
    1072         [ +  + ]:       2244 :     delete pMarkIter;
    1073                 :       2244 : }
    1074                 :            : 
    1075                 :      10083 : bool ScMarkedDataIter::Next( SCSIZE& rIndex )
    1076                 :            : {
    1077                 :      10083 :     bool bFound = false;
    1078         [ +  + ]:       7855 :     do
    1079                 :            :     {
    1080         [ +  + ]:      10099 :         if (bNext)
    1081                 :            :         {
    1082 [ +  + ][ +  + ]:       2260 :             if (!pMarkIter || !pMarkIter->Next( nTop, nBottom ))
                 [ +  + ]
    1083                 :            :             {
    1084         [ +  + ]:       2052 :                 if (bAll)                   // ganze Spalte
    1085                 :            :                 {
    1086                 :          4 :                     nTop    = 0;
    1087                 :          4 :                     nBottom = MAXROW;
    1088                 :            :                 }
    1089                 :            :                 else
    1090                 :       2048 :                     return false;
    1091                 :            :             }
    1092                 :        212 :             pColumn->Search( nTop, nPos );
    1093                 :        212 :             bNext = false;
    1094                 :        212 :             bAll  = false;                  // nur beim ersten Versuch
    1095                 :            :         }
    1096                 :            : 
    1097         [ +  + ]:       8051 :         if ( nPos >= pColumn->maItems.size() )
    1098                 :        196 :             return false;
    1099                 :            : 
    1100         [ +  + ]:       7855 :         if ( pColumn->maItems[nPos].nRow <= nBottom )
    1101                 :       7839 :             bFound = true;
    1102                 :            :         else
    1103                 :         16 :             bNext = true;
    1104                 :            :     }
    1105                 :       7855 :     while (!bFound);
    1106                 :            : 
    1107                 :       7839 :     rIndex = nPos++;
    1108                 :      10083 :     return true;
    1109                 :            : }
    1110                 :            : 
    1111                 :            : 
    1112                 :            : //------------
    1113                 :            : 
    1114                 :     778748 : bool ScColumn::IsEmptyData() const
    1115                 :            : {
    1116                 :     778748 :     return (maItems.empty());
    1117                 :            : }
    1118                 :            : 
    1119                 :    2268892 : bool ScColumn::IsEmptyVisData() const
    1120                 :            : {
    1121         [ +  + ]:    2268892 :     if ( maItems.empty() )
    1122                 :    2267241 :         return true;
    1123                 :            :     else
    1124                 :            :     {
    1125                 :       1651 :         bool bVisData = false;
    1126                 :            :         SCSIZE i;
    1127 [ +  + ][ +  + ]:       3302 :         for (i=0; i<maItems.size() && !bVisData; i++)
                 [ +  + ]
    1128                 :            :         {
    1129                 :       1651 :             bVisData = true;
    1130                 :            :         }
    1131                 :    2268892 :         return !bVisData;
    1132                 :            :     }
    1133                 :            : }
    1134                 :            : 
    1135                 :          8 : SCSIZE ScColumn::VisibleCount( SCROW nStartRow, SCROW nEndRow ) const
    1136                 :            : {
    1137                 :            :     //  Notizen werden nicht mitgezaehlt
    1138                 :            : 
    1139                 :          8 :     SCSIZE nVisCount = 0;
    1140                 :            :     SCSIZE nIndex;
    1141         [ +  - ]:          8 :     Search( nStartRow, nIndex );
    1142 [ +  + ][ +  - ]:         11 :     while ( nIndex < maItems.size() && maItems[nIndex].nRow <= nEndRow )
                 [ +  + ]
    1143                 :            :     {
    1144         [ +  - ]:          3 :         if ( maItems[nIndex].nRow >= nStartRow )
    1145                 :            :         {
    1146                 :          3 :             ++nVisCount;
    1147                 :            :         }
    1148                 :          3 :         ++nIndex;
    1149                 :            :     }
    1150                 :          8 :     return nVisCount;
    1151                 :            : }
    1152                 :            : 
    1153                 :    1335300 : SCROW ScColumn::GetLastVisDataPos() const
    1154                 :            : {
    1155                 :    1335300 :     SCROW nRet = 0;
    1156         [ +  + ]:    1335300 :     if ( !maItems.empty() )
    1157                 :            :     {
    1158                 :            :         SCSIZE i;
    1159                 :       2368 :         bool bFound = false;
    1160 [ +  + ][ +  + ]:       4736 :         for (i=maItems.size(); i>0 && !bFound; )
                 [ +  + ]
    1161                 :            :         {
    1162                 :       2368 :             --i;
    1163                 :       2368 :             bFound = true;
    1164                 :       2368 :             nRet = maItems[i].nRow;
    1165                 :            :         }
    1166                 :            :     }
    1167                 :    1335300 :     return nRet;
    1168                 :            : }
    1169                 :            : 
    1170                 :        331 : SCROW ScColumn::GetFirstVisDataPos() const
    1171                 :            : {
    1172                 :        331 :     SCROW nRet = 0;
    1173         [ +  - ]:        331 :     if ( !maItems.empty() )
    1174                 :            :     {
    1175                 :            :         SCSIZE i;
    1176                 :        331 :         bool bFound = false;
    1177 [ +  + ][ +  + ]:        662 :         for (i=0; i<maItems.size() && !bFound; i++)
                 [ +  + ]
    1178                 :            :         {
    1179                 :        331 :             bFound = true;
    1180                 :        331 :             nRet = maItems[i].nRow;
    1181                 :            :         }
    1182                 :            :     }
    1183                 :        331 :     return nRet;
    1184                 :            : }
    1185                 :            : 
    1186                 :       3114 : bool ScColumn::HasVisibleDataAt(SCROW nRow) const
    1187                 :            : {
    1188                 :            :     SCSIZE nIndex;
    1189 [ +  - ][ +  + ]:       3114 :     if (Search(nRow, nIndex))
    1190 [ +  - ][ +  - ]:         36 :         if (!maItems[nIndex].pCell->IsBlank())
    1191                 :         36 :             return true;
    1192                 :            : 
    1193                 :       3114 :     return false;
    1194                 :            : }
    1195                 :            : 
    1196                 :          7 : bool ScColumn::IsEmptyAttr() const
    1197                 :            : {
    1198         [ +  - ]:          7 :     if (pAttrArray)
    1199                 :          7 :         return pAttrArray->IsEmpty();
    1200                 :            :     else
    1201                 :          7 :         return true;
    1202                 :            : }
    1203                 :            : 
    1204                 :          7 : bool ScColumn::IsEmpty() const
    1205                 :            : {
    1206 [ +  - ][ +  - ]:          7 :     return (IsEmptyData() && IsEmptyAttr());
    1207                 :            : }
    1208                 :            : 
    1209                 :    2729815 : bool ScColumn::IsEmptyBlock(SCROW nStartRow, SCROW nEndRow) const
    1210                 :            : {
    1211         [ +  + ]:    2729815 :     if ( maItems.empty() )
    1212                 :    2728757 :         return true;
    1213                 :            : 
    1214                 :            :     SCSIZE nIndex;
    1215         [ +  - ]:       1058 :     Search( nStartRow, nIndex );
    1216 [ +  + ][ +  + ]:       1058 :     while ( nIndex < maItems.size() && maItems[nIndex].nRow <= nEndRow )
                 [ +  + ]
    1217                 :            :     {
    1218 [ +  - ][ +  - ]:        535 :         if ( !maItems[nIndex].pCell->IsBlank() )   // found a cell
    1219                 :        535 :             return false;                           // not empty
    1220                 :          0 :         ++nIndex;
    1221                 :            :     }
    1222                 :    2729815 :     return true;                                    // no cell found
    1223                 :            : }
    1224                 :            : 
    1225                 :         24 : SCSIZE ScColumn::GetEmptyLinesInBlock( SCROW nStartRow, SCROW nEndRow, ScDirection eDir ) const
    1226                 :            : {
    1227                 :         24 :     SCSIZE nLines = 0;
    1228                 :         24 :     bool bFound = false;
    1229                 :            :     SCSIZE i;
    1230         [ +  + ]:         24 :     if ( !maItems.empty() )
    1231                 :            :     {
    1232         [ +  - ]:         21 :         if (eDir == DIR_BOTTOM)
    1233                 :            :         {
    1234                 :         21 :             i = maItems.size();
    1235 [ +  + ][ +  - ]:         44 :             while (!bFound && (i > 0))
                 [ +  + ]
    1236                 :            :             {
    1237                 :         23 :                 i--;
    1238         [ -  + ]:         23 :                 if ( maItems[i].nRow < nStartRow )
    1239                 :          0 :                     break;
    1240 [ +  + ][ +  - ]:         23 :                 bFound = maItems[i].nRow <= nEndRow && !maItems[i].pCell->IsBlank();
    1241                 :            :             }
    1242         [ +  - ]:         21 :             if (bFound)
    1243                 :         21 :                 nLines = static_cast<SCSIZE>(nEndRow - maItems[i].nRow);
    1244                 :            :             else
    1245                 :          0 :                 nLines = static_cast<SCSIZE>(nEndRow - nStartRow);
    1246                 :            :         }
    1247         [ #  # ]:          0 :         else if (eDir == DIR_TOP)
    1248                 :            :         {
    1249                 :          0 :             i = 0;
    1250 [ #  # ][ #  # ]:          0 :             while (!bFound && (i < maItems.size()))
                 [ #  # ]
    1251                 :            :             {
    1252         [ #  # ]:          0 :                 if ( maItems[i].nRow > nEndRow )
    1253                 :          0 :                     break;
    1254 [ #  # ][ #  # ]:          0 :                 bFound = maItems[i].nRow >= nStartRow && !maItems[i].pCell->IsBlank();
    1255                 :          0 :                 i++;
    1256                 :            :             }
    1257         [ #  # ]:          0 :             if (bFound)
    1258                 :          0 :                 nLines = static_cast<SCSIZE>(maItems[i-1].nRow - nStartRow);
    1259                 :            :             else
    1260                 :          0 :                 nLines = static_cast<SCSIZE>(nEndRow - nStartRow);
    1261                 :            :         }
    1262                 :            :     }
    1263                 :            :     else
    1264                 :          3 :         nLines = static_cast<SCSIZE>(nEndRow - nStartRow);
    1265                 :         24 :     return nLines;
    1266                 :            : }
    1267                 :            : 
    1268                 :       1491 : SCROW ScColumn::GetFirstDataPos() const
    1269                 :            : {
    1270         [ +  - ]:       1491 :     if ( !maItems.empty() )
    1271                 :       1491 :         return maItems[0].nRow;
    1272                 :            :     else
    1273                 :       1491 :         return 0;
    1274                 :            : }
    1275                 :            : 
    1276                 :       9571 : SCROW ScColumn::GetLastDataPos() const
    1277                 :            : {
    1278         [ +  + ]:       9571 :     if ( !maItems.empty() )
    1279                 :       9098 :         return maItems.back().nRow;
    1280                 :            :     else
    1281                 :       9571 :         return 0;
    1282                 :            : }
    1283                 :            : 
    1284                 :          0 : bool ScColumn::GetPrevDataPos(SCROW& rRow) const
    1285                 :            : {
    1286                 :          0 :     bool bFound = false;
    1287                 :          0 :     SCSIZE i = maItems.size();
    1288 [ #  # ][ #  # ]:          0 :     while (!bFound && (i > 0))
                 [ #  # ]
    1289                 :            :     {
    1290                 :          0 :         --i;
    1291                 :          0 :         bFound = (maItems[i].nRow < rRow);
    1292         [ #  # ]:          0 :         if (bFound)
    1293                 :          0 :             rRow = maItems[i].nRow;
    1294                 :            :     }
    1295                 :          0 :     return bFound;
    1296                 :            : }
    1297                 :            : 
    1298                 :       1375 : bool ScColumn::GetNextDataPos(SCROW& rRow) const        // greater than rRow
    1299                 :            : {
    1300                 :            :     SCSIZE nIndex;
    1301 [ +  - ][ +  + ]:       1375 :     if (Search( rRow, nIndex ))
    1302                 :       1189 :         ++nIndex;                   // next cell
    1303                 :            : 
    1304                 :       1375 :     bool bMore = ( nIndex < maItems.size() );
    1305         [ +  + ]:       1375 :     if ( bMore )
    1306                 :       1029 :         rRow = maItems[nIndex].nRow;
    1307                 :       1375 :     return bMore;
    1308                 :            : }
    1309                 :            : 
    1310                 :         27 : SCROW ScColumn::FindNextVisibleRow(SCROW nRow, bool bForward) const
    1311                 :            : {
    1312         [ +  - ]:         27 :     if(bForward)
    1313                 :            :     {
    1314                 :         27 :         nRow++;
    1315                 :         27 :         SCROW nEndRow = 0;
    1316         [ +  - ]:         27 :         bool bHidden = pDocument->RowHidden(nRow, nTab, NULL, &nEndRow);
    1317         [ +  + ]:         27 :         if(bHidden)
    1318         [ +  - ]:          6 :             return std::min<SCROW>(MAXROW, nEndRow + 1);
    1319                 :            :         else
    1320                 :         27 :             return nRow;
    1321                 :            :     }
    1322                 :            :     else
    1323                 :            :     {
    1324                 :          0 :         nRow--;
    1325                 :          0 :         SCROW nStartRow = MAXROW;
    1326         [ #  # ]:          0 :         bool bHidden = pDocument->RowHidden(nRow, nTab, &nStartRow, NULL);
    1327         [ #  # ]:          0 :         if(bHidden)
    1328         [ #  # ]:          0 :             return std::max<SCROW>(0, nStartRow - 1);
    1329                 :            :         else
    1330                 :         27 :             return nRow;
    1331                 :            :     }
    1332                 :            : }
    1333                 :            : 
    1334                 :         12 : SCROW ScColumn::FindNextVisibleRowWithContent(SCROW nRow, bool bForward) const
    1335                 :            : {
    1336         [ +  - ]:         12 :     if(bForward)
    1337                 :            :     {
    1338         [ #  # ]:         12 :         do
    1339                 :            :         {
    1340                 :         12 :             nRow++;
    1341                 :         12 :             SCROW nEndRow = 0;
    1342         [ +  - ]:         12 :             bool bHidden = pDocument->RowHidden(nRow, nTab, NULL, &nEndRow);
    1343         [ +  + ]:         12 :             if(bHidden)
    1344                 :            :             {
    1345                 :          3 :                 nRow = nEndRow + 1;
    1346         [ -  + ]:          3 :                 if(nRow >= MAXROW)
    1347                 :          0 :                     return MAXROW;
    1348                 :            :             }
    1349                 :            : 
    1350                 :            :             SCSIZE nIndex;
    1351         [ +  - ]:         12 :             bool bThere = Search( nRow, nIndex );
    1352 [ +  + ][ +  - ]:         12 :             if( bThere && !maItems[nIndex].pCell->IsBlank())
         [ +  - ][ +  + ]
    1353                 :          9 :                 return nRow;
    1354         [ +  - ]:          3 :             else if(nIndex >= maItems.size())
    1355                 :          3 :                 return MAXROW;
    1356                 :            :             else
    1357                 :            :             {
    1358         [ #  # ]:          0 :                 if(bThere)
    1359                 :          0 :                     nRow = maItems[nIndex+1].nRow - 1;
    1360                 :            :                 else
    1361                 :          0 :                     nRow = maItems[nIndex].nRow - 1;
    1362                 :            :             }
    1363                 :            :         }
    1364                 :            :         while(nRow < MAXROW);
    1365                 :            : 
    1366                 :          0 :         return MAXROW;
    1367                 :            :     }
    1368                 :            :     else
    1369                 :            :     {
    1370         [ #  # ]:          0 :         do
    1371                 :            :         {
    1372                 :          0 :             nRow--;
    1373                 :          0 :             SCROW nStartRow = MAXROW;
    1374         [ #  # ]:          0 :             bool bHidden = pDocument->RowHidden(nRow, nTab, &nStartRow, NULL);
    1375         [ #  # ]:          0 :             if(bHidden)
    1376                 :            :             {
    1377                 :          0 :                 nRow = nStartRow - 1;
    1378         [ #  # ]:          0 :                 if(nRow <= 0)
    1379                 :          0 :                     return 0;
    1380                 :            :             }
    1381                 :            : 
    1382                 :            :             SCSIZE nIndex;
    1383         [ #  # ]:          0 :             bool bThere = Search( nRow, nIndex );
    1384 [ #  # ][ #  # ]:          0 :             if(bThere && !maItems[nIndex].pCell->IsBlank())
         [ #  # ][ #  # ]
    1385                 :          0 :                 return nRow;
    1386         [ #  # ]:          0 :             else if(nIndex == 0)
    1387                 :          0 :                 return 0;
    1388                 :            :             else
    1389                 :          0 :                 nRow = maItems[nIndex-1].nRow + 1;
    1390                 :            :         }
    1391                 :            :         while(nRow > 0);
    1392                 :            : 
    1393                 :         12 :         return 0;
    1394                 :            :     }
    1395                 :            : }
    1396                 :            : 
    1397                 :         21 : void ScColumn::FindDataAreaPos(SCROW& rRow, bool bDown) const
    1398                 :            : {
    1399                 :            :     // check if we are in a data area
    1400                 :            :     SCSIZE nIndex;
    1401         [ +  - ]:         21 :     bool bThere = Search(rRow, nIndex);
    1402 [ +  + ][ +  - ]:         21 :     if (bThere && maItems[nIndex].pCell->IsBlank())
         [ -  + ][ -  + ]
    1403                 :          0 :         bThere = false;
    1404                 :            : 
    1405                 :         21 :     size_t nLastIndex = maItems.size() - 1;
    1406         [ +  + ]:         21 :     if (bThere)
    1407                 :            :     {
    1408         [ +  - ]:         18 :         SCROW nNextRow = FindNextVisibleRow(rRow, bDown);
    1409                 :            :         SCSIZE nNewIndex;
    1410         [ +  - ]:         18 :         bool bNextThere = Search(nNextRow, nNewIndex);
    1411 [ +  + ][ +  - ]:         18 :         if(bNextThere && maItems[nNewIndex].pCell->IsBlank())
         [ -  + ][ -  + ]
    1412                 :          0 :             bNextThere = false;
    1413                 :            : 
    1414         [ +  + ]:         18 :         if(bNextThere)
    1415                 :            :         {
    1416                 :            :             SCROW nLastRow;
    1417                 :          9 :             nLastRow = nNextRow;
    1418 [ -  + ][ #  # ]:          9 :             do
         [ #  # ][ -  + ]
    1419                 :            :             {
    1420         [ +  - ]:          9 :                 nNextRow = FindNextVisibleRow(nLastRow, bDown);
    1421         [ +  - ]:          9 :                 bNextThere = Search(nNextRow, nNewIndex);
    1422 [ -  + ][ #  # ]:          9 :                 if(!bNextThere || maItems[nNewIndex].pCell->IsBlank())
         [ #  # ][ +  - ]
    1423                 :          9 :                     bNextThere = false;
    1424                 :            :                 else
    1425                 :          0 :                     nLastRow = nNextRow;
    1426                 :            :             }
    1427                 :            :             while(bNextThere && nNewIndex < nLastIndex && nNewIndex > 0);
    1428                 :            : 
    1429                 :          9 :             rRow = nLastRow;
    1430                 :            :         }
    1431                 :            :         else
    1432                 :            :         {
    1433         [ +  - ]:         18 :             rRow = FindNextVisibleRowWithContent(nNextRow, bDown);
    1434                 :            :         }
    1435                 :            :     }
    1436                 :            :     else
    1437                 :            :     {
    1438         [ +  - ]:          3 :         rRow = FindNextVisibleRowWithContent(rRow, bDown);
    1439                 :            :     }
    1440                 :         21 : }
    1441                 :            : 
    1442                 :       4178 : bool ScColumn::HasDataAt(SCROW nRow) const
    1443                 :            : {
    1444                 :            :         //  immer nur sichtbare interessant ?
    1445                 :            :         //! dann HasVisibleDataAt raus
    1446                 :            : 
    1447                 :            :     SCSIZE nIndex;
    1448 [ +  - ][ +  + ]:       4178 :     if (Search(nRow, nIndex))
    1449 [ +  - ][ +  - ]:        645 :         if (!maItems[nIndex].pCell->IsBlank())
    1450                 :        645 :             return true;
    1451                 :            : 
    1452                 :       4178 :     return false;
    1453                 :            : 
    1454                 :            : }
    1455                 :            : 
    1456                 :      14340 : bool ScColumn::IsAllAttrEqual( const ScColumn& rCol, SCROW nStartRow, SCROW nEndRow ) const
    1457                 :            : {
    1458 [ +  - ][ +  - ]:      14340 :     if (pAttrArray && rCol.pAttrArray)
    1459                 :      14340 :         return pAttrArray->IsAllEqual( *rCol.pAttrArray, nStartRow, nEndRow );
    1460                 :            :     else
    1461 [ #  # ][ #  # ]:      14340 :         return !pAttrArray && !rCol.pAttrArray;
    1462                 :            : }
    1463                 :            : 
    1464                 :         12 : bool ScColumn::IsVisibleAttrEqual( const ScColumn& rCol, SCROW nStartRow, SCROW nEndRow ) const
    1465                 :            : {
    1466 [ +  - ][ +  - ]:         12 :     if (pAttrArray && rCol.pAttrArray)
    1467                 :         12 :         return pAttrArray->IsVisibleEqual( *rCol.pAttrArray, nStartRow, nEndRow );
    1468                 :            :     else
    1469 [ #  # ][ #  # ]:         12 :         return !pAttrArray && !rCol.pAttrArray;
    1470                 :            : }
    1471                 :            : 
    1472                 :     893952 : bool ScColumn::GetFirstVisibleAttr( SCROW& rFirstRow ) const
    1473                 :            : {
    1474         [ +  - ]:     893952 :     if (pAttrArray)
    1475                 :     893952 :         return pAttrArray->GetFirstVisibleAttr( rFirstRow );
    1476                 :            :     else
    1477                 :     893952 :         return false;
    1478                 :            : }
    1479                 :            : 
    1480                 :    1333980 : bool ScColumn::GetLastVisibleAttr( SCROW& rLastRow, bool bFullFormattedArea ) const
    1481                 :            : {
    1482         [ +  - ]:    1333980 :     if (pAttrArray)
    1483                 :            :     {
    1484                 :            :         // row of last cell is needed
    1485                 :    1333980 :         SCROW nLastData = GetLastVisDataPos();    // always including notes, 0 if none
    1486                 :            : 
    1487                 :    1333980 :         return pAttrArray->GetLastVisibleAttr( rLastRow, nLastData, bFullFormattedArea );
    1488                 :            :     }
    1489                 :            :     else
    1490                 :    1333980 :         return false;
    1491                 :            : }
    1492                 :            : 
    1493                 :          0 : bool ScColumn::HasVisibleAttrIn( SCROW nStartRow, SCROW nEndRow ) const
    1494                 :            : {
    1495         [ #  # ]:          0 :     if (pAttrArray)
    1496                 :          0 :         return pAttrArray->HasVisibleAttrIn( nStartRow, nEndRow );
    1497                 :            :     else
    1498                 :          0 :         return false;
    1499                 :            : }
    1500                 :            : 
    1501                 :          5 : void ScColumn::FindUsed( SCROW nStartRow, SCROW nEndRow, bool* pUsed ) const
    1502                 :            : {
    1503                 :          5 :     SCROW nRow = 0;
    1504                 :            :     SCSIZE nIndex;
    1505         [ +  - ]:          5 :     Search( nStartRow, nIndex );
    1506 [ +  + ][ +  - ]:         20 :     while ( (nIndex < maItems.size()) ? ((nRow=maItems[nIndex].nRow) <= nEndRow) : false )
                 [ +  + ]
    1507                 :            :     {
    1508                 :         15 :         pUsed[nRow-nStartRow] = true;
    1509                 :         15 :         ++nIndex;
    1510                 :            :     }
    1511                 :          5 : }
    1512                 :            : 
    1513                 :       5121 : void ScColumn::StartListening( SvtListener& rLst, SCROW nRow )
    1514                 :            : {
    1515                 :       5121 :     SvtBroadcaster* pBC = NULL;
    1516                 :            :     ScBaseCell* pCell;
    1517                 :            : 
    1518                 :            :     SCSIZE nIndex;
    1519 [ +  - ][ +  + ]:       5121 :     if (Search(nRow,nIndex))
    1520                 :            :     {
    1521                 :       5045 :         pCell = maItems[nIndex].pCell;
    1522                 :       5045 :         pBC = pCell->GetBroadcaster();
    1523                 :            :     }
    1524                 :            :     else
    1525                 :            :     {
    1526 [ +  - ][ +  - ]:         76 :         pCell = new ScNoteCell;
    1527         [ +  - ]:         76 :         Insert(nRow, pCell);
    1528                 :            :     }
    1529                 :            : 
    1530         [ +  + ]:       5121 :     if (!pBC)
    1531                 :            :     {
    1532 [ +  - ][ +  - ]:       2630 :         pBC = new SvtBroadcaster;
    1533         [ +  - ]:       2630 :         pCell->TakeBroadcaster(pBC);
    1534                 :            :     }
    1535         [ +  - ]:       5121 :     rLst.StartListening(*pBC);
    1536                 :       5121 : }
    1537                 :            : 
    1538                 :          0 : void ScColumn::MoveListeners( SvtBroadcaster& rSource, SCROW nDestRow )
    1539                 :            : {
    1540                 :          0 :     SvtBroadcaster* pBC = NULL;
    1541                 :            :     ScBaseCell* pCell;
    1542                 :            : 
    1543                 :            :     SCSIZE nIndex;
    1544 [ #  # ][ #  # ]:          0 :     if (Search(nDestRow,nIndex))
    1545                 :            :     {
    1546                 :          0 :         pCell = maItems[nIndex].pCell;
    1547                 :          0 :         pBC = pCell->GetBroadcaster();
    1548                 :            :     }
    1549                 :            :     else
    1550                 :            :     {
    1551 [ #  # ][ #  # ]:          0 :         pCell = new ScNoteCell;
    1552         [ #  # ]:          0 :         Insert(nDestRow, pCell);
    1553                 :            :     }
    1554                 :            : 
    1555         [ #  # ]:          0 :     if (!pBC)
    1556                 :            :     {
    1557 [ #  # ][ #  # ]:          0 :         pBC = new SvtBroadcaster;
    1558         [ #  # ]:          0 :         pCell->TakeBroadcaster(pBC);
    1559                 :            :     }
    1560                 :            : 
    1561         [ #  # ]:          0 :     if (rSource.HasListeners())
    1562                 :            :     {
    1563         [ #  # ]:          0 :         SvtListenerIter aIter( rSource);
    1564 [ #  # ][ #  # ]:          0 :         for (SvtListener* pLst = aIter.GoStart(); pLst; pLst = aIter.GoNext())
                 [ #  # ]
    1565                 :            :         {
    1566         [ #  # ]:          0 :             pLst->StartListening( *pBC);
    1567         [ #  # ]:          0 :             pLst->EndListening( rSource);
    1568         [ #  # ]:          0 :         }
    1569                 :            :     }
    1570                 :          0 : }
    1571                 :            : 
    1572                 :        488 : void ScColumn::EndListening( SvtListener& rLst, SCROW nRow )
    1573                 :            : {
    1574                 :            :     SCSIZE nIndex;
    1575 [ +  - ][ +  - ]:        488 :     if (Search(nRow,nIndex))
    1576                 :            :     {
    1577                 :        488 :         ScBaseCell* pCell = maItems[nIndex].pCell;
    1578                 :        488 :         SvtBroadcaster* pBC = pCell->GetBroadcaster();
    1579         [ +  + ]:        488 :         if (pBC)
    1580                 :            :         {
    1581         [ +  - ]:        472 :             rLst.EndListening(*pBC);
    1582                 :            : 
    1583         [ +  + ]:        472 :             if (!pBC->HasListeners())
    1584                 :            :             {
    1585 [ +  - ][ -  + ]:        311 :                 if (pCell->IsBlank())
    1586         [ #  # ]:          0 :                     DeleteAtIndex(nIndex);
    1587                 :            :                 else
    1588         [ +  - ]:        311 :                     pCell->DeleteBroadcaster();
    1589                 :            :             }
    1590                 :            :         }
    1591                 :            :     }
    1592                 :        488 : }
    1593                 :            : 
    1594                 :      16384 : void ScColumn::CompileDBFormula()
    1595                 :            : {
    1596         [ +  + ]:      16384 :     if ( !maItems.empty() )
    1597         [ +  + ]:       1184 :         for (SCSIZE i = 0; i < maItems.size(); i++)
    1598                 :            :         {
    1599                 :       1042 :             ScBaseCell* pCell = maItems[i].pCell;
    1600         [ +  + ]:       1042 :             if ( pCell->GetCellType() == CELLTYPE_FORMULA )
    1601         [ +  - ]:          7 :                 ((ScFormulaCell*) pCell)->CompileDBFormula();
    1602                 :            :         }
    1603                 :      16384 : }
    1604                 :            : 
    1605                 :      10240 : void ScColumn::CompileDBFormula( bool bCreateFormulaString )
    1606                 :            : {
    1607         [ +  + ]:      10240 :     if ( !maItems.empty() )
    1608         [ +  + ]:        176 :         for (SCSIZE i = 0; i < maItems.size(); i++)
    1609                 :            :         {
    1610                 :        168 :             ScBaseCell* pCell = maItems[i].pCell;
    1611         [ -  + ]:        168 :             if ( pCell->GetCellType() == CELLTYPE_FORMULA )
    1612         [ #  # ]:          0 :                 ((ScFormulaCell*) pCell)->CompileDBFormula( bCreateFormulaString );
    1613                 :            :         }
    1614                 :      10240 : }
    1615                 :            : 
    1616                 :     239616 : void ScColumn::CompileNameFormula( bool bCreateFormulaString )
    1617                 :            : {
    1618         [ +  + ]:     239616 :     if ( !maItems.empty() )
    1619         [ +  + ]:       2514 :         for (SCSIZE i = 0; i < maItems.size(); i++)
    1620                 :            :         {
    1621                 :       1998 :             ScBaseCell* pCell = maItems[i].pCell;
    1622         [ -  + ]:       1998 :             if ( pCell->GetCellType() == CELLTYPE_FORMULA )
    1623         [ #  # ]:          0 :                 ((ScFormulaCell*) pCell)->CompileNameFormula( bCreateFormulaString );
    1624                 :            :         }
    1625                 :     239616 : }
    1626                 :            : 
    1627                 :       7168 : void ScColumn::CompileColRowNameFormula()
    1628                 :            : {
    1629         [ -  + ]:       7168 :     if ( !maItems.empty() )
    1630         [ #  # ]:          0 :         for (SCSIZE i = 0; i < maItems.size(); i++)
    1631                 :            :         {
    1632                 :          0 :             ScBaseCell* pCell = maItems[i].pCell;
    1633         [ #  # ]:          0 :             if ( pCell->GetCellType() == CELLTYPE_FORMULA )
    1634         [ #  # ]:          0 :                 ((ScFormulaCell*) pCell)->CompileColRowNameFormula();
    1635                 :            :         }
    1636                 :       7168 : }
    1637                 :            : 
    1638                 :         64 : void lcl_UpdateSubTotal( ScFunctionData& rData, ScBaseCell* pCell )
    1639                 :            : {
    1640                 :         64 :     double nValue = 0.0;
    1641                 :         64 :     bool bVal = false;
    1642                 :         64 :     bool bCell = true;
    1643   [ +  -  -  + ]:         64 :     switch (pCell->GetCellType())
    1644                 :            :     {
    1645                 :            :         case CELLTYPE_VALUE:
    1646                 :         15 :             nValue = ((ScValueCell*)pCell)->GetValue();
    1647                 :         15 :             bVal = true;
    1648                 :         15 :             break;
    1649                 :            :         case CELLTYPE_FORMULA:
    1650                 :            :             {
    1651         [ #  # ]:          0 :                 if ( rData.eFunc != SUBTOTAL_FUNC_CNT2 )        // da interessiert's nicht
    1652                 :            :                 {
    1653         [ #  # ]:          0 :                     ScFormulaCell* pFC = (ScFormulaCell*)pCell;
    1654         [ #  # ]:          0 :                     if ( pFC->GetErrCode() )
    1655                 :            :                     {
    1656         [ #  # ]:          0 :                         if ( rData.eFunc != SUBTOTAL_FUNC_CNT ) // fuer Anzahl einfach weglassen
    1657                 :          0 :                             rData.bError = true;
    1658                 :            :                     }
    1659         [ #  # ]:          0 :                     else if (pFC->IsValue())
    1660                 :            :                     {
    1661                 :          0 :                         nValue = pFC->GetValue();
    1662                 :          0 :                         bVal = true;
    1663                 :            :                     }
    1664                 :            :                     // sonst Text
    1665                 :            :                 }
    1666                 :            :             }
    1667                 :          0 :             break;
    1668                 :            :         case CELLTYPE_NOTE:
    1669                 :          0 :             bCell = false;
    1670                 :          0 :             break;
    1671                 :            :         // bei Strings nichts
    1672                 :            :         default:
    1673                 :            :         {
    1674                 :            :             // added to avoid warnings
    1675                 :            :         }
    1676                 :            :     }
    1677                 :            : 
    1678         [ +  - ]:         64 :     if (!rData.bError)
    1679                 :            :     {
    1680   [ +  -  +  -  :         64 :         switch (rData.eFunc)
                   -  - ]
    1681                 :            :         {
    1682                 :            :             case SUBTOTAL_FUNC_SUM:
    1683                 :            :             case SUBTOTAL_FUNC_AVE:
    1684         [ +  + ]:         35 :                 if (bVal)
    1685                 :            :                 {
    1686                 :          9 :                     ++rData.nCount;
    1687         [ -  + ]:          9 :                     if (!SubTotal::SafePlus( rData.nVal, nValue ))
    1688                 :          0 :                         rData.bError = true;
    1689                 :            :                 }
    1690                 :         35 :                 break;
    1691                 :            :             case SUBTOTAL_FUNC_CNT:             // nur Werte
    1692         [ #  # ]:          0 :                 if (bVal)
    1693                 :          0 :                     ++rData.nCount;
    1694                 :          0 :                 break;
    1695                 :            :             case SUBTOTAL_FUNC_CNT2:            // alle
    1696         [ +  - ]:         29 :                 if (bCell)
    1697                 :         29 :                     ++rData.nCount;
    1698                 :         29 :                 break;
    1699                 :            :             case SUBTOTAL_FUNC_MAX:
    1700         [ #  # ]:          0 :                 if (bVal)
    1701 [ #  # ][ #  # ]:          0 :                     if (++rData.nCount == 1 || nValue > rData.nVal )
                 [ #  # ]
    1702                 :          0 :                         rData.nVal = nValue;
    1703                 :          0 :                 break;
    1704                 :            :             case SUBTOTAL_FUNC_MIN:
    1705         [ #  # ]:          0 :                 if (bVal)
    1706 [ #  # ][ #  # ]:          0 :                     if (++rData.nCount == 1 || nValue < rData.nVal )
                 [ #  # ]
    1707                 :          0 :                         rData.nVal = nValue;
    1708                 :         64 :                 break;
    1709                 :            :             default:
    1710                 :            :             {
    1711                 :            :                 // added to avoid warnings
    1712                 :            :             }
    1713                 :            :         }
    1714                 :            :     }
    1715                 :         64 : }
    1716                 :            : 
    1717                 :            : //  Mehrfachselektion:
    1718                 :       2048 : void ScColumn::UpdateSelectionFunction( const ScMarkData& rMark,
    1719                 :            :                                         ScFunctionData& rData,
    1720                 :            :                                         ScFlatBoolRowSegments& rHiddenRows,
    1721                 :            :                                         bool bDoExclude, SCROW nExStartRow, SCROW nExEndRow )
    1722                 :            : {
    1723                 :            :     SCSIZE nIndex;
    1724         [ +  - ]:       2048 :     ScMarkedDataIter aDataIter(this, &rMark, false);
    1725 [ +  - ][ +  + ]:       2092 :     while (aDataIter.Next( nIndex ))
    1726                 :            :     {
    1727                 :         44 :         SCROW nRow = maItems[nIndex].nRow;
    1728         [ +  - ]:         44 :         bool bRowHidden = rHiddenRows.getValue(nRow);
    1729         [ +  - ]:         44 :         if ( !bRowHidden )
    1730 [ -  + ][ #  # ]:         44 :             if ( !bDoExclude || nRow < nExStartRow || nRow > nExEndRow )
                 [ #  # ]
    1731         [ +  - ]:         44 :                 lcl_UpdateSubTotal( rData, maItems[nIndex].pCell );
    1732         [ +  - ]:       2048 :     }
    1733                 :       2048 : }
    1734                 :            : 
    1735                 :            : //  bei bNoMarked die Mehrfachselektion weglassen
    1736                 :        235 : void ScColumn::UpdateAreaFunction( ScFunctionData& rData,
    1737                 :            :                                    ScFlatBoolRowSegments& rHiddenRows,
    1738                 :            :                                     SCROW nStartRow, SCROW nEndRow )
    1739                 :            : {
    1740                 :            :     SCSIZE nIndex;
    1741         [ +  - ]:        235 :     Search( nStartRow, nIndex );
    1742 [ +  + ][ +  + ]:        261 :     while ( nIndex<maItems.size() && maItems[nIndex].nRow<=nEndRow )
                 [ +  + ]
    1743                 :            :     {
    1744                 :         26 :         SCROW nRow = maItems[nIndex].nRow;
    1745         [ +  - ]:         26 :         bool bRowHidden = rHiddenRows.getValue(nRow);
    1746         [ +  + ]:         26 :         if ( !bRowHidden )
    1747         [ +  - ]:         20 :             lcl_UpdateSubTotal( rData, maItems[nIndex].pCell );
    1748                 :         26 :         ++nIndex;
    1749                 :            :     }
    1750                 :        235 : }
    1751                 :            : 
    1752                 :      24405 : sal_uInt32 ScColumn::GetWeightedCount() const
    1753                 :            : {
    1754                 :      24405 :     sal_uInt32 nTotal = 0;
    1755                 :            : 
    1756                 :            :     //  Notizen werden nicht gezaehlt
    1757                 :            : 
    1758         [ +  + ]:     115562 :     for (SCSIZE i=0; i<maItems.size(); i++)
    1759                 :            :     {
    1760                 :      91157 :         ScBaseCell* pCell = maItems[i].pCell;
    1761   [ +  +  +  + ]:      91157 :         switch ( pCell->GetCellType() )
    1762                 :            :         {
    1763                 :            :             case CELLTYPE_VALUE:
    1764                 :            :             case CELLTYPE_STRING:
    1765                 :      89920 :                 ++nTotal;
    1766                 :      89920 :                 break;
    1767                 :            :             case CELLTYPE_FORMULA:
    1768         [ +  - ]:        446 :                 nTotal += 5 + ((ScFormulaCell*)pCell)->GetCode()->GetCodeLen();
    1769                 :        446 :                 break;
    1770                 :            :             case CELLTYPE_EDIT:
    1771                 :        784 :                 nTotal += 50;
    1772                 :        784 :                 break;
    1773                 :            :             default:
    1774                 :            :             {
    1775                 :            :                 // added to avoid warnings
    1776                 :            :             }
    1777                 :            :         }
    1778                 :            :     }
    1779                 :            : 
    1780                 :      24405 :     return nTotal;
    1781                 :            : }
    1782                 :            : 
    1783                 :          0 : sal_uInt32 ScColumn::GetCodeCount() const
    1784                 :            : {
    1785                 :          0 :     sal_uInt32 nCodeCount = 0;
    1786                 :            : 
    1787         [ #  # ]:          0 :     for (SCSIZE i=0; i<maItems.size(); i++)
    1788                 :            :     {
    1789                 :          0 :         ScBaseCell* pCell = maItems[i].pCell;
    1790         [ #  # ]:          0 :         if ( pCell->GetCellType() == CELLTYPE_FORMULA )
    1791         [ #  # ]:          0 :             nCodeCount += ((ScFormulaCell*)pCell)->GetCode()->GetCodeLen();
    1792                 :            :     }
    1793                 :            : 
    1794                 :          0 :     return nCodeCount;
    1795                 :            : }
    1796                 :            : 
    1797                 :            : 
    1798                 :            : 
    1799                 :            : 
    1800                 :            : 
    1801                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10