LCOV - code coverage report
Current view: top level - sc/source/core/tool - consoli.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 65 413 15.7 %
Date: 2012-08-25 Functions: 9 18 50.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 35 557 6.3 %

           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 "consoli.hxx"
      30                 :            : #include "document.hxx"
      31                 :            : #include "olinetab.hxx"
      32                 :            : #include "globstr.hrc"
      33                 :            : #include "subtotal.hxx"
      34                 :            : #include "formula/errorcodes.hxx"
      35                 :            : #include "cell.hxx"
      36                 :            : 
      37                 :            : #include <math.h>
      38                 :            : #include <string.h>
      39                 :            : 
      40                 :            : #define SC_CONS_NOTFOUND    -1
      41                 :            : 
      42                 :            : // STATIC DATA -----------------------------------------------------------
      43                 :            : 
      44                 :            : static OpCode eOpCodeTable[] = {            //  Reihenfolge wie bei enum ScSubTotalFunc
      45                 :            :         ocBad,                              //  none
      46                 :            :         ocAverage,
      47                 :            :         ocCount,
      48                 :            :         ocCount2,
      49                 :            :         ocMax,
      50                 :            :         ocMin,
      51                 :            :         ocProduct,
      52                 :            :         ocStDev,
      53                 :            :         ocStDevP,
      54                 :            :         ocSum,
      55                 :            :         ocVar,
      56                 :            :         ocVarP };
      57                 :            : 
      58                 :            : // -----------------------------------------------------------------------
      59                 :            : 
      60                 :          0 : void ScReferenceList::AddEntry( SCCOL nCol, SCROW nRow, SCTAB nTab )
      61                 :            : {
      62                 :          0 :     ScReferenceEntry* pOldData = pData;
      63                 :          0 :     pData = new ScReferenceEntry[ nFullSize+1 ];
      64         [ #  # ]:          0 :     if (pOldData)
      65                 :            :     {
      66                 :          0 :         memmove( pData, pOldData, nCount * sizeof(ScReferenceEntry) );
      67         [ #  # ]:          0 :         delete[] pOldData;
      68                 :            :     }
      69         [ #  # ]:          0 :     while (nCount < nFullSize)
      70                 :            :     {
      71                 :          0 :         pData[nCount].nCol = SC_CONS_NOTFOUND;
      72                 :          0 :         pData[nCount].nRow = SC_CONS_NOTFOUND;
      73                 :          0 :         pData[nCount].nTab = SC_CONS_NOTFOUND;
      74                 :          0 :         ++nCount;
      75                 :            :     }
      76                 :          0 :     pData[nCount].nCol = nCol;
      77                 :          0 :     pData[nCount].nRow = nRow;
      78                 :          0 :     pData[nCount].nTab = nTab;
      79                 :          0 :     ++nCount;
      80                 :          0 :     nFullSize = nCount;
      81                 :          0 : }
      82                 :            : 
      83                 :            : template< typename T >
      84                 :          0 : void lcl_AddString( String**& pData, T& nCount, const String& rInsert )
      85                 :            : {
      86                 :          0 :     String** pOldData = pData;
      87                 :          0 :     pData = new String*[ nCount+1 ];
      88         [ #  # ]:          0 :     if (pOldData)
      89                 :            :     {
      90                 :          0 :         memmove( pData, pOldData, nCount * sizeof(String*) );
      91         [ #  # ]:          0 :         delete[] pOldData;
      92                 :            :     }
      93         [ #  # ]:          0 :     pData[nCount] = new String(rInsert);
      94                 :          0 :     ++nCount;
      95                 :          0 : }
      96                 :            : 
      97                 :            : // -----------------------------------------------------------------------
      98                 :            : 
      99                 :          1 : ScConsData::ScConsData() :
     100                 :            :     eFunction(SUBTOTAL_FUNC_SUM),
     101                 :            :     bReference(false),
     102                 :            :     bColByName(false),
     103                 :            :     bRowByName(false),
     104                 :            :     bSubTitles(false),
     105                 :            :     nColCount(0),
     106                 :            :     nRowCount(0),
     107                 :            :     ppUsed(NULL),
     108                 :            :     ppSum(NULL),
     109                 :            :     ppCount(NULL),
     110                 :            :     ppSumSqr(NULL),
     111                 :            :     ppRefs(NULL),
     112                 :            :     ppColHeaders(NULL),
     113                 :            :     ppRowHeaders(NULL),
     114                 :            :     nDataCount(0),
     115                 :            :     nTitleCount(0),
     116                 :            :     ppTitles(NULL),
     117                 :            :     ppTitlePos(NULL),
     118                 :          1 :     bCornerUsed(false)
     119                 :            : {
     120                 :          1 : }
     121                 :            : 
     122                 :          1 : ScConsData::~ScConsData()
     123                 :            : {
     124         [ +  - ]:          1 :     DeleteData();
     125                 :          1 : }
     126                 :            : 
     127                 :            : 
     128                 :            : #define DELETEARR(ppArray,nCount)   \
     129                 :            : {                                   \
     130                 :            :     sal_uLong i;                        \
     131                 :            :     if (ppArray)                    \
     132                 :            :         for(i=0; i<nCount; i++)     \
     133                 :            :             delete[] ppArray[i];    \
     134                 :            :     delete[] ppArray;               \
     135                 :            :     ppArray = NULL;                 \
     136                 :            : }
     137                 :            : 
     138                 :            : #define DELETESTR(ppArray,nCount)   \
     139                 :            : {                                   \
     140                 :            :     sal_uLong i;                        \
     141                 :            :     if (ppArray)                    \
     142                 :            :         for(i=0; i<nCount; i++)     \
     143                 :            :             delete ppArray[i];      \
     144                 :            :     delete[] ppArray;               \
     145                 :            :     ppArray = NULL;                 \
     146                 :            : }
     147                 :            : 
     148                 :          3 : void ScConsData::DeleteData()
     149                 :            : {
     150         [ -  + ]:          3 :     if (ppRefs)
     151                 :            :     {
     152         [ #  # ]:          0 :         for (SCSIZE i=0; i<nColCount; i++)
     153                 :            :         {
     154         [ #  # ]:          0 :             for (SCSIZE j=0; j<nRowCount; j++)
     155         [ #  # ]:          0 :                 if (ppUsed[i][j])
     156                 :          0 :                     ppRefs[i][j].Clear();
     157         [ #  # ]:          0 :             delete[] ppRefs[i];
     158                 :            :         }
     159         [ #  # ]:          0 :         delete[] ppRefs;
     160                 :          0 :         ppRefs = NULL;
     161                 :            :     }
     162                 :            : 
     163 [ -  + ][ #  # ]:          3 :     DELETEARR( ppCount, nColCount );
         [ #  # ][ -  + ]
     164 [ -  + ][ #  # ]:          3 :     DELETEARR( ppSum,   nColCount );
         [ #  # ][ -  + ]
     165 [ -  + ][ #  # ]:          3 :     DELETEARR( ppSumSqr,nColCount );
         [ #  # ][ -  + ]
     166 [ -  + ][ #  # ]:          3 :     DELETEARR( ppUsed,  nColCount );                // erst nach ppRefs !!!
         [ #  # ][ -  + ]
     167 [ -  + ][ #  # ]:          3 :     DELETEARR( ppTitlePos, nRowCount );
         [ #  # ][ -  + ]
     168 [ -  + ][ #  # ]:          3 :     DELETESTR( ppColHeaders, nColCount );
         [ #  # ][ -  + ]
     169 [ -  + ][ #  # ]:          3 :     DELETESTR( ppRowHeaders, nRowCount );
         [ #  # ][ -  + ]
     170 [ -  + ][ #  # ]:          3 :     DELETESTR( ppTitles, nTitleCount );
         [ #  # ][ -  + ]
     171                 :          3 :     nTitleCount = 0;
     172                 :          3 :     nDataCount = 0;
     173                 :            : 
     174         [ -  + ]:          3 :     if (bColByName) nColCount = 0;                  // sonst stimmt ppColHeaders nicht
     175         [ -  + ]:          3 :     if (bRowByName) nRowCount = 0;
     176                 :            : 
     177                 :          3 :     bCornerUsed = false;
     178                 :          3 :     aCornerText.Erase();
     179                 :          3 : }
     180                 :            : 
     181                 :            : #undef DELETEARR
     182                 :            : #undef DELETESTR
     183                 :            : 
     184                 :          1 : void ScConsData::InitData( sal_Bool bDelete )
     185                 :            : {
     186         [ -  + ]:          1 :     if (bDelete)
     187                 :          0 :         DeleteData();
     188                 :            : 
     189 [ -  + ][ #  # ]:          1 :     if (bReference && nColCount && !ppRefs)
                 [ #  # ]
     190                 :            :     {
     191                 :          0 :         ppRefs = new ScReferenceList*[nColCount];
     192         [ #  # ]:          0 :         for (SCSIZE i=0; i<nColCount; i++)
     193                 :          0 :             ppRefs[i] = new ScReferenceList[nRowCount];
     194                 :            :     }
     195 [ -  + ][ #  # ]:          1 :     else if (nColCount && !ppCount)
     196                 :            :     {
     197                 :          0 :         ppCount  = new double*[nColCount];
     198                 :          0 :         ppSum    = new double*[nColCount];
     199                 :          0 :         ppSumSqr = new double*[nColCount];
     200         [ #  # ]:          0 :         for (SCSIZE i=0; i<nColCount; i++)
     201                 :            :         {
     202                 :          0 :             ppCount[i]  = new double[nRowCount];
     203                 :          0 :             ppSum[i]    = new double[nRowCount];
     204                 :          0 :             ppSumSqr[i] = new double[nRowCount];
     205                 :            :         }
     206                 :            :     }
     207                 :            : 
     208 [ -  + ][ #  # ]:          1 :     if (nColCount && !ppUsed)
     209                 :            :     {
     210                 :          0 :         ppUsed = new sal_Bool*[nColCount];
     211         [ #  # ]:          0 :         for (SCSIZE i=0; i<nColCount; i++)
     212                 :            :         {
     213                 :          0 :             ppUsed[i] = new sal_Bool[nRowCount];
     214                 :          0 :             memset( ppUsed[i], 0, nRowCount * sizeof(sal_Bool) );
     215                 :            :         }
     216                 :            :     }
     217                 :            : 
     218 [ -  + ][ #  # ]:          1 :     if (nRowCount && nDataCount && !ppTitlePos)
                 [ #  # ]
     219                 :            :     {
     220                 :          0 :         ppTitlePos = new SCSIZE*[nRowCount];
     221         [ #  # ]:          0 :         for (SCSIZE i=0; i<nRowCount; i++)
     222                 :            :         {
     223                 :          0 :             ppTitlePos[i] = new SCSIZE[nDataCount];
     224                 :          0 :             memset( ppTitlePos[i], 0, nDataCount * sizeof(SCSIZE) );    //! unnoetig ?
     225                 :            :         }
     226                 :            :     }
     227                 :            : 
     228                 :            :     //  CornerText: einzelner String
     229                 :          1 : }
     230                 :            : 
     231                 :          1 : void ScConsData::DoneFields()
     232                 :            : {
     233                 :          1 :     InitData(false);
     234                 :          1 : }
     235                 :            : 
     236                 :          1 : void ScConsData::SetSize( SCCOL nCols, SCROW nRows )
     237                 :            : {
     238                 :          1 :     DeleteData();
     239                 :          1 :     nColCount = static_cast<SCSIZE>(nCols);
     240                 :          1 :     nRowCount = static_cast<SCSIZE>(nRows);
     241                 :          1 : }
     242                 :            : 
     243                 :          1 : void ScConsData::GetSize( SCCOL& rCols, SCROW& rRows ) const
     244                 :            : {
     245                 :          1 :     rCols = static_cast<SCCOL>(nColCount);
     246                 :          1 :     rRows = static_cast<SCROW>(nRowCount);
     247                 :          1 : }
     248                 :            : 
     249                 :          1 : void ScConsData::SetFlags( ScSubTotalFunc eFunc, sal_Bool bColName, sal_Bool bRowName, sal_Bool bRef )
     250                 :            : {
     251                 :          1 :     DeleteData();
     252                 :          1 :     bReference = bRef;
     253                 :          1 :     bColByName = bColName;
     254         [ -  + ]:          1 :     if (bColName) nColCount = 0;
     255                 :          1 :     bRowByName = bRowName;
     256         [ -  + ]:          1 :     if (bRowName) nRowCount = 0;
     257                 :          1 :     eFunction = eFunc;
     258                 :          1 : }
     259                 :            : 
     260                 :          0 : void ScConsData::AddFields( ScDocument* pSrcDoc, SCTAB nTab,
     261                 :            :                             SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 )
     262                 :            : {
     263                 :          0 :     ++nDataCount;
     264                 :            : 
     265         [ #  # ]:          0 :     String aTitle;
     266                 :            : 
     267                 :          0 :     SCCOL nStartCol = nCol1;
     268                 :          0 :     SCROW nStartRow = nRow1;
     269         [ #  # ]:          0 :     if (bColByName) ++nStartRow;
     270         [ #  # ]:          0 :     if (bRowByName) ++nStartCol;
     271                 :            : 
     272         [ #  # ]:          0 :     if (bColByName)
     273                 :            :     {
     274         [ #  # ]:          0 :         for (SCCOL nCol=nStartCol; nCol<=nCol2; nCol++)
     275                 :            :         {
     276         [ #  # ]:          0 :             pSrcDoc->GetString( nCol, nRow1, nTab, aTitle );
     277         [ #  # ]:          0 :             if (aTitle.Len())
     278                 :            :             {
     279                 :          0 :                 sal_Bool bFound = false;
     280 [ #  # ][ #  # ]:          0 :                 for (SCSIZE i=0; i<nColCount && !bFound; i++)
                 [ #  # ]
     281 [ #  # ][ #  # ]:          0 :                     if ( *ppColHeaders[i] == aTitle )
     282                 :          0 :                         bFound = sal_True;
     283         [ #  # ]:          0 :                 if (!bFound)
     284         [ #  # ]:          0 :                     lcl_AddString( ppColHeaders, nColCount, aTitle );
     285                 :            :             }
     286                 :            :         }
     287                 :            :     }
     288                 :            : 
     289         [ #  # ]:          0 :     if (bRowByName)
     290                 :            :     {
     291         [ #  # ]:          0 :         for (SCROW nRow=nStartRow; nRow<=nRow2; nRow++)
     292                 :            :         {
     293         [ #  # ]:          0 :             pSrcDoc->GetString( nCol1, nRow, nTab, aTitle );
     294         [ #  # ]:          0 :             if (aTitle.Len())
     295                 :            :             {
     296                 :          0 :                 sal_Bool bFound = false;
     297 [ #  # ][ #  # ]:          0 :                 for (SCSIZE i=0; i<nRowCount && !bFound; i++)
                 [ #  # ]
     298 [ #  # ][ #  # ]:          0 :                     if ( *ppRowHeaders[i] == aTitle )
     299                 :          0 :                         bFound = sal_True;
     300         [ #  # ]:          0 :                 if (!bFound)
     301         [ #  # ]:          0 :                     lcl_AddString( ppRowHeaders, nRowCount, aTitle );
     302                 :            :             }
     303                 :            :         }
     304         [ #  # ]:          0 :     }
     305                 :          0 : }
     306                 :            : 
     307                 :          0 : void ScConsData::AddName( const String& rName )
     308                 :            : {
     309                 :            :     SCSIZE nArrX;
     310                 :            :     SCSIZE nArrY;
     311                 :            : 
     312         [ #  # ]:          0 :     if (bReference)
     313                 :            :     {
     314                 :          0 :         lcl_AddString( ppTitles, nTitleCount, rName );
     315                 :            : 
     316         [ #  # ]:          0 :         for (nArrY=0; nArrY<nRowCount; nArrY++)
     317                 :            :         {
     318                 :            :             //  Daten auf gleiche Laenge bringen
     319                 :            : 
     320                 :          0 :             SCSIZE nMax = 0;
     321         [ #  # ]:          0 :             for (nArrX=0; nArrX<nColCount; nArrX++)
     322         [ #  # ]:          0 :                 if (ppUsed[nArrX][nArrY])
     323                 :          0 :                     nMax = Max( nMax, ppRefs[nArrX][nArrY].GetCount() );
     324                 :            : 
     325         [ #  # ]:          0 :             for (nArrX=0; nArrX<nColCount; nArrX++)
     326                 :            :             {
     327         [ #  # ]:          0 :                 if (!ppUsed[nArrX][nArrY])
     328                 :            :                 {
     329                 :          0 :                     ppUsed[nArrX][nArrY] = sal_True;
     330                 :          0 :                     ppRefs[nArrX][nArrY].Init();
     331                 :            :                 }
     332                 :          0 :                 ppRefs[nArrX][nArrY].SetFullSize(nMax);
     333                 :            :             }
     334                 :            : 
     335                 :            :             //  Positionen eintragen
     336                 :            : 
     337         [ #  # ]:          0 :             if (ppTitlePos)
     338         [ #  # ]:          0 :                 if (nTitleCount < nDataCount)
     339                 :          0 :                     ppTitlePos[nArrY][nTitleCount] = nMax;
     340                 :            :         }
     341                 :            :     }
     342                 :          0 : }
     343                 :            : 
     344                 :            :                                 // rCount < 0 <=> Fehler aufgetreten
     345                 :            : 
     346                 :          0 : void lcl_UpdateArray( ScSubTotalFunc eFunc,
     347                 :            :                          double& rCount, double& rSum, double& rSumSqr, double nVal )
     348                 :            : {
     349         [ #  # ]:          0 :     if (rCount < 0.0)
     350                 :          0 :         return;
     351   [ #  #  #  #  :          0 :     switch (eFunc)
             #  #  #  # ]
     352                 :            :     {
     353                 :            :         case SUBTOTAL_FUNC_SUM:
     354         [ #  # ]:          0 :             if (!SubTotal::SafePlus(rSum, nVal))
     355                 :          0 :                 rCount = -MAXDOUBLE;
     356                 :          0 :             break;
     357                 :            :         case SUBTOTAL_FUNC_PROD:
     358         [ #  # ]:          0 :             if (!SubTotal::SafeMult(rSum, nVal))
     359                 :          0 :                 rCount = -MAXDOUBLE;
     360                 :          0 :             break;
     361                 :            :         case SUBTOTAL_FUNC_CNT:
     362                 :            :         case SUBTOTAL_FUNC_CNT2:
     363                 :          0 :             rCount += 1.0;
     364                 :          0 :             break;
     365                 :            :         case SUBTOTAL_FUNC_AVE:
     366         [ #  # ]:          0 :             if (!SubTotal::SafePlus(rSum, nVal))
     367                 :          0 :                 rCount = -MAXDOUBLE;
     368                 :            :             else
     369                 :          0 :                 rCount += 1.0;
     370                 :          0 :             break;
     371                 :            :         case SUBTOTAL_FUNC_MAX:
     372         [ #  # ]:          0 :             if (nVal > rSum)
     373                 :          0 :                 rSum = nVal;
     374                 :          0 :             break;
     375                 :            :         case SUBTOTAL_FUNC_MIN:
     376         [ #  # ]:          0 :             if (nVal < rSum)
     377                 :          0 :                 rSum = nVal;
     378                 :          0 :             break;
     379                 :            :         case SUBTOTAL_FUNC_STD:
     380                 :            :         case SUBTOTAL_FUNC_STDP:
     381                 :            :         case SUBTOTAL_FUNC_VAR:
     382                 :            :         case SUBTOTAL_FUNC_VARP:
     383                 :            :         {
     384                 :          0 :             sal_Bool bOk = SubTotal::SafePlus(rSum, nVal);
     385 [ #  # ][ #  # ]:          0 :             bOk = bOk && SubTotal::SafeMult(nVal, nVal);
     386 [ #  # ][ #  # ]:          0 :             bOk = bOk && SubTotal::SafePlus(rSumSqr, nVal);
     387         [ #  # ]:          0 :             if (!bOk)
     388                 :          0 :                 rCount = -MAXDOUBLE;
     389                 :            :             else
     390                 :          0 :                 rCount += 1.0;
     391                 :          0 :             break;
     392                 :            :         }
     393                 :            :         default:
     394                 :            :         {
     395                 :            :             // added to avoid warnings
     396                 :            :         }
     397                 :            :     }
     398                 :            : }
     399                 :            : 
     400                 :          0 : void lcl_InitArray( ScSubTotalFunc eFunc,
     401                 :            :                        double& rCount, double& rSum, double& rSumSqr, double nVal )
     402                 :            : {
     403                 :          0 :     rCount = 1.0;
     404      [ #  #  # ]:          0 :     switch (eFunc)
     405                 :            :     {
     406                 :            :         case SUBTOTAL_FUNC_SUM:
     407                 :            :         case SUBTOTAL_FUNC_MAX:
     408                 :            :         case SUBTOTAL_FUNC_MIN:
     409                 :            :         case SUBTOTAL_FUNC_PROD:
     410                 :            :         case SUBTOTAL_FUNC_AVE:
     411                 :          0 :             rSum = nVal;
     412                 :          0 :             break;
     413                 :            :         case SUBTOTAL_FUNC_STD:
     414                 :            :         case SUBTOTAL_FUNC_STDP:
     415                 :            :         case SUBTOTAL_FUNC_VAR:
     416                 :            :         case SUBTOTAL_FUNC_VARP:
     417                 :            :         {
     418                 :          0 :             rSum = nVal;
     419                 :          0 :             sal_Bool bOk = SubTotal::SafeMult(nVal, nVal);
     420         [ #  # ]:          0 :             if (bOk)
     421                 :          0 :                 rSumSqr = nVal;
     422                 :            :             else
     423                 :          0 :                 rCount = -MAXDOUBLE;
     424                 :            :         }
     425                 :          0 :             break;
     426                 :            :         default:
     427                 :          0 :             break;
     428                 :            :     }
     429                 :          0 : }
     430                 :            : 
     431                 :          0 : double lcl_CalcData( ScSubTotalFunc eFunc,
     432                 :            :                         double fCount, double fSum, double fSumSqr)
     433                 :            : {
     434         [ #  # ]:          0 :     if (fCount < 0.0)
     435                 :          0 :         return 0.0;
     436                 :          0 :     double fVal = 0.0;
     437   [ #  #  #  #  :          0 :     switch (eFunc)
             #  #  #  # ]
     438                 :            :     {
     439                 :            :         case SUBTOTAL_FUNC_CNT:
     440                 :            :         case SUBTOTAL_FUNC_CNT2:
     441                 :          0 :             fVal = fCount;
     442                 :          0 :             break;
     443                 :            :         case SUBTOTAL_FUNC_SUM:
     444                 :            :         case SUBTOTAL_FUNC_MAX:
     445                 :            :         case SUBTOTAL_FUNC_MIN:
     446                 :            :         case SUBTOTAL_FUNC_PROD:
     447                 :          0 :             fVal = fSum;
     448                 :          0 :             break;
     449                 :            :         case SUBTOTAL_FUNC_AVE:
     450         [ #  # ]:          0 :             if (fCount > 0.0)
     451                 :          0 :                 fVal = fSum / fCount;
     452                 :            :             else
     453                 :          0 :                 fCount = -MAXDOUBLE;
     454                 :          0 :             break;
     455                 :            :         case SUBTOTAL_FUNC_STD:
     456                 :            :         {
     457 [ #  # ][ #  # ]:          0 :             if (fCount > 1 && SubTotal::SafeMult(fSum, fSum))
                 [ #  # ]
     458                 :          0 :                 fVal = sqrt((fSumSqr - fSum/fCount)/(fCount-1.0));
     459                 :            :             else
     460                 :          0 :                 fCount = -MAXDOUBLE;
     461                 :            :         }
     462                 :          0 :             break;
     463                 :            :         case SUBTOTAL_FUNC_STDP:
     464                 :            :         {
     465 [ #  # ][ #  # ]:          0 :             if (fCount > 0 && SubTotal::SafeMult(fSum, fSum))
                 [ #  # ]
     466                 :          0 :                 fVal = sqrt((fSumSqr - fSum/fCount)/fCount);
     467                 :            :             else
     468                 :          0 :                 fCount = -MAXDOUBLE;
     469                 :            :         }
     470                 :          0 :             break;
     471                 :            :         case SUBTOTAL_FUNC_VAR:
     472                 :            :         {
     473 [ #  # ][ #  # ]:          0 :             if (fCount > 1 && SubTotal::SafeMult(fSum, fSum))
                 [ #  # ]
     474                 :          0 :                 fVal = (fSumSqr - fSum/fCount)/(fCount-1.0);
     475                 :            :             else
     476                 :          0 :                 fCount = -MAXDOUBLE;
     477                 :            :         }
     478                 :          0 :             break;
     479                 :            :         case SUBTOTAL_FUNC_VARP:
     480                 :            :         {
     481 [ #  # ][ #  # ]:          0 :             if (fCount > 0 && SubTotal::SafeMult(fSum, fSum))
                 [ #  # ]
     482                 :          0 :                 fVal = (fSumSqr - fSum/fCount)/fCount;
     483                 :            :             else
     484                 :          0 :                 fCount = -MAXDOUBLE;
     485                 :            :         }
     486                 :          0 :             break;
     487                 :            :         default:
     488                 :            :         {
     489                 :            :             OSL_FAIL("unbekannte Funktion bei Consoli::CalcData");
     490                 :          0 :             fCount = -MAXDOUBLE;
     491                 :            :         }
     492                 :          0 :             break;
     493                 :            :     }
     494                 :          0 :     return fVal;
     495                 :            : }
     496                 :            : 
     497                 :          0 : void ScConsData::AddData( ScDocument* pSrcDoc, SCTAB nTab,
     498                 :            :                             SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 )
     499                 :            : {
     500                 :          0 :     PutInOrder(nCol1,nCol2);
     501                 :          0 :     PutInOrder(nRow1,nRow2);
     502 [ #  # ][ #  # ]:          0 :     if ( nCol2 >= sal::static_int_cast<SCCOL>(nCol1 + nColCount) && !bColByName )
                 [ #  # ]
     503                 :            :     {
     504                 :            :         OSL_FAIL("Bereich zu gross");
     505                 :          0 :         nCol2 = sal::static_int_cast<SCCOL>( nCol1 + nColCount - 1 );
     506                 :            :     }
     507 [ #  # ][ #  # ]:          0 :     if ( nRow2 >= sal::static_int_cast<SCROW>(nRow1 + nRowCount) && !bRowByName )
                 [ #  # ]
     508                 :            :     {
     509                 :            :         OSL_FAIL("Bereich zu gross");
     510                 :          0 :         nRow2 = sal::static_int_cast<SCROW>( nRow1 + nRowCount - 1 );
     511                 :            :     }
     512                 :            : 
     513                 :            :     SCCOL nCol;
     514                 :            :     SCROW nRow;
     515                 :            : 
     516                 :            :     //      Ecke links oben
     517                 :            : 
     518 [ #  # ][ #  # ]:          0 :     if ( bColByName && bRowByName )
     519                 :            :     {
     520         [ #  # ]:          0 :         String aThisCorner;
     521         [ #  # ]:          0 :         pSrcDoc->GetString(nCol1,nRow1,nTab,aThisCorner);
     522         [ #  # ]:          0 :         if (bCornerUsed)
     523                 :            :         {
     524 [ #  # ][ #  # ]:          0 :             if (aCornerText != aThisCorner)
     525         [ #  # ]:          0 :                 aCornerText.Erase();
     526                 :            :         }
     527                 :            :         else
     528                 :            :         {
     529         [ #  # ]:          0 :             aCornerText = aThisCorner;
     530                 :          0 :             bCornerUsed = sal_True;
     531         [ #  # ]:          0 :         }
     532                 :            :     }
     533                 :            : 
     534                 :            :     //      Titel suchen
     535                 :            : 
     536                 :          0 :     SCCOL nStartCol = nCol1;
     537                 :          0 :     SCROW nStartRow = nRow1;
     538         [ #  # ]:          0 :     if (bColByName) ++nStartRow;
     539         [ #  # ]:          0 :     if (bRowByName) ++nStartCol;
     540         [ #  # ]:          0 :     String aTitle;
     541                 :          0 :     SCCOL*  pDestCols = NULL;
     542                 :          0 :     SCROW*  pDestRows = NULL;
     543         [ #  # ]:          0 :     if (bColByName)
     544                 :            :     {
     545         [ #  # ]:          0 :         pDestCols = new SCCOL[nCol2-nStartCol+1];
     546         [ #  # ]:          0 :         for (nCol=nStartCol; nCol<=nCol2; nCol++)
     547                 :            :         {
     548         [ #  # ]:          0 :             pSrcDoc->GetString(nCol,nRow1,nTab,aTitle);
     549                 :          0 :             SCCOL nPos = SC_CONS_NOTFOUND;
     550         [ #  # ]:          0 :             if (aTitle.Len())
     551                 :            :             {
     552                 :          0 :                 sal_Bool bFound = false;
     553 [ #  # ][ #  # ]:          0 :                 for (SCSIZE i=0; i<nColCount && !bFound; i++)
                 [ #  # ]
     554 [ #  # ][ #  # ]:          0 :                     if ( *ppColHeaders[i] == aTitle )
     555                 :            :                     {
     556                 :          0 :                         nPos = static_cast<SCCOL>(i);
     557                 :          0 :                         bFound = sal_True;
     558                 :            :                     }
     559                 :            :                 OSL_ENSURE(bFound, "Spalte nicht gefunden");
     560                 :            :             }
     561                 :          0 :             pDestCols[nCol-nStartCol] = nPos;
     562                 :            :         }
     563                 :            :     }
     564         [ #  # ]:          0 :     if (bRowByName)
     565                 :            :     {
     566         [ #  # ]:          0 :         pDestRows = new SCROW[nRow2-nStartRow+1];
     567         [ #  # ]:          0 :         for (nRow=nStartRow; nRow<=nRow2; nRow++)
     568                 :            :         {
     569         [ #  # ]:          0 :             pSrcDoc->GetString(nCol1,nRow,nTab,aTitle);
     570                 :          0 :             SCROW nPos = SC_CONS_NOTFOUND;
     571         [ #  # ]:          0 :             if (aTitle.Len())
     572                 :            :             {
     573                 :          0 :                 sal_Bool bFound = false;
     574 [ #  # ][ #  # ]:          0 :                 for (SCSIZE i=0; i<nRowCount && !bFound; i++)
                 [ #  # ]
     575 [ #  # ][ #  # ]:          0 :                     if ( *ppRowHeaders[i] == aTitle )
     576                 :            :                     {
     577                 :          0 :                         nPos = static_cast<SCROW>(i);
     578                 :          0 :                         bFound = sal_True;
     579                 :            :                     }
     580                 :            :                 OSL_ENSURE(bFound, "Zeile nicht gefunden");
     581                 :            :             }
     582                 :          0 :             pDestRows[nRow-nStartRow] = nPos;
     583                 :            :         }
     584                 :            :     }
     585                 :          0 :     nCol1 = nStartCol;
     586                 :          0 :     nRow1 = nStartRow;
     587                 :            : 
     588                 :            :     //      Daten
     589                 :            : 
     590                 :          0 :     sal_Bool bAnyCell = ( eFunction == SUBTOTAL_FUNC_CNT2 );
     591         [ #  # ]:          0 :     for (nCol=nCol1; nCol<=nCol2; nCol++)
     592                 :            :     {
     593                 :          0 :         SCCOL nArrX = nCol-nCol1;
     594         [ #  # ]:          0 :         if (bColByName) nArrX = pDestCols[nArrX];
     595         [ #  # ]:          0 :         if (nArrX != SC_CONS_NOTFOUND)
     596                 :            :         {
     597         [ #  # ]:          0 :             for (nRow=nRow1; nRow<=nRow2; nRow++)
     598                 :            :             {
     599                 :          0 :                 SCROW nArrY = nRow-nRow1;
     600         [ #  # ]:          0 :                 if (bRowByName) nArrY = pDestRows[nArrY];
     601 [ #  # ][ #  # ]:          0 :                 if ( nArrY != SC_CONS_NOTFOUND && (
         [ #  # ][ #  # ]
                 [ #  # ]
     602         [ #  # ]:          0 :                         bAnyCell ? pSrcDoc->HasData( nCol, nRow, nTab )
     603         [ #  # ]:          0 :                                  : pSrcDoc->HasValueData( nCol, nRow, nTab ) ) )
     604                 :            :                 {
     605         [ #  # ]:          0 :                     if (bReference)
     606                 :            :                     {
     607         [ #  # ]:          0 :                         if (ppUsed[nArrX][nArrY])
     608         [ #  # ]:          0 :                             ppRefs[nArrX][nArrY].AddEntry( nCol, nRow, nTab );
     609                 :            :                         else
     610                 :            :                         {
     611                 :          0 :                             ppUsed[nArrX][nArrY] = sal_True;
     612                 :          0 :                             ppRefs[nArrX][nArrY].Init();
     613         [ #  # ]:          0 :                             ppRefs[nArrX][nArrY].AddEntry( nCol, nRow, nTab );
     614                 :            :                         }
     615                 :            :                     }
     616                 :            :                     else
     617                 :            :                     {
     618                 :            :                         double nVal;
     619         [ #  # ]:          0 :                         pSrcDoc->GetValue( nCol, nRow, nTab, nVal );
     620         [ #  # ]:          0 :                         if (ppUsed[nArrX][nArrY])
     621                 :          0 :                             lcl_UpdateArray( eFunction, ppCount[nArrX][nArrY],
     622                 :          0 :                                          ppSum[nArrX][nArrY], ppSumSqr[nArrX][nArrY],
     623         [ #  # ]:          0 :                                          nVal);
     624                 :            :                         else
     625                 :            :                         {
     626                 :          0 :                             ppUsed[nArrX][nArrY] = sal_True;
     627                 :          0 :                             lcl_InitArray( eFunction, ppCount[nArrX][nArrY],
     628                 :          0 :                                                   ppSum[nArrX][nArrY],
     629         [ #  # ]:          0 :                                                   ppSumSqr[nArrX][nArrY], nVal );
     630                 :            :                         }
     631                 :            :                     }
     632                 :            :                 }
     633                 :            :             }
     634                 :            :         }
     635                 :            :     }
     636                 :            : 
     637         [ #  # ]:          0 :     delete[] pDestCols;
     638 [ #  # ][ #  # ]:          0 :     delete[] pDestRows;
     639                 :          0 : }
     640                 :            : 
     641                 :            : //  vorher testen, wieviele Zeilen eingefuegt werden (fuer Undo)
     642                 :            : 
     643                 :          0 : SCROW ScConsData::GetInsertCount() const
     644                 :            : {
     645                 :          0 :     SCROW nInsert = 0;
     646                 :            :     SCSIZE nArrX;
     647                 :            :     SCSIZE nArrY;
     648 [ #  # ][ #  # ]:          0 :     if ( ppRefs && ppUsed )
     649                 :            :     {
     650         [ #  # ]:          0 :         for (nArrY=0; nArrY<nRowCount; nArrY++)
     651                 :            :         {
     652                 :          0 :             SCSIZE nNeeded = 0;
     653         [ #  # ]:          0 :             for (nArrX=0; nArrX<nColCount; nArrX++)
     654         [ #  # ]:          0 :                 if (ppUsed[nArrX][nArrY])
     655                 :          0 :                     nNeeded = Max( nNeeded, ppRefs[nArrX][nArrY].GetCount() );
     656                 :            : 
     657                 :          0 :             nInsert += nNeeded;
     658                 :            :         }
     659                 :            :     }
     660                 :          0 :     return nInsert;
     661                 :            : }
     662                 :            : 
     663                 :            : //  fertige Daten ins Dokument schreiben
     664                 :            : //! optimieren nach Spalten?
     665                 :            : 
     666                 :          1 : void ScConsData::OutputToDocument( ScDocument* pDestDoc, SCCOL nCol, SCROW nRow, SCTAB nTab )
     667                 :            : {
     668                 :          1 :     OpCode eOpCode = eOpCodeTable[eFunction];
     669                 :            : 
     670                 :            :     SCSIZE nArrX;
     671                 :            :     SCSIZE nArrY;
     672                 :            : 
     673                 :            :     //  Ecke links oben
     674                 :            : 
     675 [ -  + ][ #  # ]:          1 :     if ( bColByName && bRowByName && aCornerText.Len() )
         [ #  # ][ -  + ]
     676         [ #  # ]:          0 :         pDestDoc->SetString( nCol, nRow, nTab, aCornerText );
     677                 :            : 
     678                 :            :     //  Titel
     679                 :            : 
     680                 :          1 :     SCCOL nStartCol = nCol;
     681                 :          1 :     SCROW nStartRow = nRow;
     682         [ -  + ]:          1 :     if (bColByName) ++nStartRow;
     683         [ -  + ]:          1 :     if (bRowByName) ++nStartCol;
     684                 :            : 
     685         [ -  + ]:          1 :     if (bColByName)
     686         [ #  # ]:          0 :         for (SCSIZE i=0; i<nColCount; i++)
     687         [ #  # ]:          0 :             pDestDoc->SetString( sal::static_int_cast<SCCOL>(nStartCol+i), nRow, nTab, *ppColHeaders[i] );
     688         [ -  + ]:          1 :     if (bRowByName)
     689         [ #  # ]:          0 :         for (SCSIZE j=0; j<nRowCount; j++)
     690         [ #  # ]:          0 :             pDestDoc->SetString( nCol, sal::static_int_cast<SCROW>(nStartRow+j), nTab, *ppRowHeaders[j] );
     691                 :            : 
     692                 :          1 :     nCol = nStartCol;
     693                 :          1 :     nRow = nStartRow;
     694                 :            : 
     695                 :            :     //  Daten
     696                 :            : 
     697 [ -  + ][ #  # ]:          1 :     if ( ppCount && ppUsed )                            // Werte direkt einfuegen
     698                 :            :     {
     699         [ #  # ]:          0 :         for (nArrX=0; nArrX<nColCount; nArrX++)
     700         [ #  # ]:          0 :             for (nArrY=0; nArrY<nRowCount; nArrY++)
     701         [ #  # ]:          0 :                 if (ppUsed[nArrX][nArrY])
     702                 :            :                 {
     703                 :          0 :                     double fVal = lcl_CalcData( eFunction, ppCount[nArrX][nArrY],
     704                 :          0 :                                                 ppSum[nArrX][nArrY],
     705         [ #  # ]:          0 :                                                 ppSumSqr[nArrX][nArrY]);
     706         [ #  # ]:          0 :                     if (ppCount[nArrX][nArrY] < 0.0)
     707                 :          0 :                         pDestDoc->SetError( sal::static_int_cast<SCCOL>(nCol+nArrX),
     708         [ #  # ]:          0 :                                             sal::static_int_cast<SCROW>(nRow+nArrY), nTab, errNoValue );
     709                 :            :                     else
     710                 :          0 :                         pDestDoc->SetValue( sal::static_int_cast<SCCOL>(nCol+nArrX),
     711         [ #  # ]:          0 :                                             sal::static_int_cast<SCROW>(nRow+nArrY), nTab, fVal );
     712                 :            :                 }
     713                 :            :     }
     714                 :            : 
     715 [ -  + ][ #  # ]:          1 :     if ( ppRefs && ppUsed )                             // Referenzen einfuegen
     716                 :            :     {
     717                 :            :                                 //! unterscheiden, ob nach Kategorien aufgeteilt
     718         [ #  # ]:          0 :         String aString;
     719                 :            : 
     720                 :            :         ScSingleRefData aSRef;      // Daten fuer Referenz-Formelzellen
     721                 :          0 :         aSRef.InitFlags();
     722                 :          0 :         aSRef.SetFlag3D(sal_True);
     723                 :            : 
     724                 :            :         ScComplexRefData aCRef;         // Daten fuer Summen-Zellen
     725                 :          0 :         aCRef.InitFlags();
     726                 :          0 :         aCRef.Ref1.SetColRel(sal_True); aCRef.Ref1.SetRowRel(sal_True); aCRef.Ref1.SetTabRel(sal_True);
     727                 :          0 :         aCRef.Ref2.SetColRel(sal_True); aCRef.Ref2.SetRowRel(sal_True); aCRef.Ref2.SetTabRel(sal_True);
     728                 :            : 
     729         [ #  # ]:          0 :         for (nArrY=0; nArrY<nRowCount; nArrY++)
     730                 :            :         {
     731                 :          0 :             SCSIZE nNeeded = 0;
     732         [ #  # ]:          0 :             for (nArrX=0; nArrX<nColCount; nArrX++)
     733         [ #  # ]:          0 :                 if (ppUsed[nArrX][nArrY])
     734                 :          0 :                     nNeeded = Max( nNeeded, ppRefs[nArrX][nArrY].GetCount() );
     735                 :            : 
     736         [ #  # ]:          0 :             if (nNeeded)
     737                 :            :             {
     738         [ #  # ]:          0 :                 pDestDoc->InsertRow( 0,nTab, MAXCOL,nTab, nRow+nArrY, nNeeded );
     739                 :            : 
     740         [ #  # ]:          0 :                 for (nArrX=0; nArrX<nColCount; nArrX++)
     741         [ #  # ]:          0 :                     if (ppUsed[nArrX][nArrY])
     742                 :            :                     {
     743                 :          0 :                         ScReferenceList& rList = ppRefs[nArrX][nArrY];
     744                 :          0 :                         SCSIZE nCount = rList.GetCount();
     745         [ #  # ]:          0 :                         if (nCount)
     746                 :            :                         {
     747         [ #  # ]:          0 :                             for (SCSIZE nPos=0; nPos<nCount; nPos++)
     748                 :            :                             {
     749                 :          0 :                                 ScReferenceEntry aRef = rList.GetEntry(nPos);
     750         [ #  # ]:          0 :                                 if (aRef.nTab != SC_CONS_NOTFOUND)
     751                 :            :                                 {
     752                 :            :                                     //  Referenz einfuegen (absolut, 3d)
     753                 :            : 
     754                 :          0 :                                     aSRef.nCol = aRef.nCol;
     755                 :          0 :                                     aSRef.nRow = aRef.nRow;
     756                 :          0 :                                     aSRef.nTab = aRef.nTab;
     757                 :            : 
     758         [ #  # ]:          0 :                                     ScTokenArray aRefArr;
     759         [ #  # ]:          0 :                                     aRefArr.AddSingleReference(aSRef);
     760         [ #  # ]:          0 :                                     aRefArr.AddOpCode(ocStop);
     761                 :          0 :                                     ScAddress aDest( sal::static_int_cast<SCCOL>(nCol+nArrX),
     762                 :          0 :                                                      sal::static_int_cast<SCROW>(nRow+nArrY+nPos), nTab );
     763 [ #  # ][ #  # ]:          0 :                                     ScBaseCell* pCell = new ScFormulaCell( pDestDoc, aDest, &aRefArr );
                 [ #  # ]
     764 [ #  # ][ #  # ]:          0 :                                     pDestDoc->PutCell( aDest.Col(), aDest.Row(), aDest.Tab(), pCell );
     765                 :            :                                 }
     766                 :            :                             }
     767                 :            : 
     768                 :            :                             //  Summe einfuegen (relativ, nicht 3d)
     769                 :            : 
     770                 :          0 :                             ScAddress aDest( sal::static_int_cast<SCCOL>(nCol+nArrX),
     771                 :          0 :                                              sal::static_int_cast<SCROW>(nRow+nArrY+nNeeded), nTab );
     772                 :            : 
     773                 :          0 :                             aCRef.Ref1.nTab = aCRef.Ref2.nTab = nTab;
     774                 :          0 :                             aCRef.Ref1.nCol = aCRef.Ref2.nCol = sal::static_int_cast<SCsCOL>( nCol+nArrX );
     775                 :          0 :                             aCRef.Ref1.nRow = nRow+nArrY;
     776                 :          0 :                             aCRef.Ref2.nRow = nRow+nArrY+nNeeded-1;
     777         [ #  # ]:          0 :                             aCRef.CalcRelFromAbs( aDest );
     778                 :            : 
     779         [ #  # ]:          0 :                             ScTokenArray aArr;
     780         [ #  # ]:          0 :                             aArr.AddOpCode(eOpCode);            // ausgewaehlte Funktion
     781         [ #  # ]:          0 :                             aArr.AddOpCode(ocOpen);
     782         [ #  # ]:          0 :                             aArr.AddDoubleReference(aCRef);
     783         [ #  # ]:          0 :                             aArr.AddOpCode(ocClose);
     784         [ #  # ]:          0 :                             aArr.AddOpCode(ocStop);
     785 [ #  # ][ #  # ]:          0 :                             ScBaseCell* pCell = new ScFormulaCell( pDestDoc, aDest, &aArr );
                 [ #  # ]
     786 [ #  # ][ #  # ]:          0 :                             pDestDoc->PutCell( aDest.Col(), aDest.Row(), aDest.Tab(), pCell );
     787                 :            :                         }
     788                 :            :                     }
     789                 :            : 
     790                 :            :                 //  Gliederung einfuegen
     791                 :            : 
     792         [ #  # ]:          0 :                 ScOutlineArray* pOutArr = pDestDoc->GetOutlineTable( nTab, sal_True )->GetRowArray();
     793                 :          0 :                 SCROW nOutStart = nRow+nArrY;
     794                 :          0 :                 SCROW nOutEnd = nRow+nArrY+nNeeded-1;
     795                 :          0 :                 bool bSize = false;
     796         [ #  # ]:          0 :                 pOutArr->Insert( nOutStart, nOutEnd, bSize );
     797         [ #  # ]:          0 :                 pDestDoc->InitializeNoteCaptions(nTab);
     798         [ #  # ]:          0 :                 for (SCROW nOutRow=nOutStart; nOutRow<=nOutEnd; nOutRow++)
     799         [ #  # ]:          0 :                     pDestDoc->ShowRow( nOutRow, nTab, false );
     800         [ #  # ]:          0 :                 pDestDoc->SetDrawPageSize(nTab);
     801         [ #  # ]:          0 :                 pDestDoc->UpdateOutlineRow( nOutStart, nOutEnd, nTab, false );
     802                 :            : 
     803                 :            :                 //  Zwischentitel
     804                 :            : 
     805 [ #  # ][ #  # ]:          0 :                 if (ppTitlePos && ppTitles && ppRowHeaders)
                 [ #  # ]
     806                 :            :                 {
     807         [ #  # ]:          0 :                     String aDelim( RTL_CONSTASCII_USTRINGPARAM(" / ") );
     808         [ #  # ]:          0 :                     for (SCSIZE nPos=0; nPos<nDataCount; nPos++)
     809                 :            :                     {
     810                 :          0 :                         SCSIZE nTPos = ppTitlePos[nArrY][nPos];
     811                 :          0 :                         sal_Bool bDo = sal_True;
     812         [ #  # ]:          0 :                         if (nPos+1<nDataCount)
     813         [ #  # ]:          0 :                             if (ppTitlePos[nArrY][nPos+1] == nTPos)
     814                 :          0 :                                 bDo = false;                                    // leer
     815 [ #  # ][ #  # ]:          0 :                         if ( bDo && nTPos < nNeeded )
     816                 :            :                         {
     817         [ #  # ]:          0 :                             aString =  *ppRowHeaders[nArrY];
     818         [ #  # ]:          0 :                             aString += aDelim;
     819         [ #  # ]:          0 :                             aString += *ppTitles[nPos];
     820 [ #  # ][ #  # ]:          0 :                             pDestDoc->SetString( nCol-1, nRow+nArrY+nTPos, nTab, aString );
     821                 :            :                         }
     822         [ #  # ]:          0 :                     }
     823                 :            :                 }
     824                 :            : 
     825                 :          0 :                 nRow += nNeeded;
     826                 :            :             }
     827         [ #  # ]:          0 :         }
     828                 :            :     }
     829                 :          1 : }
     830                 :            : 
     831                 :            : 
     832                 :            : 
     833                 :            : 
     834                 :            : 
     835                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10