LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/sc/source/filter/oox - formulabuffer.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 95 128 74.2 %
Date: 2013-07-09 Functions: 12 16 75.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             : 
      10             : #include "formulabuffer.hxx"
      11             : #include "formulaparser.hxx"
      12             : #include <com/sun/star/sheet/XFormulaTokens.hpp>
      13             : #include <com/sun/star/sheet/XArrayFormulaTokens.hpp>
      14             : #include <com/sun/star/container/XIndexAccess.hpp>
      15             : #include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
      16             : #include <com/sun/star/table/XCell2.hpp>
      17             : #include "formulacell.hxx"
      18             : #include "document.hxx"
      19             : #include "convuno.hxx"
      20             : 
      21             : #include "rangelst.hxx"
      22             : #include "autonamecache.hxx"
      23             : #include "tokenuno.hxx"
      24             : #include "tokenarray.hxx"
      25             : 
      26             : namespace oox {
      27             : namespace xls {
      28             : 
      29             : using namespace ::com::sun::star::uno;
      30             : using namespace ::com::sun::star::table;
      31             : using namespace ::com::sun::star::sheet;
      32             : using namespace ::com::sun::star::container;
      33             : 
      34          21 : FormulaBuffer::FormulaBuffer( const WorkbookHelper& rHelper ) : WorkbookHelper( rHelper )
      35             : {
      36          21 : }
      37             : 
      38           0 : Reference< XCellRange > FormulaBuffer::getRange( const CellRangeAddress& rRange)
      39             : {
      40           0 :     Reference< XCellRange > xRange;
      41             :     try
      42             :     {
      43           0 :         xRange = mxCurrSheet->getCellRangeByPosition( rRange.StartColumn, rRange.StartRow, rRange.EndColumn, rRange.EndRow );
      44             :     }
      45           0 :     catch( Exception& )
      46             :     {
      47             :     }
      48           0 :     return xRange;
      49             : }
      50             : 
      51          21 : void FormulaBuffer::finalizeImport()
      52             : {
      53          21 :     ISegmentProgressBarRef xFormulaBar = getProgressBar().createSegment( getProgressBar().getFreeLength() );
      54             : 
      55          21 :     ScDocument& rDoc = getScDocument();
      56          42 :     Reference< XIndexAccess > xSheets( getDocument()->getSheets(), UNO_QUERY_THROW );
      57          21 :     rDoc.SetAutoNameCache( new ScAutoNameCache( &rDoc ) );
      58          64 :     for ( sal_Int16 nTab = 0, nElem = xSheets->getCount(); nTab < nElem; ++nTab )
      59             :     {
      60          43 :         double fPosition = static_cast< double> (nTab + 1) /static_cast<double>(nElem);
      61          43 :         xFormulaBar->setPosition( fPosition );
      62          43 :         mxCurrSheet = getSheetFromDoc( nTab );
      63             :         // process shared Formula
      64          43 :         SheetToFormulaEntryMap::iterator sharedIt = sharedFormulas.find( nTab );
      65          43 :         if ( sharedIt != sharedFormulas.end() )
      66             :         {
      67             :             // shared id ( to create the special shared names from )
      68           1 :             std::vector<SharedFormulaEntry>& rSharedFormulas = sharedIt->second;
      69           2 :             for ( std::vector<SharedFormulaEntry>::iterator it = rSharedFormulas.begin(), it_end = rSharedFormulas.end(); it != it_end; ++it )
      70             :             {
      71           1 :                  createSharedFormula( it->maAddress, it->mnSharedId, it->maTokenStr );
      72             :             }
      73             :         }
      74             :         // now process any defined shared formulae
      75          43 :         SheetToSharedFormulaid::iterator formulDescIt = sharedFormulaIds.find( nTab );
      76          43 :         SheetToSharedIdToTokenIndex::iterator tokensIt = tokenIndexes.find( nTab );
      77          43 :         if ( formulDescIt != sharedFormulaIds.end() && tokensIt !=  tokenIndexes.end() )
      78             :         {
      79           1 :             SharedIdToTokenIndex& rTokenIdMap = tokensIt->second;
      80           1 :             std::vector< SharedFormulaDesc >& rVector = formulDescIt->second;
      81          18 :             for ( std::vector< SharedFormulaDesc >::iterator it = rVector.begin(), it_end = rVector.end(); it != it_end; ++it )
      82             :             {
      83             :                 // see if we have a
      84             :                 // resolved tokenId
      85          17 :                 CellAddress& rAddress = it->first;
      86          17 :                 sal_Int32& rnSharedId = it->second;
      87          17 :                 SharedIdToTokenIndex::iterator itTokenId =  rTokenIdMap.find( rnSharedId );
      88          17 :                 if ( itTokenId != rTokenIdMap.end() )
      89             :                 {
      90          17 :                     ApiTokenSequence aTokens =  getFormulaParser().convertNameToFormula( itTokenId->second );
      91          17 :                     applyCellFormula( rDoc, aTokens, rAddress );
      92             :                 }
      93             :             }
      94             :         }
      95             : 
      96          43 :         FormulaDataMap::iterator cellIt = cellFormulas.find( nTab );
      97          43 :         if ( cellIt != cellFormulas.end() )
      98             :         {
      99           6 :             applyCellFormulas( cellIt->second );
     100             :         }
     101             : 
     102          43 :         ArrayFormulaDataMap::iterator itArray = cellArrayFormulas.find( nTab );
     103          43 :         if ( itArray != cellArrayFormulas.end() )
     104             :         {
     105           0 :             applyArrayFormulas( itArray->second );
     106             :         }
     107             : 
     108          43 :         FormulaValueMap::iterator itValues = cellFormulaValues.find( nTab );
     109          43 :         if ( itValues != cellFormulaValues.end() )
     110             :         {
     111           5 :             std::vector< ValueAddressPair > & rVector = itValues->second;
     112           5 :             applyCellFormulaValues( rVector );
     113             :         }
     114             :     }
     115          21 :     rDoc.SetAutoNameCache( NULL );
     116          42 :     xFormulaBar->setPosition( 1.0 );
     117          21 : }
     118             : 
     119          42 : void FormulaBuffer::applyCellFormula( ScDocument& rDoc, const ApiTokenSequence& rTokens, const ::com::sun::star::table::CellAddress& rAddress )
     120             : {
     121          42 :     ScTokenArray aTokenArray;
     122          42 :     ScAddress aCellPos;
     123          42 :     ScUnoConversion::FillScAddress( aCellPos, rAddress );
     124          42 :     ScTokenConversion::ConvertToTokenArray( rDoc, aTokenArray, rTokens );
     125          42 :     ScFormulaCell* pNewCell = new ScFormulaCell( &rDoc, aCellPos, &aTokenArray );
     126          42 :     pNewCell->StartListeningTo( &rDoc );
     127          42 :     rDoc.EnsureTable(aCellPos.Tab());
     128          42 :     rDoc.SetFormulaCell(aCellPos, pNewCell);
     129          42 : }
     130             : 
     131           6 : void FormulaBuffer::applyCellFormulas( const std::vector< TokenAddressItem >& rVector )
     132             : {
     133           6 :     ScDocument& rDoc = getScDocument();
     134          31 :     for ( std::vector< TokenAddressItem >::const_iterator it = rVector.begin(), it_end = rVector.end(); it != it_end; ++it )
     135             :     {
     136          25 :         const ::com::sun::star::table::CellAddress& rAddress = it->maCellAddress;
     137          25 :         ApiTokenSequence aTokens = getFormulaParser().importFormula( rAddress, it->maTokenStr );
     138          25 :         applyCellFormula( rDoc, aTokens, rAddress );
     139          25 :     }
     140           6 : }
     141             : 
     142           5 : void FormulaBuffer::applyCellFormulaValues( const std::vector< ValueAddressPair >& rVector )
     143             : {
     144           5 :     ScDocument& rDoc = getScDocument();
     145          28 :     for ( std::vector< ValueAddressPair >::const_iterator it = rVector.begin(), it_end = rVector.end(); it != it_end; ++it )
     146             :     {
     147          23 :         ScAddress aCellPos;
     148          23 :         ScUnoConversion::FillScAddress( aCellPos, it->first );
     149          23 :         ScFormulaCell* pCell = rDoc.GetFormulaCell(aCellPos);
     150          23 :         if (pCell)
     151             :         {
     152          23 :             pCell->SetHybridDouble( it->second );
     153          23 :             pCell->ResetDirty();
     154          23 :             pCell->SetChanged(false);
     155             :         }
     156             :     }
     157           5 : }
     158             : // bound to need this somewhere else, if so probably need to move it to
     159             : // worksheethelper or somewhere else more suitable
     160           0 : void StartCellListening( sal_Int16 nSheet, sal_Int32 nRow, sal_Int32 nCol, ScDocument& rDoc )
     161             : {
     162           0 :     ScAddress aCellPos;
     163           0 :     CellAddress aAddress;
     164           0 :     aAddress.Sheet = nSheet;
     165           0 :     aAddress.Row = nRow;
     166           0 :     aAddress.Column = nCol;
     167           0 :     ScUnoConversion::FillScAddress( aCellPos, aAddress );
     168           0 :     ScFormulaCell* pFCell = rDoc.GetFormulaCell( aCellPos );
     169           0 :     if ( pFCell )
     170           0 :         pFCell->StartListeningTo( &rDoc );
     171           0 : }
     172             : 
     173           0 : void FormulaBuffer::applyArrayFormulas( const std::vector< TokenRangeAddressItem >& rVector )
     174             : {
     175           0 :     ScDocument& rDoc = getScDocument();
     176           0 :     for ( std::vector< TokenRangeAddressItem >::const_iterator it = rVector.begin(), it_end = rVector.end(); it != it_end; ++it )
     177             :     {
     178           0 :         Reference< XArrayFormulaTokens > xTokens( getRange( it->maCellRangeAddress ), UNO_QUERY );
     179             :         OSL_ENSURE( xTokens.is(), "SheetDataBuffer::finalizeArrayFormula - missing formula token interface" );
     180           0 :         ApiTokenSequence aTokens = getFormulaParser().importFormula( it->maTokenAndAddress.maCellAddress, it->maTokenAndAddress.maTokenStr );
     181           0 :         if( xTokens.is() )
     182             :         {
     183           0 :             xTokens->setArrayTokens( aTokens );
     184             :             // set dependencies, add listeners on the cells in array
     185           0 :             for ( sal_Int32 nCol = it->maCellRangeAddress.StartColumn; nCol <=  it->maCellRangeAddress.EndColumn; ++nCol )
     186             :             {
     187           0 :                 for ( sal_Int32 nRow = it->maCellRangeAddress.StartRow; nRow <=  it->maCellRangeAddress.EndRow; ++nRow )
     188             :                 {
     189           0 :                     StartCellListening( it->maCellRangeAddress.Sheet, nRow, nCol, rDoc );
     190             :                 }
     191             :             }
     192             :         }
     193           0 :     }
     194           0 : }
     195             : 
     196           1 : void FormulaBuffer::createSharedFormulaMapEntry( const ::com::sun::star::table::CellAddress& rAddress, sal_Int32 nSharedId, const OUString& rTokens )
     197             : {
     198           1 :     std::vector<SharedFormulaEntry>& rSharedFormulas = sharedFormulas[ rAddress.Sheet ];
     199           1 :     SharedFormulaEntry aEntry( rAddress, rTokens, nSharedId );
     200           1 :     rSharedFormulas.push_back( aEntry );
     201           1 : }
     202             : 
     203          25 : void FormulaBuffer::setCellFormula( const ::com::sun::star::table::CellAddress& rAddress, const OUString& rTokenStr )
     204             : {
     205          25 :     cellFormulas[ rAddress.Sheet ].push_back( TokenAddressItem( rTokenStr, rAddress ) );
     206          25 : }
     207             : 
     208          17 : void FormulaBuffer::setCellFormula( const ::com::sun::star::table::CellAddress& rAddress, sal_Int32 nSharedId )
     209             : {
     210          17 :     sharedFormulaIds[ rAddress.Sheet ].push_back( SharedFormulaDesc( rAddress, nSharedId ) );
     211          17 : }
     212             : 
     213           0 : void FormulaBuffer::setCellArrayFormula( const ::com::sun::star::table::CellRangeAddress& rRangeAddress, const ::com::sun::star::table::CellAddress& rTokenAddress, const OUString& rTokenStr )
     214             : {
     215             : 
     216           0 :     TokenAddressItem tokenPair( rTokenStr, rTokenAddress );
     217           0 :     cellArrayFormulas[ rRangeAddress.Sheet ].push_back( TokenRangeAddressItem( tokenPair, rRangeAddress ) );
     218           0 : }
     219             : 
     220          23 : void FormulaBuffer::setCellFormulaValue( const ::com::sun::star::table::CellAddress& rAddress, double fValue )
     221             : {
     222          23 :     cellFormulaValues[ rAddress.Sheet ].push_back( ValueAddressPair( rAddress, fValue ) );
     223          23 : }
     224             : 
     225           1 : void  FormulaBuffer::createSharedFormula( const ::com::sun::star::table::CellAddress& rAddress,  sal_Int32 nSharedId, const OUString& rTokenStr )
     226             : {
     227           1 :     ApiTokenSequence aTokens = getFormulaParser().importFormula( rAddress, rTokenStr );
     228           2 :     OUString aName = OUStringBuffer().appendAscii( RTL_CONSTASCII_STRINGPARAM( "__shared_" ) ).
     229           2 :         append( static_cast< sal_Int32 >( rAddress.Sheet + 1 ) ).
     230           1 :         append( sal_Unicode( '_' ) ).append( nSharedId ).
     231           4 :         append( OUString("_0") ).makeStringAndClear();
     232           1 :     ScRangeData* pScRangeData  = createNamedRangeObject( aName, aTokens, 0  );
     233             : 
     234           1 :     pScRangeData->SetType(RT_SHARED);
     235           1 :     sal_Int32 nTokenIndex = static_cast< sal_Int32 >( pScRangeData->GetIndex() );
     236             : 
     237             :         // store the token index in the map
     238           2 :    tokenIndexes[  rAddress.Sheet ][ nSharedId ] = nTokenIndex;
     239           1 : }
     240             : } // namespace xls
     241          15 : } // namespace oox
     242             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10