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-27 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          11 : FormulaBuffer::FormulaBuffer( const WorkbookHelper& rHelper ) : WorkbookHelper( rHelper )
      35             : {
      36          11 : }
      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          11 : void FormulaBuffer::finalizeImport()
      52             : {
      53          11 :     ISegmentProgressBarRef xFormulaBar = getProgressBar().createSegment( getProgressBar().getFreeLength() );
      54             : 
      55          11 :     ScDocument& rDoc = getScDocument();
      56          11 :     Reference< XIndexAccess > xSheets( getDocument()->getSheets(), UNO_QUERY_THROW );
      57          11 :     rDoc.SetAutoNameCache( new ScAutoNameCache( &rDoc ) );
      58          36 :     for ( sal_Int16 nTab = 0, nElem = xSheets->getCount(); nTab < nElem; ++nTab )
      59             :     {
      60          25 :         double fPosition = static_cast< double> (nTab + 1) /static_cast<double>(nElem);
      61          25 :         xFormulaBar->setPosition( fPosition );
      62          25 :         mxCurrSheet = getSheetFromDoc( nTab );
      63             :         // process shared Formula
      64          25 :         SheetToFormulaEntryMap::iterator sharedIt = sharedFormulas.find( nTab );
      65          25 :         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          25 :         SheetToSharedFormulaid::iterator formulDescIt = sharedFormulaIds.find( nTab );
      76          25 :         SheetToSharedIdToTokenIndex::iterator tokensIt = tokenIndexes.find( nTab );
      77          25 :         if ( formulDescIt != sharedFormulaIds.end() && tokensIt !=  tokenIndexes.end() )
      78             :         {
      79           1 :             SharedIdToTokenIndex& rTokenIdMap = tokensIt->second;
      80           1 :             std::vector< SharedFormulaDesc >& rVector = formulDescIt->second;
      81           8 :             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           7 :                 CellAddress& rAddress = it->first;
      86           7 :                 sal_Int32& rnSharedId = it->second;
      87           7 :                 SharedIdToTokenIndex::iterator itTokenId =  rTokenIdMap.find( rnSharedId );
      88           7 :                 if ( itTokenId != rTokenIdMap.end() )
      89             :                 {
      90           7 :                     ApiTokenSequence aTokens =  getFormulaParser().convertNameToFormula( itTokenId->second );
      91           7 :                     applyCellFormula( rDoc, aTokens, rAddress );
      92             :                 }
      93             :             }
      94             :         }
      95             : 
      96          25 :         FormulaDataMap::iterator cellIt = cellFormulas.find( nTab );
      97          25 :         if ( cellIt != cellFormulas.end() )
      98             :         {
      99           7 :             applyCellFormulas( cellIt->second );
     100             :         }
     101             : 
     102          25 :         ArrayFormulaDataMap::iterator itArray = cellArrayFormulas.find( nTab );
     103          25 :         if ( itArray != cellArrayFormulas.end() )
     104             :         {
     105           0 :             applyArrayFormulas( itArray->second );
     106             :         }
     107             : 
     108          25 :         FormulaValueMap::iterator itValues = cellFormulaValues.find( nTab );
     109          25 :         if ( itValues != cellFormulaValues.end() )
     110             :         {
     111           5 :             std::vector< ValueAddressPair > & rVector = itValues->second;
     112           5 :             applyCellFormulaValues( rVector );
     113             :         }
     114             :     }
     115          11 :     rDoc.SetAutoNameCache( NULL );
     116          11 :     xFormulaBar->setPosition( 1.0 );
     117          11 : }
     118             : 
     119          34 : void FormulaBuffer::applyCellFormula( ScDocument& rDoc, const ApiTokenSequence& rTokens, const ::com::sun::star::table::CellAddress& rAddress )
     120             : {
     121          34 :         ScTokenArray aTokenArray;
     122          34 :         ScAddress aCellPos;
     123          34 :         ScUnoConversion::FillScAddress( aCellPos, rAddress );
     124          34 :         ScTokenConversion::ConvertToTokenArray( rDoc, aTokenArray, rTokens );
     125          34 :         ScBaseCell* pNewCell = new ScFormulaCell( &rDoc, aCellPos, &aTokenArray );
     126          34 :         rDoc.PutCell( aCellPos, pNewCell, sal_True );
     127          34 : }
     128             : 
     129           7 : void FormulaBuffer::applyCellFormulas( const std::vector< TokenAddressItem >& rVector )
     130             : {
     131           7 :     ScDocument& rDoc = getScDocument();
     132          34 :     for ( std::vector< TokenAddressItem >::const_iterator it = rVector.begin(), it_end = rVector.end(); it != it_end; ++it )
     133             :     {
     134          27 :         const ::com::sun::star::table::CellAddress& rAddress = it->maCellAddress;
     135          27 :         ApiTokenSequence aTokens = getFormulaParser().importFormula( rAddress, it->maTokenStr );
     136          27 :         applyCellFormula( rDoc, aTokens, rAddress );
     137          27 :     }
     138           7 : }
     139             : 
     140           5 : void FormulaBuffer::applyCellFormulaValues( const std::vector< ValueAddressPair >& rVector )
     141             : {
     142           5 :     ScDocument& rDoc = getScDocument();
     143          28 :     for ( std::vector< ValueAddressPair >::const_iterator it = rVector.begin(), it_end = rVector.end(); it != it_end; ++it )
     144             :     {
     145          23 :         ScAddress aCellPos;
     146          23 :         ScUnoConversion::FillScAddress( aCellPos, it->first );
     147          23 :         ScBaseCell* pBaseCell = rDoc.GetCell( aCellPos );
     148             :         SAL_WARN_IF( !pBaseCell, "sc", "why is the formula not imported? bug?");
     149          23 :         if ( pBaseCell && pBaseCell->GetCellType() == CELLTYPE_FORMULA )
     150             :         {
     151          23 :             ScFormulaCell* pCell = static_cast< ScFormulaCell* >( pBaseCell );
     152          23 :             pCell->SetHybridDouble( it->second );
     153          23 :             pCell->ResetDirty();
     154          23 :             pCell->ResetChanged();
     155             :         }
     156             :     }
     157           5 : }
     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           1 : void FormulaBuffer::createSharedFormulaMapEntry( const ::com::sun::star::table::CellAddress& rAddress, sal_Int32 nSharedId, const rtl::OUString& rTokens )
     172             : {
     173           1 :      std::vector<SharedFormulaEntry>& rSharedFormulas = sharedFormulas[ rAddress.Sheet ];
     174           1 :     SharedFormulaEntry aEntry( rAddress, rTokens, nSharedId );
     175           1 :     rSharedFormulas.push_back( aEntry );
     176           1 : }
     177             : 
     178          27 : void FormulaBuffer::setCellFormula( const ::com::sun::star::table::CellAddress& rAddress, const rtl::OUString& rTokenStr )
     179             : {
     180          27 :     cellFormulas[ rAddress.Sheet ].push_back( TokenAddressItem( rTokenStr, rAddress ) );
     181          27 : }
     182             : 
     183           7 : void FormulaBuffer::setCellFormula( const ::com::sun::star::table::CellAddress& rAddress, sal_Int32 nSharedId )
     184             : {
     185           7 :     sharedFormulaIds[ rAddress.Sheet ].push_back( SharedFormulaDesc( rAddress, nSharedId ) );
     186           7 : }
     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          23 : void FormulaBuffer::setCellFormulaValue( const ::com::sun::star::table::CellAddress& rAddress, double fValue )
     196             : {
     197          23 :     cellFormulaValues[ rAddress.Sheet ].push_back( ValueAddressPair( rAddress, fValue ) );
     198          23 : }
     199             : 
     200           1 : void  FormulaBuffer::createSharedFormula( const ::com::sun::star::table::CellAddress& rAddress,  sal_Int32 nSharedId, const rtl::OUString& rTokenStr )
     201             : {
     202           1 :     ApiTokenSequence aTokens = getFormulaParser().importFormula( rAddress, rTokenStr );
     203           2 :     rtl::OUString aName = rtl::OUStringBuffer().appendAscii( RTL_CONSTASCII_STRINGPARAM( "__shared_" ) ).
     204           2 :         append( static_cast< sal_Int32 >( rAddress.Sheet + 1 ) ).
     205           1 :         append( sal_Unicode( '_' ) ).append( nSharedId ).
     206           3 :         append( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("_0") ) ).makeStringAndClear();
     207           1 :     ScRangeData* pScRangeData  = createNamedRangeObject( aName, aTokens, 0  );
     208             : 
     209           1 :     pScRangeData->SetType(RT_SHARED);
     210           1 :     sal_Int32 nTokenIndex = static_cast< sal_Int32 >( pScRangeData->GetIndex() );
     211             : 
     212             :         // store the token index in the map
     213           1 :    tokenIndexes[  rAddress.Sheet ][ nSharedId ] = nTokenIndex;
     214           1 : }
     215             : } // namespace xls
     216           9 : } // namespace oox
     217             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10