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

Generated by: LCOV version 1.10