LCOV - code coverage report
Current view: top level - sc/source/core/tool - chartpos.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 221 295 74.9 %
Date: 2015-06-13 12:38:46 Functions: 11 16 68.8 %
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 "chartpos.hxx"
      21             : #include "document.hxx"
      22             : #include "rechead.hxx"
      23             : #include <osl/diagnose.h>
      24             : 
      25             : #include <boost/scoped_array.hpp>
      26             : 
      27             : namespace
      28             : {
      29         276 :     bool lcl_hasValueDataButNoDates( ScDocument* pDocument, SCCOL nCol, SCROW nRow, SCTAB nTab )
      30             :     {
      31         276 :         bool bReturn = false;
      32         276 :         if (pDocument->HasValueData( nCol, nRow, nTab ))
      33             :         {
      34             :             //treat dates like text #i25706#
      35          13 :             sal_uInt32 nNumberFormat = pDocument->GetNumberFormat( ScAddress( nCol, nRow, nTab ) );
      36          13 :             short nType = pDocument->GetFormatTable()->GetType(nNumberFormat);
      37          13 :             bool bIsDate = (nType & css::util::NumberFormat::DATE);
      38          13 :             bReturn = !bIsDate;
      39             :         }
      40         276 :         return bReturn;
      41             :     }
      42             : }
      43             : 
      44           0 : ScChartPositioner::ScChartPositioner( ScDocument* pDoc, SCTAB nTab,
      45             :                     SCCOL nStartColP, SCROW nStartRowP, SCCOL nEndColP, SCROW nEndRowP) :
      46             :         pDocument( pDoc ),
      47             :         pPositionMap( NULL ),
      48             :         eGlue( SC_CHARTGLUE_NA ),
      49             :         nStartCol(0),
      50             :         nStartRow(0),
      51             :         bColHeaders( false ),
      52             :         bRowHeaders( false ),
      53           0 :         bDummyUpperLeft( false )
      54             : {
      55           0 :     SetRangeList( ScRange( nStartColP, nStartRowP, nTab, nEndColP, nEndRowP, nTab ) );
      56           0 :     CheckColRowHeaders();
      57           0 : }
      58             : 
      59          26 : ScChartPositioner::ScChartPositioner( ScDocument* pDoc, const ScRangeListRef& rRangeList ) :
      60             :         aRangeListRef( rRangeList ),
      61             :         pDocument( pDoc ),
      62             :         pPositionMap( NULL ),
      63             :         eGlue( SC_CHARTGLUE_NA ),
      64             :         nStartCol(0),
      65             :         nStartRow(0),
      66             :         bColHeaders( false ),
      67             :         bRowHeaders( false ),
      68          26 :         bDummyUpperLeft( false )
      69             : {
      70          26 :     if ( aRangeListRef.Is() )
      71          26 :         CheckColRowHeaders();
      72          26 : }
      73             : 
      74           0 : ScChartPositioner::ScChartPositioner( const ScChartPositioner& rPositioner ) :
      75             :         aRangeListRef( rPositioner.aRangeListRef ),
      76             :         pDocument(rPositioner.pDocument),
      77             :         pPositionMap( NULL ),
      78             :         eGlue(rPositioner.eGlue),
      79             :         nStartCol(rPositioner.nStartCol),
      80             :         nStartRow(rPositioner.nStartRow),
      81             :         bColHeaders(rPositioner.bColHeaders),
      82             :         bRowHeaders(rPositioner.bRowHeaders),
      83           0 :         bDummyUpperLeft( rPositioner.bDummyUpperLeft )
      84             : {
      85           0 : }
      86             : 
      87          52 : ScChartPositioner::~ScChartPositioner()
      88             : {
      89          26 :     delete pPositionMap;
      90          26 : }
      91             : 
      92           0 : bool ScChartPositioner::operator==(const ScChartPositioner& rCmp) const
      93             : {
      94           0 :     return bColHeaders == rCmp.bColHeaders
      95           0 :         && bRowHeaders == rCmp.bRowHeaders
      96           0 :         && *aRangeListRef == *rCmp.aRangeListRef;
      97             : }
      98             : 
      99           0 : void ScChartPositioner::SetRangeList( const ScRange& rRange )
     100             : {
     101           0 :     aRangeListRef = new ScRangeList;
     102           0 :     aRangeListRef->Append( rRange );
     103           0 :     InvalidateGlue();
     104           0 : }
     105             : 
     106          44 : void ScChartPositioner::GlueState()
     107             : {
     108          44 :     if ( eGlue != SC_CHARTGLUE_NA )
     109          47 :         return;
     110          26 :     bDummyUpperLeft = false;
     111             :     ScRange* pR;
     112          26 :     if ( aRangeListRef->size() <= 1 )
     113             :     {
     114          11 :         if (  !aRangeListRef->empty() )
     115             :         {
     116          11 :             pR = aRangeListRef->front();
     117          11 :             if ( pR->aStart.Tab() == pR->aEnd.Tab() )
     118          11 :                 eGlue = SC_CHARTGLUE_NONE;
     119             :             else
     120           0 :                 eGlue = SC_CHARTGLUE_COLS;  // several tables column by column
     121          11 :             nStartCol = pR->aStart.Col();
     122          11 :             nStartRow = pR->aStart.Row();
     123             :         }
     124             :         else
     125             :         {
     126           0 :             InvalidateGlue();
     127           0 :             nStartCol = 0;
     128           0 :             nStartRow = 0;
     129             :         }
     130          11 :         return;
     131             :     }
     132             : 
     133          15 :     pR = aRangeListRef->front();
     134          15 :     nStartCol = pR->aStart.Col();
     135          15 :     nStartRow = pR->aStart.Row();
     136             :     SCCOL nMaxCols, nEndCol;
     137             :     SCROW nMaxRows, nEndRow;
     138          15 :     nMaxCols = nEndCol = 0;
     139          15 :     nMaxRows = nEndRow = 0;
     140             : 
     141             :     // <= so 1 extra pass after last item
     142          75 :     for ( size_t i = 1, nRanges = aRangeListRef->size(); i <= nRanges; ++i )
     143             :     {   // detect spanning/surrounding area etc.
     144             :         SCCOLROW nTmp, n1, n2;
     145          60 :         if ( (n1 = pR->aStart.Col()) < nStartCol ) nStartCol = static_cast<SCCOL>(n1  );
     146          60 :         if ( (n2 = pR->aEnd.Col()  ) > nEndCol   ) nEndCol   = static_cast<SCCOL>(n2  );
     147          60 :         if ( (nTmp = n2 - n1 + 1   ) > nMaxCols  ) nMaxCols  = static_cast<SCCOL>(nTmp);
     148          60 :         if ( (n1 = pR->aStart.Row()) < nStartRow ) nStartRow = static_cast<SCROW>(n1  );
     149          60 :         if ( (n2 = pR->aEnd.Row()  ) > nEndRow   ) nEndRow   = static_cast<SCROW>(n2  );
     150          60 :         if ( (nTmp = n2 - n1 + 1   ) > nMaxRows  ) nMaxRows  = static_cast<SCROW>(nTmp);
     151             : 
     152             :         // in last pass; i = nRanges so don't use at()
     153          60 :         if ( i < nRanges )
     154          45 :             pR = (*aRangeListRef)[i];
     155             :     }
     156          15 :     SCCOL nC = nEndCol - nStartCol + 1;
     157          15 :     if ( nC == 1 )
     158             :     {
     159           0 :         eGlue = SC_CHARTGLUE_ROWS;
     160           0 :         return;
     161             :     }
     162          15 :     SCROW nR = nEndRow - nStartRow + 1;
     163          15 :     if ( nR == 1 )
     164             :     {
     165           0 :         eGlue = SC_CHARTGLUE_COLS;
     166           0 :         return;
     167             :     }
     168          15 :     sal_uLong nCR = (sal_uLong)nC * nR;
     169             : 
     170             :     /*
     171             :     TODO:
     172             :     First do it simple without bit masking. A maximum of 8MB could be allocated
     173             :     this way (256 Cols x 32000 Rows). That could be reduced to 2MB by
     174             :     using 2 Bits per entry, but it is faster this way.
     175             :     Another optimization would be to store only used rows/columns in the array, but
     176             :     would mean another iteration of the RangeList indirect access to the array. */
     177             : 
     178          15 :     const sal_uInt8 nHole = 0;
     179          15 :     const sal_uInt8 nOccu = 1;
     180          15 :     const sal_uInt8 nFree = 2;
     181          15 :     const sal_uInt8 nGlue = 3;
     182             :     sal_uInt8* p;
     183          15 :     boost::scoped_array<sal_uInt8> pA(new sal_uInt8[ nCR ]);
     184          15 :     memset( pA.get(), 0, nCR * sizeof(sal_uInt8) );
     185             : 
     186             :     SCCOL nCol, nCol1, nCol2;
     187             :     SCROW nRow, nRow1, nRow2;
     188          75 :     for ( size_t i = 0, nRanges = aRangeListRef->size(); i < nRanges; ++i )
     189             :     {   // mark selections as used in 2D
     190          60 :         pR = (*aRangeListRef)[i];
     191          60 :         nCol1 = pR->aStart.Col() - nStartCol;
     192          60 :         nCol2 = pR->aEnd.Col() - nStartCol;
     193          60 :         nRow1 = pR->aStart.Row() - nStartRow;
     194          60 :         nRow2 = pR->aEnd.Row() - nStartRow;
     195         180 :         for ( nCol = nCol1; nCol <= nCol2; nCol++ )
     196             :         {
     197         120 :             p = pA.get() + (sal_uLong)nCol * nR + nRow1;
     198         480 :             for ( nRow = nRow1; nRow <= nRow2; nRow++, p++ )
     199         360 :                 *p = nOccu;
     200             :         }
     201             :     }
     202          15 :     bool bGlue = true;
     203             : 
     204          15 :     bool bGlueCols = false;
     205          60 :     for ( nCol = 0; bGlue && nCol < nC; nCol++ )
     206             :     {   // iterate columns and try to mark as unused
     207          45 :         p = pA.get() + (sal_uLong)nCol * nR;
     208         105 :         for ( nRow = 0; bGlue && nRow < nR; nRow++, p++ )
     209             :         {
     210          60 :             if ( *p == nOccu )
     211             :             {   // If there's one right in the middle, we can't combine.
     212             :                 // If it were at the edge, we could combine, if in this Column
     213             :                 // in every set line, one is set.
     214          45 :                 if ( nRow > 0 && nCol > 0 )
     215          15 :                     bGlue = false; // nCol==0 can be DummyUpperLeft
     216             :                 else
     217          30 :                     nRow = nR;
     218             :             }
     219             :             else
     220          15 :                 *p = nFree;
     221             :         }
     222          45 :         if ( bGlue && *(p = (pA.get() + ((((sal_uLong)nCol+1) * nR) - 1))) == nFree )
     223             :         {   // mark column as totally unused
     224           0 :             *p = nGlue;
     225           0 :             bGlueCols = true; // one unused column at least
     226             :         }
     227             :     }
     228             : 
     229          15 :     bool bGlueRows = false;
     230          15 :     for ( nRow = 0; bGlue && nRow < nR; nRow++ )
     231             :     {   // iterate rows and try to mark as unused
     232           0 :         p = pA.get() + nRow;
     233           0 :         for ( nCol = 0; bGlue && nCol < nC; nCol++, p+=nR )
     234             :         {
     235           0 :             if ( *p == nOccu )
     236             :             {
     237           0 :                 if ( nCol > 0 && nRow > 0 )
     238           0 :                     bGlue = false; // nRow==0 can be DummyUpperLeft
     239             :                 else
     240           0 :                     nCol = nC;
     241             :             }
     242             :             else
     243           0 :                 *p = nFree;
     244             :         }
     245           0 :         if ( bGlue && *(p = (pA.get() + ((((sal_uLong)nC-1) * nR) + nRow))) == nFree )
     246             :         {   // mark row as totally unused
     247           0 :             *p = nGlue;
     248           0 :             bGlueRows = true; // one unused row at least
     249             :         }
     250             :     }
     251             : 
     252             :     // If n=1: The upper left corner could be automagically pulled in for labeling
     253          15 :     p = pA.get() + 1;
     254          15 :     for ( sal_uLong n = 1; bGlue && n < nCR; n++, p++ )
     255             :     {   // An untouched field means we could neither reach it through rows nor columns,
     256             :         // thus we can't combine anything
     257           0 :         if ( *p == nHole )
     258           0 :             bGlue = false;
     259             :     }
     260          15 :     if ( bGlue )
     261             :     {
     262           0 :         if ( bGlueCols && bGlueRows )
     263           0 :             eGlue = SC_CHARTGLUE_BOTH;
     264           0 :         else if ( bGlueRows )
     265           0 :             eGlue = SC_CHARTGLUE_ROWS;
     266             :         else
     267           0 :             eGlue = SC_CHARTGLUE_COLS;
     268           0 :         if ( pA[0] != nOccu )
     269           0 :             bDummyUpperLeft = true;
     270             :     }
     271             :     else
     272             :     {
     273          15 :         eGlue = SC_CHARTGLUE_NONE;
     274          15 :     }
     275             : }
     276             : 
     277          26 : void ScChartPositioner::CheckColRowHeaders()
     278             : {
     279             :     SCCOL nCol1, nCol2, iCol;
     280             :     SCROW nRow1, nRow2, iRow;
     281             :     SCTAB nTab1, nTab2;
     282             : 
     283          26 :     bool bColStrings = true;
     284          26 :     bool bRowStrings = true;
     285          26 :     GlueState();
     286          26 :     if ( aRangeListRef->size() == 1 )
     287             :     {
     288          11 :         aRangeListRef->front()->GetVars( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 );
     289          11 :         if ( nCol1 > nCol2 || nRow1 > nRow2 )
     290           0 :             bColStrings = bRowStrings = false;
     291             :         else
     292             :         {
     293          55 :             for (iCol=nCol1; iCol<=nCol2 && bColStrings; iCol++)
     294             :             {
     295          44 :                 if (lcl_hasValueDataButNoDates( pDocument, iCol, nRow1, nTab1 ))
     296           0 :                         bColStrings = false;
     297             :             }
     298          66 :             for (iRow=nRow1; iRow<=nRow2 && bRowStrings; iRow++)
     299             :             {
     300          55 :                 if (lcl_hasValueDataButNoDates( pDocument, nCol1, iRow, nTab1 ))
     301           0 :                         bRowStrings = false;
     302             :             }
     303             :         }
     304             :     }
     305             :     else
     306             :     {
     307          15 :         bool bVert = (eGlue == SC_CHARTGLUE_NONE || eGlue == SC_CHARTGLUE_ROWS);
     308          69 :         for ( size_t i = 0, nRanges = aRangeListRef->size();
     309          56 :               (i < nRanges) && (bColStrings || bRowStrings);
     310             :               ++i
     311             :             )
     312             :         {
     313          54 :             ScRange* pR = (*aRangeListRef)[i];
     314          54 :             pR->GetVars( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 );
     315          54 :             bool bTopRow = (nRow1 == nStartRow);
     316          54 :             if ( bRowStrings && (bVert || nCol1 == nStartCol) )
     317             :             {   // NONE or ROWS: RowStrings in every selection possible
     318             :                 // COLS or BOTH: only from first column
     319          54 :                 if ( nCol1 <= nCol2 )
     320         203 :                     for (iRow=nRow1; iRow<=nRow2 && bRowStrings; iRow++)
     321             :                     {
     322         149 :                         if (lcl_hasValueDataButNoDates( pDocument, nCol1, iRow, nTab1 ))
     323          11 :                                 bRowStrings = false;
     324             :                     }
     325             :             }
     326          54 :             if ( bColStrings && bTopRow )
     327             :             {   // ColStrings only from first row
     328          15 :                 if ( nRow1 <= nRow2 )
     329          43 :                     for (iCol=nCol1; iCol<=nCol2 && bColStrings; iCol++)
     330             :                     {
     331          28 :                         if (lcl_hasValueDataButNoDates( pDocument, iCol, nRow1, nTab1 ))
     332           2 :                                 bColStrings = false;
     333             :                     }
     334             :             }
     335             :         }
     336             :     }
     337          26 :     bColHeaders = bColStrings;
     338          26 :     bRowHeaders = bRowStrings;
     339          26 : }
     340             : 
     341         288 : const ScChartPositionMap* ScChartPositioner::GetPositionMap()
     342             : {
     343         288 :     CreatePositionMap();
     344         288 :     return pPositionMap;
     345             : }
     346             : 
     347         288 : void ScChartPositioner::CreatePositionMap()
     348             : {
     349         288 :     if ( eGlue == SC_CHARTGLUE_NA && pPositionMap )
     350             :     {
     351           0 :         delete pPositionMap;
     352           0 :         pPositionMap = NULL;
     353             :     }
     354             : 
     355         288 :     if ( pPositionMap )
     356         558 :         return ;
     357             : 
     358          18 :     SCSIZE nColAdd = bRowHeaders ? 1 : 0;
     359          18 :     SCSIZE nRowAdd = bColHeaders ? 1 : 0;
     360             : 
     361             :     SCCOL nCol, nCol1, nCol2;
     362             :     SCROW nRow, nRow1, nRow2;
     363             :     SCTAB nTab, nTab1, nTab2;
     364             : 
     365             :     //  real size (without hidden rows/columns)
     366             : 
     367          18 :     SCSIZE nColCount = 0;
     368          18 :     SCSIZE nRowCount = 0;
     369             : 
     370          18 :     GlueState();
     371             : 
     372          18 :     const bool bNoGlue = (eGlue == SC_CHARTGLUE_NONE);
     373          18 :     ColumnMap* pCols = new ColumnMap;
     374          18 :     SCROW nNoGlueRow = 0;
     375          81 :     for ( size_t i = 0, nRanges = aRangeListRef->size(); i < nRanges; ++i )
     376             :     {
     377          63 :         ScRange* pR = (*aRangeListRef)[i];
     378          63 :         pR->GetVars( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 );
     379         126 :         for ( nTab = nTab1; nTab <= nTab2; nTab++ )
     380             :         {
     381             :             // nTab in ColKey to allow to have the same col/row in another tabe
     382          63 :             sal_uLong nInsCol = (static_cast<sal_uLong>(nTab) << 16) | (bNoGlue ? 0 :
     383          63 :                     static_cast<sal_uLong>(nCol1));
     384         195 :             for ( nCol = nCol1; nCol <= nCol2; ++nCol, ++nInsCol )
     385             :             {
     386         132 :                 RowMap* pCol = NULL;
     387         132 :                 ColumnMap::const_iterator it = pCols->find( nInsCol );
     388         132 :                 if ( it == pCols->end() )
     389             :                 {
     390          42 :                     pCol = new RowMap;
     391          42 :                     pCols->insert( ColumnMap::value_type( nInsCol, pCol ) );
     392             :                 }
     393             :                 else
     394          90 :                     pCol = it->second;
     395             : 
     396             :                 // in other table a new ColKey already was created,
     397             :                 // the rows must be equal to be filled with Dummy
     398         132 :                 sal_uLong nInsRow = (bNoGlue ? nNoGlueRow : nRow1);
     399         552 :                 for ( nRow = nRow1; nRow <= nRow2; nRow++, nInsRow++ )
     400             :                 {
     401         420 :                     if ( pCol->find( nInsRow ) == pCol->end() )
     402             :                     {
     403         420 :                         pCol->insert( RowMap::value_type( nInsRow, new ScAddress( nCol, nRow, nTab ) ) );
     404             :                     }
     405             :                 }
     406             :             }
     407             :         }
     408             :         // For NoGlue: associated tables will be rendered as ColGlue
     409          63 :         nNoGlueRow += nRow2 - nRow1 + 1;
     410             :     }
     411             : 
     412             :     // count of data
     413          18 :     nColCount = static_cast< SCSIZE >( pCols->size());
     414          18 :     if ( !pCols->empty() )
     415             :     {
     416          18 :         RowMap* pCol = pCols->begin()->second;
     417          18 :         if ( bDummyUpperLeft )
     418           0 :             (*pCol)[ 0 ] = NULL; // Dummy for labeling
     419          18 :         nRowCount = static_cast< SCSIZE >( pCol->size());
     420             :     }
     421             :     else
     422           0 :         nRowCount = 0;
     423          18 :     if ( nColCount > 0 )
     424          18 :         nColCount -= nColAdd;
     425          18 :     if ( nRowCount > 0 )
     426          18 :         nRowCount -= nRowAdd;
     427             : 
     428          18 :     if ( nColCount==0 || nRowCount==0 )
     429             :     {   // create an entry without data
     430             :         RowMap* pCol;
     431           0 :         if ( !pCols->empty() )
     432           0 :             pCol = pCols->begin()->second;
     433             :         else
     434             :         {
     435           0 :             pCol = new RowMap;
     436           0 :             (*pCols)[ 0 ] = pCol;
     437             :         }
     438           0 :         nColCount = 1;
     439           0 :         if ( !pCol->empty() )
     440             :         {   // cannot be if nColCount==0 || nRowCount==0
     441           0 :             ScAddress* pPos = pCol->begin()->second;
     442           0 :             if ( pPos )
     443             :             {
     444           0 :                 sal_uLong nCurrentKey = pCol->begin()->first;
     445           0 :                 delete pPos;
     446           0 :                 (*pCol)[ nCurrentKey ] = NULL;
     447             :             }
     448             :         }
     449             :         else
     450           0 :             (*pCol)[ 0 ] = NULL;
     451           0 :         nRowCount = 1;
     452           0 :         nColAdd = 0;
     453           0 :         nRowAdd = 0;
     454             :     }
     455             :     else
     456             :     {
     457          18 :         if ( bNoGlue )
     458             :         {   // fill gaps with Dummies, first column is master
     459          18 :             RowMap* pFirstCol = pCols->begin()->second;
     460          18 :             sal_uLong nCount = pFirstCol->size();
     461          18 :             RowMap::const_iterator it1 = pFirstCol->begin();
     462         213 :             for ( sal_uLong n = 0; n < nCount; n++, ++it1 )
     463             :             {
     464         195 :                 sal_uLong nKey = it1->first;
     465         420 :                 for (ColumnMap::const_iterator it2 = ++pCols->begin(); it2 != pCols->end(); ++it2 )
     466         225 :                     it2->second->insert( RowMap::value_type( nKey, nullptr )); // no data
     467             :             }
     468             :         }
     469             :     }
     470             : 
     471             :     pPositionMap = new ScChartPositionMap( static_cast<SCCOL>(nColCount), static_cast<SCROW>(nRowCount),
     472          18 :         static_cast<SCCOL>(nColAdd), static_cast<SCROW>(nRowAdd), *pCols );
     473             : 
     474             :     //  cleanup
     475          60 :     for (ColumnMap::const_iterator it = pCols->begin(); it != pCols->end(); ++it )
     476             :     {   // Only delete tables, not the ScAddress*!
     477          42 :         delete it->second;
     478             :     }
     479          18 :     delete pCols;
     480             : }
     481             : 
     482          18 : ScChartPositionMap::ScChartPositionMap( SCCOL nChartCols, SCROW nChartRows,
     483             :             SCCOL nColAdd, SCROW nRowAdd, ColumnMap& rCols ) :
     484          18 :         ppData( new ScAddress* [ nChartCols * nChartRows ] ),
     485          18 :         ppColHeader( new ScAddress* [ nChartCols ] ),
     486          18 :         ppRowHeader( new ScAddress* [ nChartRows ] ),
     487          18 :         nCount( (sal_uLong) nChartCols * nChartRows ),
     488             :         nColCount( nChartCols ),
     489          72 :         nRowCount( nChartRows )
     490             : {
     491             :     OSL_ENSURE( nColCount && nRowCount, "ScChartPositionMap without dimension" );
     492             : 
     493          18 :     ColumnMap::const_iterator pColIter = rCols.begin();
     494          18 :     RowMap* pCol1 = pColIter->second;
     495          18 :     RowMap::const_iterator pPos1Iter;
     496             : 
     497             :     // row header
     498          18 :     pPos1Iter = pCol1->begin();
     499          18 :     if ( nRowAdd )
     500          14 :         ++pPos1Iter;
     501          18 :     if ( nColAdd )
     502             :     {   // independent
     503          14 :         SCROW nRow = 0;
     504         147 :         for ( ; nRow < nRowCount && pPos1Iter != pCol1->end(); nRow++ )
     505             :         {
     506         133 :             ppRowHeader[ nRow ] = pPos1Iter->second;
     507         133 :             ++pPos1Iter;
     508             :         }
     509          14 :         for ( ; nRow < nRowCount; nRow++ )
     510           0 :             ppRowHeader[ nRow ] = NULL;
     511             :     }
     512             :     else
     513             :     {   // copy
     514           4 :         SCROW nRow = 0;
     515          52 :         for ( ; nRow < nRowCount && pPos1Iter != pCol1->end(); nRow++ )
     516             :         {
     517          48 :             ppRowHeader[ nRow ] = pPos1Iter->second ?
     518          48 :                 new ScAddress( *pPos1Iter->second ) : NULL;
     519          48 :             ++pPos1Iter;
     520             :         }
     521           4 :         for ( ; nRow < nRowCount; nRow++ )
     522           0 :             ppRowHeader[ nRow ] = NULL;
     523             :     }
     524          18 :     if ( nColAdd )
     525             :     {
     526          14 :         ++pColIter;
     527             :     }
     528             : 
     529             :     // data column by column and column-header
     530          18 :     sal_uLong nIndex = 0;
     531          46 :     for ( SCCOL nCol = 0; nCol < nColCount; nCol++ )
     532             :     {
     533          28 :         if ( pColIter != rCols.end() )
     534             :         {
     535          28 :             RowMap* pCol2 = pColIter->second;
     536          28 :             RowMap::const_iterator pPosIter = pCol2->begin();
     537          28 :             if ( pPosIter != pCol2->end() )
     538             :             {
     539          28 :                 if ( nRowAdd )
     540             :                 {
     541          20 :                     ppColHeader[ nCol ] = pPosIter->second; // independent
     542          20 :                     ++pPosIter;
     543             :                 }
     544             :                 else
     545           8 :                     ppColHeader[ nCol ] = pPosIter->second ?
     546           8 :                         new ScAddress( *pPosIter->second ) : NULL;
     547             :             }
     548             : 
     549          28 :             SCROW nRow = 0;
     550         281 :             for ( ; nRow < nRowCount && pPosIter != pCol2->end(); nRow++, nIndex++ )
     551             :             {
     552         253 :                 ppData[ nIndex ] = pPosIter->second;
     553         253 :                 ++pPosIter;
     554             :             }
     555          28 :             for ( ; nRow < nRowCount; nRow++, nIndex++ )
     556           0 :                 ppData[ nIndex ] = NULL;
     557             : 
     558          28 :             ++pColIter;
     559             :         }
     560             :         else
     561             :         {
     562           0 :             ppColHeader[ nCol ] = NULL;
     563           0 :             for ( SCROW nRow = 0; nRow < nRowCount; nRow++, nIndex++ )
     564             :             {
     565           0 :                 ppData[ nIndex ] = NULL;
     566             :             }
     567             :         }
     568             :     }
     569          18 : }
     570             : 
     571          18 : ScChartPositionMap::~ScChartPositionMap()
     572             : {
     573         271 :     for ( sal_uLong nIndex=0; nIndex < nCount; nIndex++ )
     574             :     {
     575         253 :         delete ppData[nIndex];
     576             :     }
     577          18 :     delete [] ppData;
     578             : 
     579             :     SCCOL j;
     580          46 :     for ( j=0; j < nColCount; j++ )
     581             :     {
     582          28 :         delete ppColHeader[j];
     583             :     }
     584          18 :     delete [] ppColHeader;
     585             :     SCROW i;
     586         199 :     for ( i=0; i < nRowCount; i++ )
     587             :     {
     588         181 :         delete ppRowHeader[i];
     589             :     }
     590          18 :     delete [] ppRowHeader;
     591         174 : }
     592             : 
     593             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11