LCOV - code coverage report
Current view: top level - sc/source/filter/oox - formulabuffer.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 190 217 87.6 %
Date: 2014-11-03 Functions: 22 24 91.7 %
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 <externallinkbuffer.hxx>
      13             : #include <com/sun/star/sheet/XFormulaTokens.hpp>
      14             : #include <com/sun/star/sheet/XArrayFormulaTokens.hpp>
      15             : #include <com/sun/star/container/XIndexAccess.hpp>
      16             : #include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
      17             : #include <com/sun/star/table/XCell2.hpp>
      18             : #include "formulacell.hxx"
      19             : #include "document.hxx"
      20             : #include "documentimport.hxx"
      21             : #include "convuno.hxx"
      22             : 
      23             : #include "rangelst.hxx"
      24             : #include "autonamecache.hxx"
      25             : #include "tokenuno.hxx"
      26             : #include "tokenarray.hxx"
      27             : #include "sharedformulagroups.hxx"
      28             : #include "externalrefmgr.hxx"
      29             : #include "tokenstringcontext.hxx"
      30             : #include <oox/token/tokens.hxx>
      31             : #include <svl/sharedstringpool.hxx>
      32             : 
      33             : using namespace com::sun::star;
      34             : using namespace ::com::sun::star::uno;
      35             : using namespace ::com::sun::star::table;
      36             : using namespace ::com::sun::star::sheet;
      37             : using namespace ::com::sun::star::container;
      38             : 
      39             : #include <boost/scoped_ptr.hpp>
      40             : #include <boost/noncopyable.hpp>
      41             : 
      42             : namespace oox { namespace xls {
      43             : 
      44             : namespace {
      45             : 
      46             : /**
      47             :  * Cache the token array for the last cell position in each column. We use
      48             :  * one cache per sheet.
      49             :  */
      50             : class CachedTokenArray : boost::noncopyable
      51             : {
      52             : public:
      53             : 
      54             :     struct Item : boost::noncopyable
      55             :     {
      56             :         SCROW mnRow;
      57             :         ScFormulaCell* mpCell;
      58             : 
      59         202 :         Item() : mnRow(-1), mpCell(NULL) {}
      60             :     };
      61             : 
      62          50 :     CachedTokenArray( ScDocument& rDoc ) :
      63          50 :         maCxt(&rDoc, formula::FormulaGrammar::GRAM_OOXML) {}
      64             : 
      65          50 :     ~CachedTokenArray()
      66          50 :     {
      67          50 :         ColCacheType::const_iterator it = maCache.begin(), itEnd = maCache.end();
      68         252 :         for (; it != itEnd; ++it)
      69         202 :             delete it->second;
      70          50 :     }
      71             : 
      72        2130 :     Item* get( const ScAddress& rPos, const OUString& rFormula )
      73             :     {
      74             :         // Check if a token array is cached for this column.
      75        2130 :         ColCacheType::iterator it = maCache.find(rPos.Col());
      76        2130 :         if (it == maCache.end())
      77         202 :             return NULL;
      78             : 
      79        1928 :         Item& rCached = *it->second;
      80        1928 :         const ScTokenArray& rCode = *rCached.mpCell->GetCode();
      81        1928 :         OUString aPredicted = rCode.CreateString(maCxt, rPos);
      82        1928 :         if (rFormula == aPredicted)
      83         810 :             return &rCached;
      84             : 
      85        1118 :         return NULL;
      86             :     }
      87             : 
      88        1320 :     void store( const ScAddress& rPos, ScFormulaCell* pCell )
      89             :     {
      90        1320 :         ColCacheType::iterator it = maCache.find(rPos.Col());
      91        1320 :         if (it == maCache.end())
      92             :         {
      93             :             // Create an entry for this column.
      94             :             std::pair<ColCacheType::iterator,bool> r =
      95         202 :                 maCache.insert(ColCacheType::value_type(rPos.Col(), new Item));
      96         202 :             if (!r.second)
      97             :                 // Insertion failed.
      98        1320 :                 return;
      99             : 
     100         202 :             it = r.first;
     101             :         }
     102             : 
     103        1320 :         Item& rItem = *it->second;
     104        1320 :         rItem.mnRow = rPos.Row();
     105        1320 :         rItem.mpCell = pCell;
     106             :     }
     107             : 
     108             : private:
     109             :     typedef boost::unordered_map<SCCOL, Item*> ColCacheType;
     110             :     ColCacheType maCache;
     111             :     sc::TokenStringContext maCxt;
     112             : };
     113             : 
     114          18 : void applySharedFormulas(
     115             :     ScDocumentImport& rDoc,
     116             :     SvNumberFormatter& rFormatter,
     117             :     std::vector<FormulaBuffer::SharedFormulaEntry>& rSharedFormulas,
     118             :     std::vector<FormulaBuffer::SharedFormulaDesc>& rCells )
     119             : {
     120          18 :     sc::SharedFormulaGroups aGroups;
     121             :     {
     122             :         // Process shared formulas first.
     123          18 :         std::vector<FormulaBuffer::SharedFormulaEntry>::const_iterator it = rSharedFormulas.begin(), itEnd = rSharedFormulas.end();
     124         144 :         for (; it != itEnd; ++it)
     125             :         {
     126         126 :             const table::CellAddress& rAddr = it->maAddress;
     127         126 :             sal_Int32 nId = it->mnSharedId;
     128         126 :             const OUString& rTokenStr = it->maTokenStr;
     129             : 
     130         126 :             ScAddress aPos;
     131         126 :             ScUnoConversion::FillScAddress(aPos, rAddr);
     132         126 :             ScCompiler aComp(&rDoc.getDoc(), aPos);
     133         126 :             aComp.SetNumberFormatter(&rFormatter);
     134         126 :             aComp.SetGrammar(formula::FormulaGrammar::GRAM_OOXML);
     135         126 :             ScTokenArray* pArray = aComp.CompileString(rTokenStr);
     136         126 :             if (pArray)
     137             :             {
     138         126 :                 aComp.CompileTokenArray(); // Generate RPN tokens.
     139         126 :                 aGroups.set(nId, pArray);
     140             :             }
     141         126 :         }
     142             :     }
     143             : 
     144             :     {
     145             :         // Process formulas that use shared formulas.
     146          18 :         std::vector<FormulaBuffer::SharedFormulaDesc>::const_iterator it = rCells.begin(), itEnd = rCells.end();
     147        2262 :         for (; it != itEnd; ++it)
     148             :         {
     149        2244 :             const table::CellAddress& rAddr = it->maAddress;
     150        2244 :             const ScTokenArray* pArray = aGroups.get(it->mnSharedId);
     151        2244 :             if (!pArray)
     152           0 :                 continue;
     153             : 
     154        2244 :             ScAddress aPos;
     155        2244 :             ScUnoConversion::FillScAddress(aPos, rAddr);
     156        2244 :             ScFormulaCell* pCell = new ScFormulaCell(&rDoc.getDoc(), aPos, *pArray);
     157        2244 :             rDoc.setFormulaCell(aPos, pCell);
     158        2244 :             if (it->maCellValue.isEmpty())
     159             :             {
     160             :                 // No cached cell value. Mark it for re-calculation.
     161           0 :                 pCell->SetDirty(true);
     162           0 :                 continue;
     163             :             }
     164             : 
     165             :             // Set cached formula results. For now, we only use numeric
     166             :             // results. Find out how to utilize cached results of other types.
     167        2244 :             switch (it->mnValueType)
     168             :             {
     169             :                 case XML_n:
     170             :                     // numeric value.
     171         728 :                     pCell->SetResultDouble(it->maCellValue.toDouble());
     172         728 :                 break;
     173             :                 default:
     174             :                     // Mark it for re-calculation.
     175        1516 :                     pCell->SetDirty(true);
     176             :             }
     177             :         }
     178          18 :     }
     179          18 : }
     180             : 
     181          50 : void applyCellFormulas(
     182             :     ScDocumentImport& rDoc, CachedTokenArray& rCache, SvNumberFormatter& rFormatter,
     183             :     const uno::Sequence<sheet::ExternalLinkInfo>& rExternalLinks,
     184             :     const std::vector<FormulaBuffer::TokenAddressItem>& rCells )
     185             : {
     186          50 :     std::vector<FormulaBuffer::TokenAddressItem>::const_iterator it = rCells.begin(), itEnd = rCells.end();
     187        2180 :     for (; it != itEnd; ++it)
     188             :     {
     189        2130 :         ScAddress aPos;
     190        2130 :         ScUnoConversion::FillScAddress(aPos, it->maCellAddress);
     191        2130 :         CachedTokenArray::Item* p = rCache.get(aPos, it->maTokenStr);
     192        2130 :         if (p)
     193             :         {
     194             :             // Use the cached version to avoid re-compilation.
     195             : 
     196         810 :             ScFormulaCell* pCell = NULL;
     197         810 :             if (p->mnRow + 1 == aPos.Row())
     198             :             {
     199             :                 // Put them in the same formula group.
     200         804 :                 ScFormulaCell& rPrev = *p->mpCell;
     201         804 :                 ScFormulaCellGroupRef xGroup = rPrev.GetCellGroup();
     202         804 :                 if (!xGroup)
     203             :                 {
     204             :                     // Last cell is not grouped yet. Start a new group.
     205             :                     assert(rPrev.aPos.Row() == p->mnRow);
     206         226 :                     xGroup = rPrev.CreateCellGroup(1, false);
     207             :                 }
     208         804 :                 ++xGroup->mnLength;
     209             : 
     210         804 :                 pCell = new ScFormulaCell(&rDoc.getDoc(), aPos, xGroup);
     211             :             }
     212             :             else
     213           6 :                 pCell = new ScFormulaCell(&rDoc.getDoc(), aPos, p->mpCell->GetCode()->Clone());
     214             : 
     215         810 :             rDoc.setFormulaCell(aPos, pCell);
     216             : 
     217             :             // Update the cache.
     218         810 :             p->mnRow = aPos.Row();
     219         810 :             p->mpCell = pCell;
     220        1620 :             continue;
     221             :         }
     222             : 
     223        1320 :         ScCompiler aCompiler(&rDoc.getDoc(), aPos);
     224        1320 :         aCompiler.SetNumberFormatter(&rFormatter);
     225        1320 :         aCompiler.SetGrammar(formula::FormulaGrammar::GRAM_OOXML);
     226        1320 :         aCompiler.SetExternalLinks(rExternalLinks);
     227        1320 :         ScTokenArray* pCode = aCompiler.CompileString(it->maTokenStr);
     228        1320 :         if (!pCode)
     229           0 :             continue;
     230             : 
     231        1320 :         aCompiler.CompileTokenArray(); // Generate RPN tokens.
     232        1320 :         ScFormulaCell* pCell = new ScFormulaCell(&rDoc.getDoc(), aPos, pCode);
     233        1320 :         rDoc.setFormulaCell(aPos, pCell);
     234        1320 :         rCache.store(aPos, pCell);
     235        1320 :     }
     236          50 : }
     237             : 
     238           0 : void applyArrayFormulas(
     239             :     ScDocumentImport& rDoc, SvNumberFormatter& rFormatter,
     240             :     const std::vector<FormulaBuffer::TokenRangeAddressItem>& rArrays )
     241             : {
     242           0 :     std::vector<FormulaBuffer::TokenRangeAddressItem>::const_iterator it = rArrays.begin(), itEnd = rArrays.end();
     243           0 :     for (; it != itEnd; ++it)
     244             :     {
     245           0 :         ScAddress aPos;
     246           0 :         ScUnoConversion::FillScAddress(aPos, it->maTokenAndAddress.maCellAddress);
     247           0 :         ScRange aRange;
     248           0 :         ScUnoConversion::FillScRange(aRange, it->maCellRangeAddress);
     249             : 
     250           0 :         ScCompiler aComp(&rDoc.getDoc(), aPos);
     251           0 :         aComp.SetNumberFormatter(&rFormatter);
     252           0 :         aComp.SetGrammar(formula::FormulaGrammar::GRAM_OOXML);
     253           0 :         boost::scoped_ptr<ScTokenArray> pArray(aComp.CompileString(it->maTokenAndAddress.maTokenStr));
     254           0 :         if (pArray)
     255           0 :             rDoc.setMatrixCells(aRange, *pArray, formula::FormulaGrammar::GRAM_OOXML);
     256           0 :     }
     257           0 : }
     258             : 
     259          50 : void applyCellFormulaValues(
     260             :     ScDocumentImport& rDoc, const std::vector<FormulaBuffer::FormulaValue>& rVector )
     261             : {
     262          50 :     svl::SharedStringPool& rStrPool = rDoc.getDoc().GetSharedStringPool();
     263             : 
     264          50 :     std::vector<FormulaBuffer::FormulaValue>::const_iterator it = rVector.begin(), itEnd = rVector.end();
     265        2178 :     for (; it != itEnd; ++it)
     266             :     {
     267        2128 :         ScAddress aCellPos;
     268        2128 :         ScUnoConversion::FillScAddress(aCellPos, it->maCellAddress);
     269        2128 :         ScFormulaCell* pCell = rDoc.getDoc().GetFormulaCell(aCellPos);
     270        2128 :         const OUString& rValueStr = it->maValueStr;
     271        2128 :         if (!pCell)
     272           0 :             continue;
     273             : 
     274        2128 :         switch (it->mnCellType)
     275             :         {
     276             :             case XML_n:
     277             :             {
     278        2058 :                 pCell->SetResultDouble(rValueStr.toDouble());
     279        2058 :                 pCell->ResetDirty();
     280        2058 :                 pCell->SetChanged(false);
     281             :             }
     282        2058 :             break;
     283             :             case XML_str:
     284             :             {
     285          46 :                 svl::SharedString aSS = rStrPool.intern(rValueStr);
     286          46 :                 pCell->SetResultToken(new formula::FormulaStringToken(aSS));
     287          46 :                 pCell->ResetDirty();
     288          46 :                 pCell->SetChanged(false);
     289             :             }
     290          46 :             break;
     291             :             default:
     292             :                 ;
     293             :         }
     294             :     }
     295          50 : }
     296             : 
     297         260 : void processSheetFormulaCells(
     298             :     ScDocumentImport& rDoc, FormulaBuffer::SheetItem& rItem, SvNumberFormatter& rFormatter,
     299             :     const uno::Sequence<sheet::ExternalLinkInfo>& rExternalLinks )
     300             : {
     301         260 :     if (rItem.mpSharedFormulaEntries && rItem.mpSharedFormulaIDs)
     302          18 :         applySharedFormulas(rDoc, rFormatter, *rItem.mpSharedFormulaEntries, *rItem.mpSharedFormulaIDs);
     303             : 
     304         260 :     if (rItem.mpCellFormulas)
     305             :     {
     306          50 :         CachedTokenArray aCache(rDoc.getDoc());
     307          50 :         applyCellFormulas(rDoc, aCache, rFormatter, rExternalLinks, *rItem.mpCellFormulas);
     308             :     }
     309             : 
     310         260 :     if (rItem.mpArrayFormulas)
     311           0 :         applyArrayFormulas(rDoc, rFormatter, *rItem.mpArrayFormulas);
     312             : 
     313         260 :     if (rItem.mpCellFormulaValues)
     314          50 :         applyCellFormulaValues(rDoc, *rItem.mpCellFormulaValues);
     315         260 : }
     316             : 
     317             : class WorkerThread: public salhelper::Thread, private boost::noncopyable
     318             : {
     319             :     ScDocumentImport& mrDoc;
     320             :     FormulaBuffer::SheetItem& mrItem;
     321             :     boost::scoped_ptr<SvNumberFormatter> mpFormatter;
     322             :     const uno::Sequence<sheet::ExternalLinkInfo>& mrExternalLinks;
     323             : 
     324             : public:
     325             :     WorkerThread(
     326             :         ScDocumentImport& rDoc, FormulaBuffer::SheetItem& rItem, SvNumberFormatter* pFormatter,
     327             :         const uno::Sequence<sheet::ExternalLinkInfo>& rExternalLinks ) :
     328             :         salhelper::Thread("xlsx-import-formula-buffer-worker-thread"),
     329             :         mrDoc(rDoc), mrItem(rItem), mpFormatter(pFormatter), mrExternalLinks(rExternalLinks) {}
     330             : 
     331             :     virtual ~WorkerThread() {}
     332             : 
     333             : protected:
     334             :     virtual void execute() SAL_OVERRIDE
     335             :     {
     336             :         processSheetFormulaCells(mrDoc, mrItem, *mpFormatter, mrExternalLinks);
     337             :     }
     338             : };
     339             : 
     340             : }
     341             : 
     342         126 : FormulaBuffer::SharedFormulaEntry::SharedFormulaEntry(
     343             :     const table::CellAddress& rAddr, const table::CellRangeAddress& rRange,
     344             :     const OUString& rTokenStr, sal_Int32 nSharedId ) :
     345         126 :     maAddress(rAddr), maRange(rRange), maTokenStr(rTokenStr), mnSharedId(nSharedId) {}
     346             : 
     347        2244 : FormulaBuffer::SharedFormulaDesc::SharedFormulaDesc(
     348             :     const com::sun::star::table::CellAddress& rAddr, sal_Int32 nSharedId,
     349             :     const OUString& rCellValue, sal_Int32 nValueType ) :
     350        2244 :     maAddress(rAddr), mnSharedId(nSharedId), maCellValue(rCellValue), mnValueType(nValueType) {}
     351             : 
     352         260 : FormulaBuffer::SheetItem::SheetItem() :
     353             :     mpCellFormulas(NULL),
     354             :     mpArrayFormulas(NULL),
     355             :     mpCellFormulaValues(NULL),
     356             :     mpSharedFormulaEntries(NULL),
     357         260 :     mpSharedFormulaIDs(NULL) {}
     358             : 
     359         128 : FormulaBuffer::FormulaBuffer( const WorkbookHelper& rHelper ) : WorkbookHelper( rHelper )
     360             : {
     361         128 : }
     362             : 
     363         128 : void FormulaBuffer::SetSheetCount( SCTAB nSheets )
     364             : {
     365         128 :     maCellFormulas.resize( nSheets );
     366         128 :     maCellArrayFormulas.resize( nSheets );
     367         128 :     maSharedFormulas.resize( nSheets );
     368         128 :     maSharedFormulaIds.resize( nSheets );
     369         128 :     maCellFormulaValues.resize( nSheets );
     370         128 : }
     371             : 
     372         128 : void FormulaBuffer::finalizeImport()
     373             : {
     374         128 :     ISegmentProgressBarRef xFormulaBar = getProgressBar().createSegment( getProgressBar().getFreeLength() );
     375             : 
     376         128 :     const size_t nThreadCount = 1;
     377         128 :     ScDocumentImport& rDoc = getDocImport();
     378         128 :     rDoc.getDoc().SetAutoNameCache(new ScAutoNameCache(&rDoc.getDoc()));
     379         256 :     ScExternalRefManager::ApiGuard aExtRefGuard(&rDoc.getDoc());
     380             : 
     381         128 :     SCTAB nTabCount = rDoc.getDoc().GetTableCount();
     382             : 
     383             :     // Fetch all the formulas to process first.
     384         256 :     std::vector<SheetItem> aSheetItems;
     385         128 :     aSheetItems.reserve(nTabCount);
     386         388 :     for (SCTAB nTab = 0; nTab < nTabCount; ++nTab)
     387         260 :         aSheetItems.push_back(getSheetItem(nTab));
     388             : 
     389         128 :     std::vector<SheetItem>::iterator it = aSheetItems.begin(), itEnd = aSheetItems.end();
     390             : 
     391             :     if (nThreadCount == 1)
     392             :     {
     393         388 :         for (; it != itEnd; ++it)
     394         260 :             processSheetFormulaCells(rDoc, *it, *rDoc.getDoc().GetFormatTable(), getExternalLinks().getLinkInfos());
     395             :     }
     396             :     else
     397             :     {
     398             :         typedef rtl::Reference<WorkerThread> WorkerThreadRef;
     399             :         std::vector<WorkerThreadRef> aThreads;
     400             :         aThreads.reserve(nThreadCount);
     401             :         // TODO: Right now we are spawning multiple threads all at once and block
     402             :         // on them all at once.  Any more clever thread management would require
     403             :         // use of condition variables which our own osl thread framework seems to
     404             :         // lack.
     405             :         while (it != itEnd)
     406             :         {
     407             :             for (size_t i = 0; i < nThreadCount; ++i)
     408             :             {
     409             :                 if (it == itEnd)
     410             :                     break;
     411             : 
     412             :                 WorkerThreadRef xThread(new WorkerThread(rDoc, *it, rDoc.getDoc().CreateFormatTable(), getExternalLinks().getLinkInfos()));
     413             :                 ++it;
     414             :                 aThreads.push_back(xThread);
     415             :                 xThread->launch();
     416             :             }
     417             : 
     418             :             for (size_t i = 0, n = aThreads.size(); i < n; ++i)
     419             :             {
     420             :                 if (aThreads[i].is())
     421             :                     aThreads[i]->join();
     422             :             }
     423             : 
     424             :             aThreads.clear();
     425             :         }
     426             :     }
     427             : 
     428         128 :     rDoc.getDoc().SetAutoNameCache(NULL);
     429             : 
     430         256 :     xFormulaBar->setPosition( 1.0 );
     431         128 : }
     432             : 
     433         260 : FormulaBuffer::SheetItem FormulaBuffer::getSheetItem( SCTAB nTab )
     434             : {
     435         260 :     osl::MutexGuard aGuard(&maMtxData);
     436             : 
     437         260 :     SheetItem aItem;
     438             : 
     439         260 :     if( (size_t) nTab >= maCellFormulas.size() )
     440             :     {
     441             :         SAL_WARN( "sc", "Tab " << nTab << " out of bounds " << maCellFormulas.size() );
     442           0 :         return aItem;
     443             :     }
     444             : 
     445         260 :     if( maCellFormulas[ nTab ].size() > 0 )
     446          50 :         aItem.mpCellFormulas = &maCellFormulas[ nTab ];
     447         260 :     if( maCellArrayFormulas[ nTab ].size() > 0 )
     448           0 :         aItem.mpArrayFormulas = &maCellArrayFormulas[ nTab ];
     449         260 :     if( maCellFormulaValues[ nTab ].size() > 0 )
     450          50 :         aItem.mpCellFormulaValues = &maCellFormulaValues[ nTab ];
     451         260 :     if( maSharedFormulas[ nTab ].size() > 0 )
     452          18 :         aItem.mpSharedFormulaEntries = &maSharedFormulas[ nTab ];
     453         260 :     if( maSharedFormulaIds[ nTab ].size() > 0 )
     454          18 :         aItem.mpSharedFormulaIDs = &maSharedFormulaIds[ nTab ];
     455             : 
     456         260 :     return aItem;
     457             : }
     458             : 
     459         126 : void FormulaBuffer::createSharedFormulaMapEntry(
     460             :     const table::CellAddress& rAddress, const table::CellRangeAddress& rRange,
     461             :     sal_Int32 nSharedId, const OUString& rTokens )
     462             : {
     463             :     assert( rAddress.Sheet >= 0 && (size_t)rAddress.Sheet < maSharedFormulas.size() );
     464         126 :     std::vector<SharedFormulaEntry>& rSharedFormulas = maSharedFormulas[ rAddress.Sheet ];
     465         126 :     SharedFormulaEntry aEntry(rAddress, rRange, rTokens, nSharedId);
     466         126 :     rSharedFormulas.push_back( aEntry );
     467         126 : }
     468             : 
     469        2130 : void FormulaBuffer::setCellFormula( const ::com::sun::star::table::CellAddress& rAddress, const OUString& rTokenStr )
     470             : {
     471             :     assert( rAddress.Sheet >= 0 && (size_t)rAddress.Sheet < maCellFormulas.size() );
     472        2130 :     maCellFormulas[ rAddress.Sheet ].push_back( TokenAddressItem( rTokenStr, rAddress ) );
     473        2130 : }
     474             : 
     475        2244 : void FormulaBuffer::setCellFormula(
     476             :     const table::CellAddress& rAddress, sal_Int32 nSharedId, const OUString& rCellValue, sal_Int32 nValueType )
     477             : {
     478             :     assert( rAddress.Sheet >= 0 && (size_t)rAddress.Sheet < maSharedFormulaIds.size() );
     479        2244 :     maSharedFormulaIds[rAddress.Sheet].push_back(
     480        4488 :         SharedFormulaDesc(rAddress, nSharedId, rCellValue, nValueType));
     481        2244 : }
     482             : 
     483           0 : void FormulaBuffer::setCellArrayFormula( const ::com::sun::star::table::CellRangeAddress& rRangeAddress, const ::com::sun::star::table::CellAddress& rTokenAddress, const OUString& rTokenStr )
     484             : {
     485             : 
     486           0 :     TokenAddressItem tokenPair( rTokenStr, rTokenAddress );
     487             :     assert( rRangeAddress.Sheet >= 0 && (size_t)rRangeAddress.Sheet < maCellArrayFormulas.size() );
     488           0 :     maCellArrayFormulas[ rRangeAddress.Sheet ].push_back( TokenRangeAddressItem( tokenPair, rRangeAddress ) );
     489           0 : }
     490             : 
     491        2128 : void FormulaBuffer::setCellFormulaValue(
     492             :         const css::table::CellAddress& rAddress, const OUString& rValueStr, sal_Int32 nCellType )
     493             : {
     494             :     assert( rAddress.Sheet >= 0 && (size_t)rAddress.Sheet < maCellFormulaValues.size() );
     495        2128 :     FormulaValue aVal;
     496        2128 :     aVal.maCellAddress = rAddress;
     497        2128 :     aVal.maValueStr = rValueStr;
     498        2128 :     aVal.mnCellType = nCellType;
     499        2128 :     maCellFormulaValues[rAddress.Sheet].push_back(aVal);
     500        2128 : }
     501             : 
     502          48 : }}
     503             : 
     504             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10