LCOV - code coverage report
Current view: top level - sc/source/core/tool - consoli.cxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 0 408 0.0 %
Date: 2014-04-14 Functions: 0 18 0.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10