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

Generated by: LCOV version 1.10