LCOV - code coverage report
Current view: top level - libreoffice/sc/source/filter/oox - formulabuffer.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 94 112 83.9 %
Date: 2012-12-17 Functions: 12 15 80.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             :  * Copyright 2012 LibreOffice contributors.
       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 "cell.hxx"
      18             : #include "document.hxx"
      19             : #include "convuno.hxx"
      20             : 
      21             : #include "rangelst.hxx"
      22             : #include "autonamecache.hxx"
      23             : #include "tokenuno.hxx"
      24             : 
      25             : namespace oox {
      26             : namespace xls {
      27             : 
      28             : using namespace ::com::sun::star::uno;
      29             : using namespace ::com::sun::star::table;
      30             : using namespace ::com::sun::star::uno;
      31             : using namespace ::com::sun::star::sheet;
      32             : using namespace ::com::sun::star::container;
      33             : 
      34          22 : FormulaBuffer::FormulaBuffer( const WorkbookHelper& rHelper ) : WorkbookHelper( rHelper )
      35             : {
      36          22 : }
      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          22 : void FormulaBuffer::finalizeImport()
      52             : {
      53          22 :     ISegmentProgressBarRef xFormulaBar = getProgressBar().createSegment( getProgressBar().getFreeLength() );
      54             : 
      55          22 :     ScDocument& rDoc = getScDocument();
      56          22 :     Reference< XIndexAccess > xSheets( getDocument()->getSheets(), UNO_QUERY_THROW );
      57          22 :     rDoc.SetAutoNameCache( new ScAutoNameCache( &rDoc ) );
      58          72 :     for ( sal_Int16 nTab = 0, nElem = xSheets->getCount(); nTab < nElem; ++nTab )
      59             :     {
      60          50 :         double fPosition = static_cast< double> (nTab + 1) /static_cast<double>(nElem);
      61          50 :         xFormulaBar->setPosition( fPosition );
      62          50 :         mxCurrSheet = getSheetFromDoc( nTab );
      63             :         // process shared Formula
      64          50 :         SheetToFormulaEntryMap::iterator sharedIt = sharedFormulas.find( nTab );
      65          50 :         if ( sharedIt != sharedFormulas.end() )
      66             :         {
      67             :             // shared id ( to create the special shared names from )
      68           2 :             std::vector<SharedFormulaEntry>& rSharedFormulas = sharedIt->second;
      69           4 :             for ( std::vector<SharedFormulaEntry>::iterator it = rSharedFormulas.begin(), it_end = rSharedFormulas.end(); it != it_end; ++it )
      70             :             {
      71           2 :                  createSharedFormula( it->maAddress, it->mnSharedId, it->maTokenStr );
      72             :             }
      73             :         }
      74             :         // now process any defined shared formulae
      75          50 :         SheetToSharedFormulaid::iterator formulDescIt = sharedFormulaIds.find( nTab );
      76          50 :         SheetToSharedIdToTokenIndex::iterator tokensIt = tokenIndexes.find( nTab );
      77          50 :         if ( formulDescIt != sharedFormulaIds.end() && tokensIt !=  tokenIndexes.end() )
      78             :         {
      79           2 :             SharedIdToTokenIndex& rTokenIdMap = tokensIt->second;
      80           2 :             std::vector< SharedFormulaDesc >& rVector = formulDescIt->second;
      81          16 :             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          14 :                 CellAddress& rAddress = it->first;
      86          14 :                 sal_Int32& rnSharedId = it->second;
      87          14 :                 SharedIdToTokenIndex::iterator itTokenId =  rTokenIdMap.find( rnSharedId );
      88          14 :                 if ( itTokenId != rTokenIdMap.end() )
      89             :                 {
      90          14 :                     ApiTokenSequence aTokens =  getFormulaParser().convertNameToFormula( itTokenId->second );
      91          14 :                     applyCellFormula( rDoc, aTokens, rAddress );
      92             :                 }
      93             :             }
      94             :         }
      95             : 
      96          50 :         FormulaDataMap::iterator cellIt = cellFormulas.find( nTab );
      97          50 :         if ( cellIt != cellFormulas.end() )
      98             :         {
      99          14 :             applyCellFormulas( cellIt->second );
     100             :         }
     101             : 
     102          50 :         ArrayFormulaDataMap::iterator itArray = cellArrayFormulas.find( nTab );
     103          50 :         if ( itArray != cellArrayFormulas.end() )
     104             :         {
     105           0 :             applyArrayFormulas( itArray->second );
     106             :         }
     107             : 
     108          50 :         FormulaValueMap::iterator itValues = cellFormulaValues.find( nTab );
     109          50 :         if ( itValues != cellFormulaValues.end() )
     110             :         {
     111          10 :             std::vector< ValueAddressPair > & rVector = itValues->second;
     112          10 :             applyCellFormulaValues( rVector );
     113             :         }
     114             :     }
     115          22 :     rDoc.SetAutoNameCache( NULL );
     116          22 :     xFormulaBar->setPosition( 1.0 );
     117          22 : }
     118             : 
     119          68 : void FormulaBuffer::applyCellFormula( ScDocument& rDoc, const ApiTokenSequence& rTokens, const ::com::sun::star::table::CellAddress& rAddress )
     120             : {
     121          68 :         ScTokenArray aTokenArray;
     122          68 :         ScAddress aCellPos;
     123          68 :         ScUnoConversion::FillScAddress( aCellPos, rAddress );
     124          68 :         ScTokenConversion::ConvertToTokenArray( rDoc, aTokenArray, rTokens );
     125          68 :         ScBaseCell* pNewCell = new ScFormulaCell( &rDoc, aCellPos, &aTokenArray );
     126          68 :         rDoc.PutCell( aCellPos, pNewCell, sal_True );
     127          68 : }
     128             : 
     129          14 : void FormulaBuffer::applyCellFormulas( const std::vector< TokenAddressItem >& rVector )
     130             : {
     131          14 :     ScDocument& rDoc = getScDocument();
     132          68 :     for ( std::vector< TokenAddressItem >::const_iterator it = rVector.begin(), it_end = rVector.end(); it != it_end; ++it )
     133             :     {
     134          54 :         const ::com::sun::star::table::CellAddress& rAddress = it->maCellAddress;
     135          54 :         ApiTokenSequence aTokens = getFormulaParser().importFormula( rAddress, it->maTokenStr );
     136          54 :         applyCellFormula( rDoc, aTokens, rAddress );
     137          54 :     }
     138          14 : }
     139             : 
     140          10 : void FormulaBuffer::applyCellFormulaValues( const std::vector< ValueAddressPair >& rVector )
     141             : {
     142          10 :     ScDocument& rDoc = getScDocument();
     143          56 :     for ( std::vector< ValueAddressPair >::const_iterator it = rVector.begin(), it_end = rVector.end(); it != it_end; ++it )
     144             :     {
     145          46 :         ScAddress aCellPos;
     146          46 :         ScUnoConversion::FillScAddress( aCellPos, it->first );
     147          46 :         ScBaseCell* pBaseCell = rDoc.GetCell( aCellPos );
     148             :         SAL_WARN_IF( !pBaseCell, "sc", "why is the formula not imported? bug?");
     149          46 :         if ( pBaseCell && pBaseCell->GetCellType() == CELLTYPE_FORMULA )
     150             :         {
     151          46 :             ScFormulaCell* pCell = static_cast< ScFormulaCell* >( pBaseCell );
     152          46 :             pCell->SetHybridDouble( it->second );
     153          46 :             pCell->ResetDirty();
     154          46 :             pCell->ResetChanged();
     155             :         }
     156             :     }
     157          10 : }
     158             : 
     159           0 : void FormulaBuffer::applyArrayFormulas( const std::vector< TokenRangeAddressItem >& rVector )
     160             : {
     161           0 :     for ( std::vector< TokenRangeAddressItem >::const_iterator it = rVector.begin(), it_end = rVector.end(); it != it_end; ++it )
     162             :     {
     163           0 :         Reference< XArrayFormulaTokens > xTokens( getRange( it->maCellRangeAddress ), UNO_QUERY );
     164             :         OSL_ENSURE( xTokens.is(), "SheetDataBuffer::finalizeArrayFormula - missing formula token interface" );
     165           0 :         ApiTokenSequence aTokens = getFormulaParser().importFormula( it->maTokenAndAddress.maCellAddress, it->maTokenAndAddress.maTokenStr );
     166           0 :         if( xTokens.is() )
     167           0 :             xTokens->setArrayTokens( aTokens );
     168           0 :     }
     169           0 : }
     170             : 
     171           2 : void FormulaBuffer::createSharedFormulaMapEntry( const ::com::sun::star::table::CellAddress& rAddress, sal_Int32 nSharedId, const rtl::OUString& rTokens )
     172             : {
     173           2 :      std::vector<SharedFormulaEntry>& rSharedFormulas = sharedFormulas[ rAddress.Sheet ];
     174           2 :     SharedFormulaEntry aEntry( rAddress, rTokens, nSharedId );
     175           2 :     rSharedFormulas.push_back( aEntry );
     176           2 : }
     177             : 
     178          54 : void FormulaBuffer::setCellFormula( const ::com::sun::star::table::CellAddress& rAddress, const rtl::OUString& rTokenStr )
     179             : {
     180          54 :     cellFormulas[ rAddress.Sheet ].push_back( TokenAddressItem( rTokenStr, rAddress ) );
     181          54 : }
     182             : 
     183          14 : void FormulaBuffer::setCellFormula( const ::com::sun::star::table::CellAddress& rAddress, sal_Int32 nSharedId )
     184             : {
     185          14 :     sharedFormulaIds[ rAddress.Sheet ].push_back( SharedFormulaDesc( rAddress, nSharedId ) );
     186          14 : }
     187             : 
     188           0 : void FormulaBuffer::setCellArrayFormula( const ::com::sun::star::table::CellRangeAddress& rRangeAddress, const ::com::sun::star::table::CellAddress& rTokenAddress, const rtl::OUString& rTokenStr )
     189             : {
     190             : 
     191           0 :     TokenAddressItem tokenPair( rTokenStr, rTokenAddress );
     192           0 :     cellArrayFormulas[ rRangeAddress.Sheet ].push_back( TokenRangeAddressItem( tokenPair, rRangeAddress ) );
     193           0 : }
     194             : 
     195          46 : void FormulaBuffer::setCellFormulaValue( const ::com::sun::star::table::CellAddress& rAddress, double fValue )
     196             : {
     197          46 :     cellFormulaValues[ rAddress.Sheet ].push_back( ValueAddressPair( rAddress, fValue ) );
     198          46 : }
     199             : 
     200           2 : void  FormulaBuffer::createSharedFormula( const ::com::sun::star::table::CellAddress& rAddress,  sal_Int32 nSharedId, const rtl::OUString& rTokenStr )
     201             : {
     202           2 :     ApiTokenSequence aTokens = getFormulaParser().importFormula( rAddress, rTokenStr );
     203           4 :     rtl::OUString aName = rtl::OUStringBuffer().appendAscii( RTL_CONSTASCII_STRINGPARAM( "__shared_" ) ).
     204           4 :         append( static_cast< sal_Int32 >( rAddress.Sheet + 1 ) ).
     205           2 :         append( sal_Unicode( '_' ) ).append( nSharedId ).
     206           6 :         append( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("_0") ) ).makeStringAndClear();
     207           2 :     ScRangeData* pScRangeData  = createNamedRangeObject( aName, aTokens, 0  );
     208             : 
     209           2 :     pScRangeData->SetType(RT_SHARED);
     210           2 :     sal_Int32 nTokenIndex = static_cast< sal_Int32 >( pScRangeData->GetIndex() );
     211             : 
     212             :         // store the token index in the map
     213           2 :    tokenIndexes[  rAddress.Sheet ][ nSharedId ] = nTokenIndex;
     214           2 : }
     215             : } // namespace xls
     216          24 : } // namespace oox
     217             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10