[Libreoffice-commits] core.git: 20 commits - formula/source include/formula include/svl sc/inc sc/qa sc/source svl/source
Kohei Yoshida
kohei.yoshida at collabora.com
Thu Nov 7 02:39:49 CET 2013
formula/source/core/api/FormulaCompiler.cxx | 66 +++--
include/formula/token.hxx | 19 +
include/svl/sharedstringpool.hxx | 2
sc/inc/compiler.hxx | 12
sc/inc/document.hxx | 1
sc/inc/documentimport.hxx | 2
sc/inc/externalrefmgr.hxx | 35 +-
sc/inc/formulacell.hxx | 18 +
sc/qa/unit/ucalc.hxx | 2
sc/qa/unit/ucalc_formula.cxx | 56 ++++
sc/source/core/data/column.cxx | 2
sc/source/core/data/column3.cxx | 14 -
sc/source/core/data/conditio.cxx | 8
sc/source/core/data/documen2.cxx | 5
sc/source/core/data/documen4.cxx | 4
sc/source/core/data/documentimport.cxx | 10
sc/source/core/data/formulacell.cxx | 95 ++++++-
sc/source/core/data/poolhelp.cxx | 28 +-
sc/source/core/data/table2.cxx | 4
sc/source/core/data/table3.cxx | 2
sc/source/core/data/validat.cxx | 4
sc/source/core/inc/poolhelp.hxx | 4
sc/source/core/tool/address.cxx | 67 ++++-
sc/source/core/tool/compiler.cxx | 64 ++---
sc/source/core/tool/consoli.cxx | 4
sc/source/filter/excel/excform.cxx | 2
sc/source/filter/excel/impop.cxx | 2
sc/source/filter/excel/xechart.cxx | 4
sc/source/filter/excel/xipivot.cxx | 2
sc/source/filter/inc/formulabuffer.hxx | 57 +++-
sc/source/filter/lotus/lotimpop.cxx | 2
sc/source/filter/lotus/op.cxx | 4
sc/source/filter/oox/formulabuffer.cxx | 328 +++++++++++++++++----------
sc/source/filter/oox/worksheethelper.cxx | 2
sc/source/filter/orcus/interface.cxx | 4
sc/source/filter/qpro/qpro.cxx | 2
sc/source/filter/xcl97/XclImpChangeTrack.cxx | 2
sc/source/filter/xml/xmlcelli.cxx | 2
sc/source/ui/docshell/externalrefmgr.cxx | 91 +++++++
sc/source/ui/docshell/impex.cxx | 2
sc/source/ui/miscdlgs/anyrefdg.cxx | 8
sc/source/ui/unoobj/cellsuno.cxx | 2
sc/source/ui/unoobj/funcuno.cxx | 5
sc/source/ui/vba/vbaname.cxx | 6
sc/source/ui/vba/vbanames.cxx | 4
sc/source/ui/vba/vbarange.cxx | 7
sc/source/ui/view/tabvwsha.cxx | 4
sc/source/ui/view/viewfun4.cxx | 9
sc/source/ui/view/viewfunc.cxx | 2
svl/source/misc/sharedstringpool.cxx | 6
svl/source/numbers/zforfind.cxx | 6
svl/source/numbers/zforfind.hxx | 3
52 files changed, 793 insertions(+), 303 deletions(-)
New commits:
commit db65fff2aa0e98622932c0372212b4a68f65b72e
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date: Wed Nov 6 18:51:34 2013 -0500
Perform formula cell compilations in multiple threads during xlsx import.
One sheet per thread. Right now the thread count is set to 1 due to non
re-entrancy of a large portion of Calc core, and beyond. We need to fix
that first before setting the thread count to more than 1.
Change-Id: I6997c1e9540de939f1f00b1798e2b32059787ae5
diff --git a/sc/source/filter/inc/formulabuffer.hxx b/sc/source/filter/inc/formulabuffer.hxx
index f9e5229..7e881ee 100644
--- a/sc/source/filter/inc/formulabuffer.hxx
+++ b/sc/source/filter/inc/formulabuffer.hxx
@@ -13,6 +13,8 @@
#include <utility>
#include "oox/helper/refmap.hxx"
#include "oox/helper/refvector.hxx"
+#include "salhelper/thread.hxx"
+#include "osl/mutex.hxx"
#include "workbookhelper.hxx"
#include <com/sun/star/table/CellAddress.hpp>
#include <com/sun/star/table/CellRangeAddress.hpp>
@@ -29,6 +31,21 @@ namespace oox { namespace xls {
class FormulaBuffer : public WorkbookHelper
{
+ class FinalizeThread : public salhelper::Thread
+ {
+ FormulaBuffer& mrParent;
+ size_t mnThreadCount;
+ public:
+ FinalizeThread( FormulaBuffer& rParent, size_t nThreadCount );
+ virtual ~FinalizeThread();
+
+ protected:
+ virtual void execute();
+ };
+
+ friend class FinalizeThread;
+
+public:
/**
* Represents a shared formula definition.
*/
@@ -74,6 +91,20 @@ class FormulaBuffer : public WorkbookHelper
TokenRangeAddressItem( const TokenAddressItem& rTokenAndAddress, const ::com::sun::star::table::CellRangeAddress& rCellRangeAddress ) : maTokenAndAddress( rTokenAndAddress ), maCellRangeAddress( rCellRangeAddress ) {}
};
+ typedef std::pair<com::sun::star::table::CellAddress, double> ValueAddressPair;
+
+ struct SheetItem
+ {
+ std::vector<TokenAddressItem>* mpCellFormulas;
+ std::vector<TokenRangeAddressItem>* mpArrayFormulas;
+ std::vector<ValueAddressPair>* mpCellFormulaValues;
+ std::vector<SharedFormulaEntry>* mpSharedFormulaEntries;
+ std::vector<SharedFormulaDesc>* mpSharedFormulaIDs;
+
+ SheetItem();
+ };
+
+private:
typedef ::std::map< SCTAB, std::vector<TokenAddressItem> > FormulaDataMap;
typedef ::std::map< SCTAB, std::vector<TokenRangeAddressItem> > ArrayFormulaDataMap;
// sheet -> list of shared formula descriptions
@@ -81,19 +112,16 @@ class FormulaBuffer : public WorkbookHelper
// sheet -> stuff needed to create shared formulae
typedef ::std::map< SCTAB, std::vector<SharedFormulaEntry> > SheetToFormulaEntryMap;
- typedef ::std::pair< ::com::sun::star::table::CellAddress, double > ValueAddressPair;
typedef ::std::map< SCTAB, std::vector<ValueAddressPair> > FormulaValueMap;
+ osl::Mutex maMtxData;
FormulaDataMap maCellFormulas;
ArrayFormulaDataMap maCellArrayFormulas;
SheetToFormulaEntryMap maSharedFormulas;
SheetToSharedFormulaid maSharedFormulaIds;
FormulaValueMap maCellFormulaValues;
- void applyArrayFormulas( const std::vector< TokenRangeAddressItem >& rVector );
- void applyCellFormulas( const std::vector< TokenAddressItem >& rVector );
- void applyCellFormulaValues( const std::vector< ValueAddressPair >& rVector );
- void applySharedFormulas( SCTAB nTab );
+ SheetItem getSheetItem( SCTAB nTab );
public:
explicit FormulaBuffer( const WorkbookHelper& rHelper );
diff --git a/sc/source/filter/oox/formulabuffer.cxx b/sc/source/filter/oox/formulabuffer.cxx
index 04be139..c3e1d24 100644
--- a/sc/source/filter/oox/formulabuffer.cxx
+++ b/sc/source/filter/oox/formulabuffer.cxx
@@ -33,114 +33,22 @@ using namespace ::com::sun::star::table;
using namespace ::com::sun::star::sheet;
using namespace ::com::sun::star::container;
-namespace oox { namespace xls {
-
-FormulaBuffer::SharedFormulaEntry::SharedFormulaEntry(
- const table::CellAddress& rAddr, const table::CellRangeAddress& rRange,
- const OUString& rTokenStr, sal_Int32 nSharedId ) :
- maAddress(rAddr), maRange(rRange), maTokenStr(rTokenStr), mnSharedId(nSharedId) {}
-
-FormulaBuffer::SharedFormulaDesc::SharedFormulaDesc(
- const com::sun::star::table::CellAddress& rAddr, sal_Int32 nSharedId,
- const OUString& rCellValue, sal_Int32 nValueType ) :
- maAddress(rAddr), mnSharedId(nSharedId), maCellValue(rCellValue), mnValueType(nValueType) {}
-
-FormulaBuffer::FormulaBuffer( const WorkbookHelper& rHelper ) : WorkbookHelper( rHelper )
-{
-}
-
-void FormulaBuffer::finalizeImport()
-{
- ISegmentProgressBarRef xFormulaBar = getProgressBar().createSegment( getProgressBar().getFreeLength() );
-
- ScDocument& rDoc = getScDocument();
- rDoc.SetAutoNameCache( new ScAutoNameCache( &rDoc ) );
- for (SCTAB nTab = 0, nElem = rDoc.GetTableCount(); nTab < nElem; ++nTab)
- {
- double fPosition = static_cast< double> (nTab + 1) /static_cast<double>(nElem);
- xFormulaBar->setPosition( fPosition );
+#include <boost/scoped_ptr.hpp>
- applySharedFormulas(nTab);
-
- FormulaDataMap::iterator cellIt = maCellFormulas.find( nTab );
- if ( cellIt != maCellFormulas.end() )
- {
- applyCellFormulas( cellIt->second );
- }
-
- ArrayFormulaDataMap::iterator itArray = maCellArrayFormulas.find( nTab );
- if ( itArray != maCellArrayFormulas.end() )
- {
- applyArrayFormulas( itArray->second );
- }
-
- FormulaValueMap::iterator itValues = maCellFormulaValues.find( nTab );
- if ( itValues != maCellFormulaValues.end() )
- {
- std::vector< ValueAddressPair > & rVector = itValues->second;
- applyCellFormulaValues( rVector );
- }
- }
- rDoc.SetAutoNameCache( NULL );
- xFormulaBar->setPosition( 1.0 );
-}
-
-void FormulaBuffer::applyCellFormulas( const std::vector< TokenAddressItem >& rVector )
-{
- ScDocumentImport& rDoc = getDocImport();
- ScExternalRefManager::ApiGuard aExtRefGuard(&rDoc.getDoc());
- for ( std::vector< TokenAddressItem >::const_iterator it = rVector.begin(), it_end = rVector.end(); it != it_end; ++it )
- {
- ScAddress aPos;
- ScUnoConversion::FillScAddress(aPos, it->maCellAddress);
- ScCompiler aCompiler(&rDoc.getDoc(), aPos);
- aCompiler.SetGrammar(formula::FormulaGrammar::GRAM_ENGLISH_XL_OOX);
- ScTokenArray* pCode = aCompiler.CompileString(it->maTokenStr);
- if (!pCode)
- continue;
+namespace oox { namespace xls {
- rDoc.setFormulaCell(aPos, pCode);
- }
-}
+namespace {
-void FormulaBuffer::applyCellFormulaValues( const std::vector< ValueAddressPair >& rVector )
+void applySharedFormulas(
+ ScDocumentImport& rDoc,
+ SvNumberFormatter& rFormatter,
+ std::vector<FormulaBuffer::SharedFormulaEntry>& rSharedFormulas,
+ std::vector<FormulaBuffer::SharedFormulaDesc>& rCells )
{
- ScDocument& rDoc = getScDocument();
- for ( std::vector< ValueAddressPair >::const_iterator it = rVector.begin(), it_end = rVector.end(); it != it_end; ++it )
- {
- ScAddress aCellPos;
- ScUnoConversion::FillScAddress( aCellPos, it->first );
- ScFormulaCell* pCell = rDoc.GetFormulaCell(aCellPos);
- if (pCell)
- {
- pCell->SetHybridDouble( it->second );
- pCell->ResetDirty();
- pCell->SetChanged(false);
- }
- }
-}
-
-void FormulaBuffer::applySharedFormulas( SCTAB nTab )
-{
- SheetToFormulaEntryMap::const_iterator itShared = maSharedFormulas.find(nTab);
- if (itShared == maSharedFormulas.end())
- // There is no shared formulas for this sheet.
- return;
-
- SheetToSharedFormulaid::const_iterator itCells = maSharedFormulaIds.find(nTab);
- if (itCells == maSharedFormulaIds.end())
- // There is no formula cells that use shared formulas for this sheet.
- return;
-
- const std::vector<SharedFormulaEntry>& rSharedFormulas = itShared->second;
- const std::vector<SharedFormulaDesc>& rCells = itCells->second;
-
- ScDocumentImport& rDoc = getDocImport();
-
sc::SharedFormulaGroups aGroups;
{
// Process shared formulas first.
- std::vector<SharedFormulaEntry>::const_iterator it = rSharedFormulas.begin(), itEnd = rSharedFormulas.end();
+ std::vector<FormulaBuffer::SharedFormulaEntry>::const_iterator it = rSharedFormulas.begin(), itEnd = rSharedFormulas.end();
for (; it != itEnd; ++it)
{
const table::CellAddress& rAddr = it->maAddress;
@@ -150,6 +58,7 @@ void FormulaBuffer::applySharedFormulas( SCTAB nTab )
ScAddress aPos;
ScUnoConversion::FillScAddress(aPos, rAddr);
ScCompiler aComp(&rDoc.getDoc(), aPos);
+ aComp.SetNumberFormatter(&rFormatter);
aComp.SetGrammar(formula::FormulaGrammar::GRAM_ENGLISH_XL_OOX);
ScTokenArray* pArray = aComp.CompileString(rTokenStr);
if (pArray)
@@ -159,7 +68,7 @@ void FormulaBuffer::applySharedFormulas( SCTAB nTab )
{
// Process formulas that use shared formulas.
- std::vector<SharedFormulaDesc>::const_iterator it = rCells.begin(), itEnd = rCells.end();
+ std::vector<FormulaBuffer::SharedFormulaDesc>::const_iterator it = rCells.begin(), itEnd = rCells.end();
for (; it != itEnd; ++it)
{
const table::CellAddress& rAddr = it->maAddress;
@@ -194,10 +103,32 @@ void FormulaBuffer::applySharedFormulas( SCTAB nTab )
}
}
-void FormulaBuffer::applyArrayFormulas( const std::vector< TokenRangeAddressItem >& rVector )
+void applyCellFormulas(
+ ScDocumentImport& rDoc, SvNumberFormatter& rFormatter,
+ const std::vector<FormulaBuffer::TokenAddressItem>& rCells )
{
- ScDocumentImport& rDocImport = getDocImport();
- std::vector<TokenRangeAddressItem>::const_iterator it = rVector.begin(), itEnd = rVector.end();
+ ScExternalRefManager::ApiGuard aExtRefGuard(&rDoc.getDoc());
+ std::vector<FormulaBuffer::TokenAddressItem>::const_iterator it = rCells.begin(), itEnd = rCells.end();
+ for (; it != itEnd; ++it)
+ {
+ ScAddress aPos;
+ ScUnoConversion::FillScAddress(aPos, it->maCellAddress);
+ ScCompiler aCompiler(&rDoc.getDoc(), aPos);
+ aCompiler.SetNumberFormatter(&rFormatter);
+ aCompiler.SetGrammar(formula::FormulaGrammar::GRAM_ENGLISH_XL_OOX);
+ ScTokenArray* pCode = aCompiler.CompileString(it->maTokenStr);
+ if (!pCode)
+ continue;
+
+ rDoc.setFormulaCell(aPos, pCode);
+ }
+}
+
+void applyArrayFormulas(
+ ScDocumentImport& rDoc, SvNumberFormatter& rFormatter,
+ const std::vector<FormulaBuffer::TokenRangeAddressItem>& rArrays )
+{
+ std::vector<FormulaBuffer::TokenRangeAddressItem>::const_iterator it = rArrays.begin(), itEnd = rArrays.end();
for (; it != itEnd; ++it)
{
ScAddress aPos;
@@ -205,12 +136,185 @@ void FormulaBuffer::applyArrayFormulas( const std::vector< TokenRangeAddressItem
ScRange aRange;
ScUnoConversion::FillScRange(aRange, it->maCellRangeAddress);
- ScCompiler aComp(&rDocImport.getDoc(), aPos);
+ ScCompiler aComp(&rDoc.getDoc(), aPos);
+ aComp.SetNumberFormatter(&rFormatter);
aComp.SetGrammar(formula::FormulaGrammar::GRAM_ENGLISH_XL_OOX);
boost::scoped_ptr<ScTokenArray> pArray(aComp.CompileString(it->maTokenAndAddress.maTokenStr));
if (pArray)
- rDocImport.setMatrixCells(aRange, *pArray, formula::FormulaGrammar::GRAM_ENGLISH_XL_OOX);
+ rDoc.setMatrixCells(aRange, *pArray, formula::FormulaGrammar::GRAM_ENGLISH_XL_OOX);
+ }
+}
+
+void applyCellFormulaValues(
+ ScDocumentImport& rDoc, const std::vector<FormulaBuffer::ValueAddressPair>& rVector )
+{
+ std::vector<FormulaBuffer::ValueAddressPair>::const_iterator it = rVector.begin(), itEnd = rVector.end();
+ for (; it != itEnd; ++it)
+ {
+ ScAddress aCellPos;
+ ScUnoConversion::FillScAddress(aCellPos, it->first);
+ ScFormulaCell* pCell = rDoc.getDoc().GetFormulaCell(aCellPos);
+ if (pCell)
+ {
+ pCell->SetHybridDouble(it->second);
+ pCell->ResetDirty();
+ pCell->SetChanged(false);
+ }
+ }
+}
+
+class WorkerThread : public salhelper::Thread
+{
+ ScDocumentImport& mrDoc;
+ FormulaBuffer::SheetItem& mrItem;
+ boost::scoped_ptr<SvNumberFormatter> mpFormatter;
+
+ WorkerThread( const WorkerThread& );
+ WorkerThread& operator= ( const WorkerThread& );
+
+public:
+ WorkerThread( ScDocumentImport& rDoc, FormulaBuffer::SheetItem& rItem, SvNumberFormatter* pFormatter ) :
+ salhelper::Thread("xlsx-import-formula-buffer-worker-thread"),
+ mrDoc(rDoc), mrItem(rItem), mpFormatter(pFormatter) {}
+
+ virtual ~WorkerThread() {}
+
+protected:
+ virtual void execute()
+ {
+ if (mrItem.mpSharedFormulaEntries && mrItem.mpSharedFormulaIDs)
+ applySharedFormulas(mrDoc, *mpFormatter, *mrItem.mpSharedFormulaEntries, *mrItem.mpSharedFormulaIDs);
+
+ if (mrItem.mpCellFormulas)
+ applyCellFormulas(mrDoc, *mpFormatter, *mrItem.mpCellFormulas);
+
+ if (mrItem.mpArrayFormulas)
+ applyArrayFormulas(mrDoc, *mpFormatter, *mrItem.mpArrayFormulas);
+
+ if (mrItem.mpCellFormulaValues)
+ applyCellFormulaValues(mrDoc, *mrItem.mpCellFormulaValues);
+ }
+};
+
+}
+
+FormulaBuffer::SharedFormulaEntry::SharedFormulaEntry(
+ const table::CellAddress& rAddr, const table::CellRangeAddress& rRange,
+ const OUString& rTokenStr, sal_Int32 nSharedId ) :
+ maAddress(rAddr), maRange(rRange), maTokenStr(rTokenStr), mnSharedId(nSharedId) {}
+
+FormulaBuffer::SharedFormulaDesc::SharedFormulaDesc(
+ const com::sun::star::table::CellAddress& rAddr, sal_Int32 nSharedId,
+ const OUString& rCellValue, sal_Int32 nValueType ) :
+ maAddress(rAddr), mnSharedId(nSharedId), maCellValue(rCellValue), mnValueType(nValueType) {}
+
+FormulaBuffer::SheetItem::SheetItem() :
+ mpCellFormulas(NULL),
+ mpArrayFormulas(NULL),
+ mpCellFormulaValues(NULL),
+ mpSharedFormulaEntries(NULL),
+ mpSharedFormulaIDs(NULL) {}
+
+FormulaBuffer::FinalizeThread::FinalizeThread( FormulaBuffer& rParent, size_t nThreadCount ) :
+ salhelper::Thread("xlsx-import-formula-buffer-finalize-thread"),
+ mrParent(rParent), mnThreadCount(nThreadCount) {}
+
+FormulaBuffer::FinalizeThread::~FinalizeThread() {}
+
+void FormulaBuffer::FinalizeThread::execute()
+{
+ ScDocumentImport& rDoc = mrParent.getDocImport();
+ rDoc.getDoc().SetAutoNameCache(new ScAutoNameCache(&rDoc.getDoc()));
+ SCTAB nTabCount = rDoc.getDoc().GetTableCount();
+
+ std::vector<SheetItem> aSheetItems;
+ aSheetItems.reserve(nTabCount);
+ for (SCTAB nTab = 0; nTab < nTabCount; ++nTab)
+ aSheetItems.push_back(mrParent.getSheetItem(nTab));
+
+ typedef rtl::Reference<WorkerThread> WorkerThreadRef;
+ std::vector<WorkerThreadRef> aThreads;
+ aThreads.reserve(mnThreadCount);
+
+ std::vector<SheetItem>::iterator it = aSheetItems.begin(), itEnd = aSheetItems.end();
+
+ while (it != itEnd)
+ {
+ for (size_t i = 0; i < mnThreadCount; ++i)
+ {
+ if (it == itEnd)
+ break;
+
+ WorkerThreadRef xThread(new WorkerThread(rDoc, *it, rDoc.getDoc().CreateFormatTable()));
+ ++it;
+ aThreads.push_back(xThread);
+ xThread->launch();
+ }
+
+ for (size_t i = 0, n = aThreads.size(); i < n; ++i)
+ {
+ if (aThreads[i].is())
+ aThreads[i]->join();
+ }
+
+ aThreads.clear();
+ }
+
+ rDoc.getDoc().SetAutoNameCache(NULL);
+}
+
+FormulaBuffer::FormulaBuffer( const WorkbookHelper& rHelper ) : WorkbookHelper( rHelper )
+{
+}
+
+void FormulaBuffer::finalizeImport()
+{
+ ISegmentProgressBarRef xFormulaBar = getProgressBar().createSegment( getProgressBar().getFreeLength() );
+
+ rtl::Reference<FinalizeThread> xThreadMgr(new FinalizeThread(*this, 1));
+ xThreadMgr->launch();
+
+ if (xThreadMgr.is())
+ xThreadMgr->join();
+
+ xFormulaBar->setPosition( 1.0 );
+}
+
+FormulaBuffer::SheetItem FormulaBuffer::getSheetItem( SCTAB nTab )
+{
+ osl::MutexGuard aGuard(&maMtxData);
+
+ SheetItem aItem;
+ {
+ FormulaDataMap::iterator it = maCellFormulas.find(nTab);
+ if (it != maCellFormulas.end())
+ aItem.mpCellFormulas = &it->second;
+ }
+
+ {
+ ArrayFormulaDataMap::iterator it = maCellArrayFormulas.find(nTab);
+ if (it != maCellArrayFormulas.end())
+ aItem.mpArrayFormulas = &it->second;
+ }
+
+ {
+ FormulaValueMap::iterator it = maCellFormulaValues.find(nTab);
+ if (it != maCellFormulaValues.end())
+ aItem.mpCellFormulaValues = &it->second;
+ }
+
+ {
+ SheetToFormulaEntryMap::iterator it = maSharedFormulas.find(nTab);
+ if (it != maSharedFormulas.end())
+ aItem.mpSharedFormulaEntries = &it->second;
+ }
+
+ {
+ SheetToSharedFormulaid::iterator it = maSharedFormulaIds.find(nTab);
+ if (it != maSharedFormulaIds.end())
+ aItem.mpSharedFormulaIDs = &it->second;
}
+ return aItem;
}
void FormulaBuffer::createSharedFormulaMapEntry(
commit 1cefb146a878080ff8609c9af21c1e494af1245b
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date: Wed Nov 6 18:43:47 2013 -0500
Allow instantiation of more than one SvNumberFormatter from the document.
Change-Id: Ide6875e031268337bf6a21286176a38905c12691
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index 6929e9b..09f1466 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -1621,6 +1621,7 @@ public:
const ScMarkData* pMarkData = NULL );
SC_DLLPUBLIC SvNumberFormatter* GetFormatTable() const;
+ SC_DLLPUBLIC SvNumberFormatter* CreateFormatTable() const;
void Sort( SCTAB nTab, const ScSortParam& rSortParam, bool bKeepQuery, ScProgress* pProgress );
SCSIZE Query( SCTAB nTab, const ScQueryParam& rQueryParam, bool bKeepSub );
diff --git a/sc/source/core/data/documen2.cxx b/sc/source/core/data/documen2.cxx
index 1e0bb87..23a4bcf 100644
--- a/sc/source/core/data/documen2.cxx
+++ b/sc/source/core/data/documen2.cxx
@@ -491,6 +491,11 @@ SvNumberFormatter* ScDocument::GetFormatTable() const
return xPoolHelper->GetFormTable();
}
+SvNumberFormatter* ScDocument::CreateFormatTable() const
+{
+ return xPoolHelper->CreateNumberFormatter();
+}
+
SfxItemPool* ScDocument::GetEditPool() const
{
return xPoolHelper->GetEditPool();
diff --git a/sc/source/core/data/poolhelp.cxx b/sc/source/core/data/poolhelp.cxx
index b6f027a..74d5cbe 100644
--- a/sc/source/core/data/poolhelp.cxx
+++ b/sc/source/core/data/poolhelp.cxx
@@ -71,14 +71,8 @@ SfxItemPool* ScPoolHelper::GetEnginePool() const
}
SvNumberFormatter* ScPoolHelper::GetFormTable() const
{
- if ( !pFormTable )
- {
- pFormTable = new SvNumberFormatter( comphelper::getProcessComponentContext(), ScGlobal::eLnge );
- pFormTable->SetColorLink( LINK( m_pSourceDoc, ScDocument, GetUserDefinedColor ) );
- pFormTable->SetEvalDateFormat( NF_EVALDATEFORMAT_INTL_FORMAT );
-
- UseDocOptions(); // null date, year2000, std precision
- }
+ if (!pFormTable)
+ pFormTable = CreateNumberFormatter();
return pFormTable;
}
@@ -100,6 +94,24 @@ void ScPoolHelper::SetFormTableOpt(const ScDocOptions& rOpt)
UseDocOptions(); // #i105512# if the number formatter exists, update its settings
}
+SvNumberFormatter* ScPoolHelper::CreateNumberFormatter() const
+{
+ SvNumberFormatter* p = NULL;
+ {
+ osl::MutexGuard aGuard(&maMtxCreateNumFormatter);
+ p = new SvNumberFormatter(comphelper::getProcessComponentContext(), ScGlobal::eLnge);
+ }
+ p->SetColorLink( LINK(m_pSourceDoc, ScDocument, GetUserDefinedColor) );
+ p->SetEvalDateFormat(NF_EVALDATEFORMAT_INTL_FORMAT);
+
+ sal_uInt16 d,m,y;
+ aOpt.GetDate(d, m, y);
+ p->ChangeNullDate(d, m, y);
+ p->ChangeStandardPrec(aOpt.GetStdPrecision());
+ p->SetYear2000(aOpt.GetYear2000());
+ return p;
+}
+
void ScPoolHelper::SourceDocumentGone()
{
// reset all pointers to the source document
diff --git a/sc/source/core/inc/poolhelp.hxx b/sc/source/core/inc/poolhelp.hxx
index 6eaa0a9..c60bd1b 100644
--- a/sc/source/core/inc/poolhelp.hxx
+++ b/sc/source/core/inc/poolhelp.hxx
@@ -23,6 +23,7 @@
#include <rtl/ref.hxx>
#include <salhelper/simplereferenceobject.hxx>
#include "docoptio.hxx"
+#include "osl/mutex.hxx"
class ScDocument;
class ScDocumentPool;
@@ -34,6 +35,7 @@ class SfxItemPool;
class ScPoolHelper : public salhelper::SimpleReferenceObject
{
private:
+ mutable osl::Mutex maMtxCreateNumFormatter;
ScDocOptions aOpt;
ScDocumentPool* pDocPool;
rtl::Reference< ScStyleSheetPool > mxStylePool;
@@ -59,6 +61,8 @@ public:
SfxItemPool* GetEnginePool() const;
void SetFormTableOpt(const ScDocOptions& rOpt);
+
+ SvNumberFormatter* CreateNumberFormatter() const;
};
#endif
commit db9a73d51823a0c8392cc426da8f96ff69209832
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date: Wed Nov 6 18:41:18 2013 -0500
Allow non-pooled instance of SvNumberFormatter inside ScCompiler.
Change-Id: I645079254621c2f2684a69116b094e37e46f46f4
diff --git a/sc/inc/compiler.hxx b/sc/inc/compiler.hxx
index c16f749..0cd47c5 100644
--- a/sc/inc/compiler.hxx
+++ b/sc/inc/compiler.hxx
@@ -312,6 +312,8 @@ private:
ScDocument* pDoc;
ScAddress aPos;
+ SvNumberFormatter* mpFormatter;
+
// For CONV_XL_OOX, may be set via API by MOOXML filter.
::com::sun::star::uno::Sequence< const ::com::sun::star::sheet::ExternalLinkInfo > maExternalLinks;
@@ -400,6 +402,7 @@ public:
void SetGrammar( const formula::FormulaGrammar::Grammar eGrammar );
+ void SetNumberFormatter( SvNumberFormatter* pFormatter );
EncodeUrlMode GetEncodeUrlMode() const;
private:
/** Set grammar and reference convention from within SetFormulaLanguage()
diff --git a/sc/source/core/tool/compiler.cxx b/sc/source/core/tool/compiler.cxx
index 6b6d011..9b77a7d 100644
--- a/sc/source/core/tool/compiler.cxx
+++ b/sc/source/core/tool/compiler.cxx
@@ -239,6 +239,11 @@ void ScCompiler::SetGrammar( const FormulaGrammar::Grammar eGrammar )
}
}
+void ScCompiler::SetNumberFormatter( SvNumberFormatter* pFormatter )
+{
+ mpFormatter = pFormatter;
+}
+
ScCompiler::EncodeUrlMode ScCompiler::GetEncodeUrlMode() const
{
return meEncodeUrlMode;
@@ -1640,6 +1645,7 @@ ScCompiler::ScCompiler( ScDocument* pDocument, const ScAddress& rPos,ScTokenArra
: FormulaCompiler(rArr),
pDoc( pDocument ),
aPos( rPos ),
+ mpFormatter(pDoc->GetFormatTable()),
pCharClass( ScGlobal::pCharClass ),
mnPredetectedReference(0),
mnRangeOpPosInSymbol(-1),
@@ -1656,6 +1662,7 @@ ScCompiler::ScCompiler( ScDocument* pDocument, const ScAddress& rPos)
:
pDoc( pDocument ),
aPos( rPos ),
+ mpFormatter(pDoc->GetFormatTable()),
pCharClass( ScGlobal::pCharClass ),
mnPredetectedReference(0),
mnRangeOpPosInSymbol(-1),
@@ -2517,40 +2524,37 @@ bool ScCompiler::IsOpCode2( const OUString& rName )
bool ScCompiler::IsValue( const OUString& rSym )
{
double fVal;
- sal_uInt32 nIndex = ( mxSymbols->isEnglish() ?
- pDoc->GetFormatTable()->GetStandardIndex( LANGUAGE_ENGLISH_US ) : 0 );
+ sal_uInt32 nIndex = mxSymbols->isEnglish() ? mpFormatter->GetStandardIndex(LANGUAGE_ENGLISH_US) : 0;
- if (pDoc->GetFormatTable()->IsNumberFormat( rSym, nIndex, fVal ) )
- {
- sal_uInt16 nType = pDoc->GetFormatTable()->GetType(nIndex);
+ if (!mpFormatter->IsNumberFormat(rSym, nIndex, fVal))
+ return false;
- // Don't accept 3:3 as time, it is a reference to entire row 3 instead.
- // Dates should never be entered directly and automatically converted
- // to serial, because the serial would be wrong if null-date changed.
- // Usually it wouldn't be accepted anyway because the date separator
- // clashed with other separators or operators.
- if (nType & (NUMBERFORMAT_TIME | NUMBERFORMAT_DATE))
- return false;
+ sal_uInt16 nType = mpFormatter->GetType(nIndex);
- if (nType == NUMBERFORMAT_LOGICAL)
- {
- const sal_Unicode* p = aFormula.getStr() + nSrcPos;
- while( *p == ' ' )
- p++;
- if (*p == '(')
- return false; // Boolean function instead.
- }
+ // Don't accept 3:3 as time, it is a reference to entire row 3 instead.
+ // Dates should never be entered directly and automatically converted
+ // to serial, because the serial would be wrong if null-date changed.
+ // Usually it wouldn't be accepted anyway because the date separator
+ // clashed with other separators or operators.
+ if (nType & (NUMBERFORMAT_TIME | NUMBERFORMAT_DATE))
+ return false;
- if( nType == NUMBERFORMAT_TEXT )
- // HACK: number too big!
- SetError( errIllegalArgument );
- ScRawToken aToken;
- aToken.SetDouble( fVal );
- pRawToken = aToken.Clone();
- return true;
+ if (nType == NUMBERFORMAT_LOGICAL)
+ {
+ const sal_Unicode* p = aFormula.getStr() + nSrcPos;
+ while( *p == ' ' )
+ p++;
+ if (*p == '(')
+ return false; // Boolean function instead.
}
- else
- return false;
+
+ if( nType == NUMBERFORMAT_TEXT )
+ // HACK: number too big!
+ SetError( errIllegalArgument );
+ ScRawToken aToken;
+ aToken.SetDouble( fVal );
+ pRawToken = aToken.Clone();
+ return true;
}
bool ScCompiler::IsString()
commit 4efc5fa37681e1e0ff3cfffab8a4ea33f24b5ba0
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date: Wed Nov 6 18:34:18 2013 -0500
Protect those global symbols containers with mutex during initialization.
Change-Id: Id15b3e1a2bfebd2ea795fd412a259f125f5d9bab
diff --git a/formula/source/core/api/FormulaCompiler.cxx b/formula/source/core/api/FormulaCompiler.cxx
index fda54bd..804fb03 100644
--- a/formula/source/core/api/FormulaCompiler.cxx
+++ b/formula/source/core/api/FormulaCompiler.cxx
@@ -24,6 +24,8 @@
#include "core_resource.hxx"
#include "core_resource.hrc"
+#include "osl/mutex.hxx"
+
#include <svl/zforlist.hxx>
#include <tools/rc.hxx>
#include <tools/rcid.h>
@@ -39,8 +41,7 @@ namespace formula
static const sal_Char* pInternal[ 1 ] = { "TTT" };
-namespace
-{
+namespace {
class FormulaCompilerRecursionGuard
{
@@ -248,6 +249,13 @@ const sal_Unicode* lcl_UnicodeStrChr( const sal_Unicode* pStr, sal_Unicode c )
return NULL;
}
+struct OpCodeMapData
+{
+ FormulaCompiler::NonConstOpCodeMapPtr mxSymbolMap;
+ osl::Mutex maMtx;
+};
+
+
} // namespace
@@ -625,21 +633,25 @@ FormulaCompiler::OpCodeMapPtr FormulaCompiler::CreateOpCodeMap(
void lcl_fillNativeSymbols( FormulaCompiler::NonConstOpCodeMapPtr& xMap, bool bDestroy = false )
{
- static FormulaCompiler::NonConstOpCodeMapPtr s_SymbolMap;
+ static OpCodeMapData aSymbolMap;
+ osl::MutexGuard aGuard(&aSymbolMap.maMtx);
+
if ( bDestroy )
{
- s_SymbolMap.reset();
+ aSymbolMap.mxSymbolMap.reset();
}
- else if ( !s_SymbolMap.get() )
+ else if (!aSymbolMap.mxSymbolMap)
{
// Core
- s_SymbolMap.reset( new FormulaCompiler::OpCodeMap( SC_OPCODE_LAST_OPCODE_ID + 1, true,
- FormulaGrammar::GRAM_NATIVE_UI));
+ aSymbolMap.mxSymbolMap.reset(
+ new FormulaCompiler::OpCodeMap(
+ SC_OPCODE_LAST_OPCODE_ID + 1, true, FormulaGrammar::GRAM_NATIVE_UI));
OModuleClient aModuleClient;
- OpCodeList aOpCodeListNative( RID_STRLIST_FUNCTION_NAMES, s_SymbolMap );
+ OpCodeList aOpCodeListNative(RID_STRLIST_FUNCTION_NAMES, aSymbolMap.mxSymbolMap);
// No AddInMap for native core mapping.
}
- xMap = s_SymbolMap;
+
+ xMap = aSymbolMap.mxSymbolMap;
}
const OUString& FormulaCompiler::GetNativeSymbol( OpCode eOp )
@@ -661,34 +673,38 @@ void FormulaCompiler::InitSymbolsNative() const
void FormulaCompiler::InitSymbolsEnglish() const
{
- static NonConstOpCodeMapPtr s_sSymbol;
- if ( !s_sSymbol.get() )
- loadSymbols( RID_STRLIST_FUNCTION_NAMES_ENGLISH, FormulaGrammar::GRAM_ENGLISH, s_sSymbol);
- mxSymbolsEnglish = s_sSymbol;
+ static OpCodeMapData aMap;
+ osl::MutexGuard aGuard(&aMap.maMtx);
+ if (!aMap.mxSymbolMap)
+ loadSymbols(RID_STRLIST_FUNCTION_NAMES_ENGLISH, FormulaGrammar::GRAM_ENGLISH, aMap.mxSymbolMap);
+ mxSymbolsEnglish = aMap.mxSymbolMap;
}
void FormulaCompiler::InitSymbolsPODF() const
{
- static NonConstOpCodeMapPtr s_sSymbol;
- if ( !s_sSymbol.get() )
- loadSymbols( RID_STRLIST_FUNCTION_NAMES_ENGLISH, FormulaGrammar::GRAM_PODF, s_sSymbol);
- mxSymbolsPODF = s_sSymbol;
+ static OpCodeMapData aMap;
+ osl::MutexGuard aGuard(&aMap.maMtx);
+ if (!aMap.mxSymbolMap)
+ loadSymbols(RID_STRLIST_FUNCTION_NAMES_ENGLISH, FormulaGrammar::GRAM_PODF, aMap.mxSymbolMap);
+ mxSymbolsPODF = aMap.mxSymbolMap;
}
void FormulaCompiler::InitSymbolsODFF() const
{
- static NonConstOpCodeMapPtr s_sSymbol;
- if ( !s_sSymbol.get() )
- loadSymbols( RID_STRLIST_FUNCTION_NAMES_ENGLISH_ODFF, FormulaGrammar::GRAM_ODFF, s_sSymbol);
- mxSymbolsODFF = s_sSymbol;
+ static OpCodeMapData aMap;
+ osl::MutexGuard aGuard(&aMap.maMtx);
+ if (!aMap.mxSymbolMap)
+ loadSymbols(RID_STRLIST_FUNCTION_NAMES_ENGLISH_ODFF, FormulaGrammar::GRAM_ODFF, aMap.mxSymbolMap);
+ mxSymbolsODFF = aMap.mxSymbolMap;
}
void FormulaCompiler::InitSymbolsEnglishXL() const
{
- static NonConstOpCodeMapPtr s_sSymbol;
- if ( !s_sSymbol.get() )
- loadSymbols( RID_STRLIST_FUNCTION_NAMES_ENGLISH, FormulaGrammar::GRAM_ENGLISH, s_sSymbol);
- mxSymbolsEnglishXL = s_sSymbol;
+ static OpCodeMapData aMap;
+ osl::MutexGuard aGuard(&aMap.maMtx);
+ if (!aMap.mxSymbolMap)
+ loadSymbols(RID_STRLIST_FUNCTION_NAMES_ENGLISH, FormulaGrammar::GRAM_ENGLISH, aMap.mxSymbolMap);
+ mxSymbolsEnglishXL = aMap.mxSymbolMap;
// TODO: For now, just replace the separators to the Excel English
// variants. Later, if we want to properly map Excel functions with Calc
commit 88357ee6f4f0b6c42b2b07eae3cbe59d62075896
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date: Wed Nov 6 14:55:41 2013 -0500
Make TransformInput() a non-member function.
Change-Id: Ieb077b6ce661e2885d6010519f137235a048f9df
diff --git a/svl/source/numbers/zforfind.cxx b/svl/source/numbers/zforfind.cxx
index 9cd3362..3726c33 100644
--- a/svl/source/numbers/zforfind.cxx
+++ b/svl/source/numbers/zforfind.cxx
@@ -147,8 +147,8 @@ inline bool ImpSvNumberInputScan::MyIsdigit( sal_Unicode c )
return c < 128 && isdigit( (unsigned char) c );
}
-
-void ImpSvNumberInputScan::TransformInput( OUString& rStr )
+// native number transliteration if necessary
+void TransformInput( SvNumberFormatter* pFormatter, OUString& rStr )
{
sal_Int32 nPos, nLen;
for ( nPos = 0, nLen = rStr.getLength(); nPos < nLen; ++nPos )
@@ -3271,7 +3271,7 @@ bool ImpSvNumberInputScan::IsNumberFormat( const OUString& rString, // s
// NoMoreUpperNeeded, all comparisons on UpperCase
aString = pFormatter->GetCharClass()->uppercase( rString );
// convert native number to ASCII if necessary
- TransformInput( aString );
+ TransformInput(pFormatter, aString);
res = IsNumberFormatMain( aString, pFormat );
}
diff --git a/svl/source/numbers/zforfind.hxx b/svl/source/numbers/zforfind.hxx
index 4c070a1..6e24040 100644
--- a/svl/source/numbers/zforfind.hxx
+++ b/svl/source/numbers/zforfind.hxx
@@ -362,9 +362,6 @@ private:
static inline bool MyIsdigit( sal_Unicode c );
- // native number transliteration if necessary
- void TransformInput( OUString& rString );
-
/** Whether input matches locale dependent date acceptance pattern.
@param nStartPatternAt
commit 35a5999247bbb120dc677515d199b7da3c39146f
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date: Tue Nov 5 19:06:15 2013 -0500
Guard cache access with mutex & a new method just to check for range name.
Change-Id: Id24b5ba72362f9d878b4878c1e807bed3e596b20
diff --git a/sc/inc/externalrefmgr.hxx b/sc/inc/externalrefmgr.hxx
index 6156abb..b3d35f9 100644
--- a/sc/inc/externalrefmgr.hxx
+++ b/sc/inc/externalrefmgr.hxx
@@ -233,6 +233,7 @@ public:
ScExternalRefCache::TokenArrayRef getRangeNameTokens(sal_uInt16 nFileId, const OUString& rName);
void setRangeNameTokens(sal_uInt16 nFileId, const OUString& rName, TokenArrayRef pArray);
+ bool isValidRangeName(sal_uInt16 nFileId, const OUString& rName) const;
void setCellData(sal_uInt16 nFileId, const OUString& rTabName,
SCCOL nCol, SCROW nRow, TokenRef pToken, sal_uLong nFmtIndex);
@@ -557,6 +558,8 @@ public:
ScExternalRefCache::TokenArrayRef getRangeNameTokens(
sal_uInt16 nFileId, const OUString& rName, const ScAddress* pCurPos = NULL);
+ bool isValidRangeName(sal_uInt16 nFileId, const OUString& rName);
+
OUString getOwnDocumentName() const;
bool isOwnDocument(const OUString& rFile) const;
@@ -765,6 +768,12 @@ private:
private:
ScDocument* mpDoc;
+ /** Mutex for accessing cached data and/or source document shells. */
+ mutable osl::Mutex maMtxCacheAccess;
+
+ /** Mutex for source document meta-data access. */
+ mutable osl::Mutex maMtxSrcFiles;
+
/** cache of referenced ranges and names from source documents. */
ScExternalRefCache maRefCache;
@@ -798,7 +807,6 @@ private:
* external document identifiers.
*/
std::vector<SrcFileData> maSrcFiles;
- mutable osl::Mutex maMtxSrcFiles;
/** Status whether in reference marking state. See isInReferenceMarking(). */
bool mbInReferenceMarking:1;
diff --git a/sc/source/core/tool/compiler.cxx b/sc/source/core/tool/compiler.cxx
index 62bf259..6b6d011 100644
--- a/sc/source/core/tool/compiler.cxx
+++ b/sc/source/core/tool/compiler.cxx
@@ -2914,7 +2914,7 @@ bool ScCompiler::IsExternalNamedRange( const OUString& rSymbol )
pRefMgr->convertToAbsName(aTmp);
aFile = aTmp;
sal_uInt16 nFileId = pRefMgr->getExternalFileId(aFile);
- if (!pRefMgr->getRangeNameTokens(nFileId, aName).get())
+ if (!pRefMgr->isValidRangeName(nFileId, aName))
// range name doesn't exist in the source document.
return false;
diff --git a/sc/source/ui/docshell/externalrefmgr.cxx b/sc/source/ui/docshell/externalrefmgr.cxx
index 1561cbb..9c07fd7 100644
--- a/sc/source/ui/docshell/externalrefmgr.cxx
+++ b/sc/source/ui/docshell/externalrefmgr.cxx
@@ -710,6 +710,18 @@ void ScExternalRefCache::setRangeNameTokens(sal_uInt16 nFileId, const OUString&
pDoc->maRealRangeNameMap.insert(NamePairMap::value_type(aUpperName, rName));
}
+bool ScExternalRefCache::isValidRangeName(sal_uInt16 nFileId, const OUString& rName) const
+{
+ osl::MutexGuard aGuard(&maMtxDocs);
+
+ DocItem* pDoc = getDocItem(nFileId);
+ if (!pDoc)
+ return false;
+
+ const RangeNameMap& rMap = pDoc->maRangeNames;
+ return rMap.count(rName) > 0;
+}
+
void ScExternalRefCache::setCellData(sal_uInt16 nFileId, const OUString& rTabName, SCCOL nCol, SCROW nRow,
TokenRef pToken, sal_uLong nFmtIndex)
{
@@ -1747,6 +1759,8 @@ ScExternalRefCache::TokenRef ScExternalRefManager::getSingleRefToken(
sal_uInt16 nFileId, const OUString& rTabName, const ScAddress& rCell,
const ScAddress* pCurPos, SCTAB* pTab, ScExternalRefCache::CellFormat* pFmt)
{
+ osl::MutexGuard aGuard(&maMtxCacheAccess);
+
if (pCurPos)
insertRefCell(nFileId, *pCurPos);
@@ -1839,6 +1853,8 @@ ScExternalRefCache::TokenRef ScExternalRefManager::getSingleRefToken(
ScExternalRefCache::TokenArrayRef ScExternalRefManager::getDoubleRefTokens(
sal_uInt16 nFileId, const OUString& rTabName, const ScRange& rRange, const ScAddress* pCurPos)
{
+ osl::MutexGuard aGuard(&maMtxCacheAccess);
+
if (pCurPos)
insertRefCell(nFileId, *pCurPos);
@@ -1885,6 +1901,8 @@ ScExternalRefCache::TokenArrayRef ScExternalRefManager::getDoubleRefTokens(
ScExternalRefCache::TokenArrayRef ScExternalRefManager::getRangeNameTokens(
sal_uInt16 nFileId, const OUString& rName, const ScAddress* pCurPos)
{
+ osl::MutexGuard aGuard(&maMtxCacheAccess);
+
if (pCurPos)
insertRefCell(nFileId, *pCurPos);
@@ -1924,6 +1942,42 @@ ScExternalRefCache::TokenArrayRef ScExternalRefManager::getRangeNameTokens(
return pArray;
}
+namespace {
+
+bool hasRangeName(ScDocument& rDoc, const OUString& rName)
+{
+ ScRangeName* pExtNames = rDoc.GetRangeName();
+ OUString aUpperName = ScGlobal::pCharClass->uppercase(rName);
+ const ScRangeData* pRangeData = pExtNames->findByUpperName(aUpperName);
+ return pRangeData != NULL;
+}
+
+}
+
+bool ScExternalRefManager::isValidRangeName(sal_uInt16 nFileId, const OUString& rName)
+{
+ osl::MutexGuard aGuard(&maMtxCacheAccess);
+
+ maybeLinkExternalFile(nFileId);
+ ScDocument* pSrcDoc = getInMemorySrcDocument(nFileId);
+ if (pSrcDoc)
+ {
+ // Only check the presence of the name.
+ return hasRangeName(*pSrcDoc, rName);
+ }
+
+ if (maRefCache.isValidRangeName(nFileId, rName))
+ // Range name is cached.
+ return true;
+
+ pSrcDoc = getSrcDocument(nFileId);
+ if (!pSrcDoc)
+ // failed to load document from disk.
+ return false;
+
+ return hasRangeName(*pSrcDoc, rName);
+}
+
void ScExternalRefManager::refreshAllRefCells(sal_uInt16 nFileId)
{
RefCellMap::iterator itrFile = maRefCells.find(nFileId);
commit 719c3fb46bb38c69daea617ea9aaafc72505684d
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date: Tue Nov 5 17:10:24 2013 -0500
Add mutex for external source document meta-data container.
These get updated from reference parser code (ScAddress, ScRange etc)
which may be run from multiple threads.
Change-Id: I5a1aaa4b51d9b9fb032458eb5e89f0652887184e
diff --git a/sc/inc/externalrefmgr.hxx b/sc/inc/externalrefmgr.hxx
index c5a73ae..6156abb 100644
--- a/sc/inc/externalrefmgr.hxx
+++ b/sc/inc/externalrefmgr.hxx
@@ -793,8 +793,12 @@ private:
NumFmtMap maNumFormatMap;
- /** original source file index. */
- ::std::vector<SrcFileData> maSrcFiles;
+ /**
+ * List of external source document meta-data, used to keep track of
+ * external document identifiers.
+ */
+ std::vector<SrcFileData> maSrcFiles;
+ mutable osl::Mutex maMtxSrcFiles;
/** Status whether in reference marking state. See isInReferenceMarking(). */
bool mbInReferenceMarking:1;
diff --git a/sc/source/ui/docshell/externalrefmgr.cxx b/sc/source/ui/docshell/externalrefmgr.cxx
index f7d026b..1561cbb 100644
--- a/sc/source/ui/docshell/externalrefmgr.cxx
+++ b/sc/source/ui/docshell/externalrefmgr.cxx
@@ -1594,6 +1594,7 @@ void ScExternalRefManager::getAllCachedNumberFormats(vector<sal_uInt32>& rNumFmt
sal_uInt16 ScExternalRefManager::getExternalFileCount() const
{
+ osl::MutexGuard aGuard(&maMtxSrcFiles);
return static_cast< sal_uInt16 >( maSrcFiles.size() );
}
@@ -2360,6 +2361,7 @@ void ScExternalRefManager::SrcFileData::maybeCreateRealFileName(const OUString&
void ScExternalRefManager::maybeCreateRealFileName(sal_uInt16 nFileId)
{
+ osl::MutexGuard aGuard(&maMtxSrcFiles);
if (nFileId >= maSrcFiles.size())
return;
@@ -2404,6 +2406,8 @@ void ScExternalRefManager::convertToAbsName(OUString& rFile) const
sal_uInt16 ScExternalRefManager::getExternalFileId(const OUString& rFile)
{
+ osl::MutexGuard aGuard(&maMtxSrcFiles);
+
vector<SrcFileData>::const_iterator itrBeg = maSrcFiles.begin(), itrEnd = maSrcFiles.end();
vector<SrcFileData>::const_iterator itr = find_if(itrBeg, itrEnd, FindSrcFileByName(rFile));
if (itr != itrEnd)
@@ -2420,6 +2424,8 @@ sal_uInt16 ScExternalRefManager::getExternalFileId(const OUString& rFile)
const OUString* ScExternalRefManager::getExternalFileName(sal_uInt16 nFileId, bool bForceOriginal)
{
+ osl::MutexGuard aGuard(&maMtxSrcFiles);
+
if (nFileId >= maSrcFiles.size())
return NULL;
@@ -2436,11 +2442,14 @@ const OUString* ScExternalRefManager::getExternalFileName(sal_uInt16 nFileId, bo
bool ScExternalRefManager::hasExternalFile(sal_uInt16 nFileId) const
{
+ osl::MutexGuard aGuard(&maMtxSrcFiles);
return nFileId < maSrcFiles.size();
}
bool ScExternalRefManager::hasExternalFile(const OUString& rFile) const
{
+ osl::MutexGuard aGuard(&maMtxSrcFiles);
+
vector<SrcFileData>::const_iterator itrBeg = maSrcFiles.begin(), itrEnd = maSrcFiles.end();
vector<SrcFileData>::const_iterator itr = find_if(itrBeg, itrEnd, FindSrcFileByName(rFile));
return itr != itrEnd;
@@ -2539,6 +2548,8 @@ void ScExternalRefManager::breakLink(sal_uInt16 nFileId)
void ScExternalRefManager::switchSrcFile(sal_uInt16 nFileId, const OUString& rNewFile, const OUString& rNewFilter)
{
+ osl::MutexGuard aGuard(&maMtxSrcFiles);
+
maSrcFiles[nFileId].maFileName = rNewFile;
maSrcFiles[nFileId].maRelativeName = OUString();
maSrcFiles[nFileId].maRealFileName = OUString();
@@ -2553,6 +2564,8 @@ void ScExternalRefManager::switchSrcFile(sal_uInt16 nFileId, const OUString& rNe
void ScExternalRefManager::setRelativeFileName(sal_uInt16 nFileId, const OUString& rRelUrl)
{
+ osl::MutexGuard aGuard(&maMtxSrcFiles);
+
if (nFileId >= maSrcFiles.size())
return;
maSrcFiles[nFileId].maRelativeName = rRelUrl;
@@ -2560,6 +2573,8 @@ void ScExternalRefManager::setRelativeFileName(sal_uInt16 nFileId, const OUStrin
void ScExternalRefManager::setFilterData(sal_uInt16 nFileId, const OUString& rFilterName, const OUString& rOptions)
{
+ osl::MutexGuard aGuard(&maMtxSrcFiles);
+
if (nFileId >= maSrcFiles.size())
return;
maSrcFiles[nFileId].maFilterName = rFilterName;
@@ -2578,11 +2593,13 @@ void ScExternalRefManager::clear()
bool ScExternalRefManager::hasExternalData() const
{
+ osl::MutexGuard aGuard(&maMtxSrcFiles);
return !maSrcFiles.empty();
}
void ScExternalRefManager::resetSrcFileData(const OUString& rBaseFileUrl)
{
+ osl::MutexGuard aGuard(&maMtxSrcFiles);
for (vector<SrcFileData>::iterator itr = maSrcFiles.begin(), itrEnd = maSrcFiles.end();
itr != itrEnd; ++itr)
{
@@ -2598,6 +2615,7 @@ void ScExternalRefManager::resetSrcFileData(const OUString& rBaseFileUrl)
void ScExternalRefManager::updateAbsAfterLoad()
{
+ osl::MutexGuard aGuard(&maMtxSrcFiles);
OUString aOwn( getOwnDocumentName() );
for (vector<SrcFileData>::iterator itr = maSrcFiles.begin(), itrEnd = maSrcFiles.end();
itr != itrEnd; ++itr)
commit 112fb381299ed917b729b17066974a3dc9c3bafd
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date: Tue Nov 5 16:55:54 2013 -0500
Make this method private as it is used only internally.
Change-Id: I752c9a6bcd7f5b057cd517a9630a975009d6fb0d
diff --git a/sc/inc/externalrefmgr.hxx b/sc/inc/externalrefmgr.hxx
index 21e4e75a..c5a73ae 100644
--- a/sc/inc/externalrefmgr.hxx
+++ b/sc/inc/externalrefmgr.hxx
@@ -669,14 +669,6 @@ public:
*/
bool isFileLoadable(const OUString& rFile) const;
- /**
- * If in maUnsavedDocShells move it to maDocShells and create a correct
- * external reference entry
- *
- * @param Pointer to the newly saved DocumentShell
- */
- void transformUnsavedRefToSavedRef( SfxObjectShell* pShell );
-
virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint );
/**
@@ -762,6 +754,13 @@ private:
sal_uInt32 getMappedNumberFormat(sal_uInt16 nFileId, sal_uInt32 nNumFmt, const ScDocument* pSrcDoc);
+ /**
+ * If in maUnsavedDocShells move it to maDocShells and create a correct
+ * external reference entry
+ *
+ * @param Pointer to the newly saved DocumentShell
+ */
+ void transformUnsavedRefToSavedRef( SfxObjectShell* pShell );
private:
ScDocument* mpDoc;
commit 7d2619c9ad084237238b54a0e1c7a449fd7441be
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date: Tue Nov 5 16:49:55 2013 -0500
Set mutex for external ref cache content.
Change-Id: Id00c0e553e08740df8d9b7eef19407e1b0d3f022
diff --git a/sc/inc/externalrefmgr.hxx b/sc/inc/externalrefmgr.hxx
index 9ade21d..21e4e75a 100644
--- a/sc/inc/externalrefmgr.hxx
+++ b/sc/inc/externalrefmgr.hxx
@@ -32,6 +32,7 @@
#include "types.hxx"
#include "rangelst.hxx"
#include "formula/token.hxx"
+#include "osl/mutex.hxx"
#include <boost/unordered_map.hpp>
#include <boost/unordered_set.hpp>
@@ -340,6 +341,7 @@ private:
DocItem* getDocItem(sal_uInt16 nFileId) const;
private:
+ mutable osl::Mutex maMtxDocs;
mutable DocDataType maDocs;
};
@@ -682,7 +684,7 @@ public:
*
* @return true if the document still contains references to an unsaved file
*/
- bool containsUnsavedReferences() { return !maUnsavedDocShells.empty(); }
+ bool containsUnsavedReferences() const { return !maUnsavedDocShells.empty(); }
void insertRefCell(sal_uInt16 nFileId, const ScAddress& rCell);
diff --git a/sc/source/ui/docshell/externalrefmgr.cxx b/sc/source/ui/docshell/externalrefmgr.cxx
index 676352a..f7d026b 100644
--- a/sc/source/ui/docshell/externalrefmgr.cxx
+++ b/sc/source/ui/docshell/externalrefmgr.cxx
@@ -494,6 +494,8 @@ ScExternalRefCache::~ScExternalRefCache() {}
const OUString* ScExternalRefCache::getRealTableName(sal_uInt16 nFileId, const OUString& rTabName) const
{
+ osl::MutexGuard aGuard(&maMtxDocs);
+
DocDataType::const_iterator itrDoc = maDocs.find(nFileId);
if (itrDoc == maDocs.end())
{
@@ -515,6 +517,8 @@ const OUString* ScExternalRefCache::getRealTableName(sal_uInt16 nFileId, const O
const OUString* ScExternalRefCache::getRealRangeName(sal_uInt16 nFileId, const OUString& rRangeName) const
{
+ osl::MutexGuard aGuard(&maMtxDocs);
+
DocDataType::const_iterator itrDoc = maDocs.find(nFileId);
if (itrDoc == maDocs.end())
{
@@ -535,6 +539,8 @@ const OUString* ScExternalRefCache::getRealRangeName(sal_uInt16 nFileId, const O
ScExternalRefCache::TokenRef ScExternalRefCache::getCellData(
sal_uInt16 nFileId, const OUString& rTabName, SCCOL nCol, SCROW nRow, sal_uInt32* pnFmtIndex)
{
+ osl::MutexGuard aGuard(&maMtxDocs);
+
DocDataType::const_iterator itrDoc = maDocs.find(nFileId);
if (itrDoc == maDocs.end())
{
@@ -564,6 +570,8 @@ ScExternalRefCache::TokenRef ScExternalRefCache::getCellData(
ScExternalRefCache::TokenArrayRef ScExternalRefCache::getCellRangeData(
sal_uInt16 nFileId, const OUString& rTabName, const ScRange& rRange)
{
+ osl::MutexGuard aGuard(&maMtxDocs);
+
DocDataType::iterator itrDoc = maDocs.find(nFileId);
if (itrDoc == maDocs.end())
// specified document is not cached.
@@ -673,6 +681,8 @@ ScExternalRefCache::TokenArrayRef ScExternalRefCache::getCellRangeData(
ScExternalRefCache::TokenArrayRef ScExternalRefCache::getRangeNameTokens(sal_uInt16 nFileId, const OUString& rName)
{
+ osl::MutexGuard aGuard(&maMtxDocs);
+
DocItem* pDoc = getDocItem(nFileId);
if (!pDoc)
return TokenArrayRef();
@@ -688,6 +698,8 @@ ScExternalRefCache::TokenArrayRef ScExternalRefCache::getRangeNameTokens(sal_uIn
void ScExternalRefCache::setRangeNameTokens(sal_uInt16 nFileId, const OUString& rName, TokenArrayRef pArray)
{
+ osl::MutexGuard aGuard(&maMtxDocs);
+
DocItem* pDoc = getDocItem(nFileId);
if (!pDoc)
return;
@@ -912,6 +924,8 @@ SCsTAB ScExternalRefCache::getTabSpan( sal_uInt16 nFileId, const OUString& rStar
void ScExternalRefCache::getAllNumberFormats(vector<sal_uInt32>& rNumFmts) const
{
+ osl::MutexGuard aGuard(&maMtxDocs);
+
using ::std::sort;
using ::std::unique;
@@ -986,6 +1000,8 @@ bool ScExternalRefCache::setCacheTableReferenced( sal_uInt16 nFileId, const OUSt
void ScExternalRefCache::setAllCacheTableReferencedStati( bool bReferenced )
{
+ osl::MutexGuard aGuard(&maMtxDocs);
+
if (bReferenced)
{
maReferenced.reset(0);
@@ -1174,11 +1190,14 @@ ScExternalRefCache::TableTypeRef ScExternalRefCache::getCacheTable(sal_uInt16 nF
void ScExternalRefCache::clearCache(sal_uInt16 nFileId)
{
+ osl::MutexGuard aGuard(&maMtxDocs);
maDocs.erase(nFileId);
}
ScExternalRefCache::DocItem* ScExternalRefCache::getDocItem(sal_uInt16 nFileId) const
{
+ osl::MutexGuard aGuard(&maMtxDocs);
+
using ::std::pair;
DocDataType::iterator itrDoc = maDocs.find(nFileId);
if (itrDoc == maDocs.end())
commit 29d1303e234d5d7ee2f312d28592869f020eb2f2
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date: Tue Nov 5 16:25:16 2013 -0500
Use atomic increment and decrement for thread-safe reference count.
Change-Id: I630298b1c37a6d23c1aa17aabc1c9b2dcb48608a
diff --git a/include/formula/token.hxx b/include/formula/token.hxx
index 8fa8708..ea91e2c 100644
--- a/include/formula/token.hxx
+++ b/include/formula/token.hxx
@@ -29,6 +29,7 @@
#include "formula/formuladllapi.h"
#include "formula/types.hxx"
#include "svl/sharedstring.hxx"
+#include "osl/interlck.h"
namespace formula
{
@@ -107,12 +108,18 @@ public:
bool IsFunction() const; // pure functions, no operators
bool IsExternalRef() const;
sal_uInt8 GetParamCount() const;
- inline void IncRef() const { nRefCnt++; }
- inline void DecRef() const
- {
- if (!--nRefCnt)
- const_cast<FormulaToken*>(this)->Delete();
- }
+
+ inline void IncRef() const
+ {
+ osl_atomic_increment(&nRefCnt);
+ }
+
+ inline void DecRef() const
+ {
+ if (!osl_atomic_decrement(&nRefCnt))
+ const_cast<FormulaToken*>(this)->Delete();
+ }
+
inline sal_uInt16 GetRef() const { return nRefCnt; }
inline OpCode GetOpCode() const { return eOp; }
commit 1d996cee76a50a5a6aa74e21eec89e03a05772e7
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date: Tue Nov 5 14:55:21 2013 -0500
Keep the integer type in sync and remove unused data members.
Change-Id: Iaaf1ebddd3b946b3211952729d41b01f0967f374
diff --git a/sc/source/filter/inc/formulabuffer.hxx b/sc/source/filter/inc/formulabuffer.hxx
index dbb77bb..f9e5229 100644
--- a/sc/source/filter/inc/formulabuffer.hxx
+++ b/sc/source/filter/inc/formulabuffer.hxx
@@ -74,30 +74,26 @@ class FormulaBuffer : public WorkbookHelper
TokenRangeAddressItem( const TokenAddressItem& rTokenAndAddress, const ::com::sun::star::table::CellRangeAddress& rCellRangeAddress ) : maTokenAndAddress( rTokenAndAddress ), maCellRangeAddress( rCellRangeAddress ) {}
};
- typedef ::std::map< sal_Int32, std::vector< TokenAddressItem > > FormulaDataMap;
- typedef ::std::map< sal_Int32, std::vector< TokenRangeAddressItem > > ArrayFormulaDataMap;
+ typedef ::std::map< SCTAB, std::vector<TokenAddressItem> > FormulaDataMap;
+ typedef ::std::map< SCTAB, std::vector<TokenRangeAddressItem> > ArrayFormulaDataMap;
// sheet -> list of shared formula descriptions
- typedef ::std::map< sal_Int32, std::vector< SharedFormulaDesc > > SheetToSharedFormulaid;
+ typedef ::std::map< SCTAB, std::vector<SharedFormulaDesc> > SheetToSharedFormulaid;
// sheet -> stuff needed to create shared formulae
- typedef ::std::map< sal_Int32, std::vector< SharedFormulaEntry > > SheetToFormulaEntryMap;
- // sharedId -> tokedId
- typedef ::std::map< sal_Int32, sal_Int32 > SharedIdToTokenIndex;
- typedef ::std::map< sal_Int32, SharedIdToTokenIndex > SheetToSharedIdToTokenIndex;
+ typedef ::std::map< SCTAB, std::vector<SharedFormulaEntry> > SheetToFormulaEntryMap;
+
typedef ::std::pair< ::com::sun::star::table::CellAddress, double > ValueAddressPair;
- typedef ::std::map< sal_Int32, std::vector< ValueAddressPair > > FormulaValueMap;
+ typedef ::std::map< SCTAB, std::vector<ValueAddressPair> > FormulaValueMap;
- com::sun::star::uno::Reference< com::sun::star::sheet::XSpreadsheet > mxCurrSheet;
FormulaDataMap maCellFormulas;
ArrayFormulaDataMap maCellArrayFormulas;
SheetToFormulaEntryMap maSharedFormulas;
SheetToSharedFormulaid maSharedFormulaIds;
- SheetToSharedIdToTokenIndex maTokenIndexes;
FormulaValueMap maCellFormulaValues;
void applyArrayFormulas( const std::vector< TokenRangeAddressItem >& rVector );
void applyCellFormulas( const std::vector< TokenAddressItem >& rVector );
void applyCellFormulaValues( const std::vector< ValueAddressPair >& rVector );
- void applySharedFormulas( sal_Int32 nTab );
+ void applySharedFormulas( SCTAB nTab );
public:
explicit FormulaBuffer( const WorkbookHelper& rHelper );
diff --git a/sc/source/filter/oox/formulabuffer.cxx b/sc/source/filter/oox/formulabuffer.cxx
index 68e1d2e..04be139 100644
--- a/sc/source/filter/oox/formulabuffer.cxx
+++ b/sc/source/filter/oox/formulabuffer.cxx
@@ -54,13 +54,11 @@ void FormulaBuffer::finalizeImport()
ISegmentProgressBarRef xFormulaBar = getProgressBar().createSegment( getProgressBar().getFreeLength() );
ScDocument& rDoc = getScDocument();
- Reference< XIndexAccess > xSheets( getDocument()->getSheets(), UNO_QUERY_THROW );
rDoc.SetAutoNameCache( new ScAutoNameCache( &rDoc ) );
- for ( sal_Int32 nTab = 0, nElem = xSheets->getCount(); nTab < nElem; ++nTab )
+ for (SCTAB nTab = 0, nElem = rDoc.GetTableCount(); nTab < nElem; ++nTab)
{
double fPosition = static_cast< double> (nTab + 1) /static_cast<double>(nElem);
xFormulaBar->setPosition( fPosition );
- mxCurrSheet = getSheetFromDoc( nTab );
applySharedFormulas(nTab);
@@ -122,7 +120,7 @@ void FormulaBuffer::applyCellFormulaValues( const std::vector< ValueAddressPair
}
}
-void FormulaBuffer::applySharedFormulas( sal_Int32 nTab )
+void FormulaBuffer::applySharedFormulas( SCTAB nTab )
{
SheetToFormulaEntryMap::const_iterator itShared = maSharedFormulas.find(nTab);
if (itShared == maSharedFormulas.end())
commit 7045802f27f3efe74b4ed9146d33abe253df043a
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date: Tue Nov 5 14:38:28 2013 -0500
Add mutex to guard the shared string pool content.
Change-Id: I0eb97d0fbeaefd8a1c86d240ed8bd7f208fb662e
diff --git a/include/svl/sharedstringpool.hxx b/include/svl/sharedstringpool.hxx
index 1b2796d..b2cb367 100644
--- a/include/svl/sharedstringpool.hxx
+++ b/include/svl/sharedstringpool.hxx
@@ -11,6 +11,7 @@
#define INCLUDED_SVL_SHAREDSTRINGPOOL_HXX
#include "svl/sharedstring.hxx"
+#include "osl/mutex.hxx"
#include <boost/unordered_map.hpp>
#include <boost/unordered_set.hpp>
@@ -30,6 +31,7 @@ class SVL_DLLPUBLIC SharedStringPool
typedef std::pair<StrHashType::iterator, bool> InsertResultType;
typedef boost::unordered_map<const rtl_uString*, OUString> StrStoreType;
+ mutable osl::Mutex maMutex;
StrHashType maStrPool;
StrHashType maStrPoolUpper;
StrStoreType maStrStore;
diff --git a/svl/source/misc/sharedstringpool.cxx b/svl/source/misc/sharedstringpool.cxx
index 46bf814..1e85da5 100644
--- a/svl/source/misc/sharedstringpool.cxx
+++ b/svl/source/misc/sharedstringpool.cxx
@@ -17,6 +17,8 @@ SharedStringPool::SharedStringPool( const CharClass* pCharClass ) : mpCharClass(
SharedString SharedStringPool::intern( const OUString& rStr )
{
+ osl::MutexGuard aGuard(&maMutex);
+
InsertResultType aRes = findOrInsert(maStrPool, rStr);
if (aRes.first == maStrPool.end())
// Insertion failed.
@@ -63,6 +65,8 @@ inline sal_Int32 getRefCount( const rtl_uString* p )
void SharedStringPool::purge()
{
+ osl::MutexGuard aGuard(&maMutex);
+
StrHashType aNewStrPool;
StrHashType::iterator it = maStrPool.begin(), itEnd = maStrPool.end();
for (; it != itEnd; ++it)
@@ -98,11 +102,13 @@ void SharedStringPool::purge()
size_t SharedStringPool::getCount() const
{
+ osl::MutexGuard aGuard(&maMutex);
return maStrPool.size();
}
size_t SharedStringPool::getCountIgnoreCase() const
{
+ osl::MutexGuard aGuard(&maMutex);
return maStrPoolUpper.size();
}
commit 9611851a5349f564ba97bacd9619eb8b329ae283
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date: Tue Nov 5 11:55:57 2013 -0500
Avoid using an extra buffer when the name doesn't contain double-quotes.
Change-Id: Idc76ccad114e5964f80c5a3c8c8da2a64c1a2b86
diff --git a/sc/source/core/tool/address.cxx b/sc/source/core/tool/address.cxx
index 41aae82..ec9e088 100644
--- a/sc/source/core/tool/address.cxx
+++ b/sc/source/core/tool/address.cxx
@@ -47,6 +47,44 @@ ScAddress::Details::Details ( const ScDocument* pDoc,
{
}
+namespace {
+
+const sal_Unicode* parseQuotedNameWithBuffer( const sal_Unicode* pStart, const sal_Unicode* p, OUString& rName )
+{
+ // The current character must be on the 2nd quote.
+
+ // Push all the characters up to the current, but skip the very first
+ // character which is the opening quote.
+ OUStringBuffer aBuf(OUString(pStart+1, p-pStart-1));
+
+ ++p; // Skip the 2nd quote.
+ sal_Unicode cPrev = 0;
+ for (; *p; ++p)
+ {
+ if (*p == '\'')
+ {
+ if (cPrev == '\'')
+ {
+ // double single-quote equals one single quote.
+ aBuf.append(*p);
+ cPrev = 0;
+ continue;
+ }
+ }
+ else if (cPrev == '\'')
+ {
+ // We are past the closing quote. We're done!
+ rName = aBuf.makeStringAndClear();
+ return p;
+ }
+ else
+ aBuf.append(*p);
+ cPrev = *p;
+ }
+
+ return pStart;
+}
+
/**
* Parse from the opening single quote to the closing single quote. Inside
* the quotes, a single quote character is encoded by double single-quote
@@ -59,13 +97,11 @@ ScAddress::Details::Details ( const ScDocument* pDoc,
* @return pointer to the character immediately after the closing single
* quote.
*/
-static const sal_Unicode* lcl_ParseQuotedName( const sal_Unicode* p, OUString& rName )
+const sal_Unicode* parseQuotedName( const sal_Unicode* p, OUString& rName )
{
- rName = "";
if (*p != '\'')
return p;
- OUStringBuffer aBuf;
const sal_Unicode* pStart = p;
sal_Unicode cPrev = 0;
for (++p; *p; ++p)
@@ -75,25 +111,26 @@ static const sal_Unicode* lcl_ParseQuotedName( const sal_Unicode* p, OUString& r
if (cPrev == '\'')
{
// double single-quote equals one single quote.
- aBuf.append(*p);
- cPrev = 0;
- continue;
+ return parseQuotedNameWithBuffer(pStart, p, rName);
}
}
else if (cPrev == '\'')
{
- // We are past the closing quote. We're done!
- rName = aBuf.makeStringAndClear();
+ // We are past the closing quote. We're done! Skip the opening
+ // and closing quotes.
+ rName = OUString(pStart+1, p - pStart-2);
return p;
}
- else
- aBuf.append(*p);
+
cPrev = *p;
}
+ rName = "";
return pStart;
}
+}
+
static long int
sal_Unicode_strtol ( const sal_Unicode* p,
const sal_Unicode** pEnd )
@@ -265,7 +302,7 @@ lcl_XL_ParseSheetRef( const sal_Unicode* start,
}
else if( *p == '\'')
{
- p = lcl_ParseQuotedName(p, aTabName);
+ p = parseQuotedName(p, aTabName);
if (aTabName.isEmpty())
return NULL;
}
@@ -415,7 +452,7 @@ const sal_Unicode* ScRange::Parse_XL_Header(
// single quote text inside the quoted text.
if (*p == '\'')
{
- p = lcl_ParseQuotedName(p, rExternDocName);
+ p = parseQuotedName(p, rExternDocName);
if (!*p || *p != ']' || rExternDocName.isEmpty())
{
rExternDocName = "";
@@ -447,7 +484,7 @@ const sal_Unicode* ScRange::Parse_XL_Header(
// Excel does not allow [ and ] characters in sheet names though.
// But, more sickness comes with MOOXML as there may be
// '[1]Sheet 4'!$A$1 where [1] is the external doc's index.
- p = lcl_ParseQuotedName(p, rExternDocName);
+ p = parseQuotedName(p, rExternDocName);
if (!*p || *p != '!')
{
rExternDocName = "";
@@ -1003,7 +1040,7 @@ lcl_ScAddress_Parse_OOo( const sal_Unicode* p, ScDocument* pDoc, ScAddress& rAdd
{
const sal_Unicode* pStart = p;
OUString aTmp;
- p = lcl_ParseQuotedName(p, aTmp);
+ p = parseQuotedName(p, aTmp);
aDocName = aTmp;
if (*p++ == SC_COMPILER_FILE_TAB_SEP)
bExtDoc = true;
@@ -1036,7 +1073,7 @@ lcl_ScAddress_Parse_OOo( const sal_Unicode* p, ScDocument* pDoc, ScAddress& rAdd
// Tokens that start at ' can have anything in them until a final
// ' but '' marks an escaped '. We've earlier guaranteed that a
// string containing '' will be surrounded by '.
- p = lcl_ParseQuotedName(p, aTab);
+ p = parseQuotedName(p, aTab);
}
else
{
diff --git a/sc/source/filter/oox/formulabuffer.cxx b/sc/source/filter/oox/formulabuffer.cxx
index bc074a2..68e1d2e 100644
--- a/sc/source/filter/oox/formulabuffer.cxx
+++ b/sc/source/filter/oox/formulabuffer.cxx
@@ -90,11 +90,11 @@ void FormulaBuffer::finalizeImport()
void FormulaBuffer::applyCellFormulas( const std::vector< TokenAddressItem >& rVector )
{
ScDocumentImport& rDoc = getDocImport();
+ ScExternalRefManager::ApiGuard aExtRefGuard(&rDoc.getDoc());
for ( std::vector< TokenAddressItem >::const_iterator it = rVector.begin(), it_end = rVector.end(); it != it_end; ++it )
{
ScAddress aPos;
ScUnoConversion::FillScAddress(aPos, it->maCellAddress);
- ScExternalRefManager::ApiGuard aExtRefGuard(&rDoc.getDoc());
ScCompiler aCompiler(&rDoc.getDoc(), aPos);
aCompiler.SetGrammar(formula::FormulaGrammar::GRAM_ENGLISH_XL_OOX);
ScTokenArray* pCode = aCompiler.CompileString(it->maTokenStr);
commit dd9b59ef1869509817aa093747142e1ab0c3adba
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date: Tue Nov 5 11:00:05 2013 -0500
Add new test for parsing OOo A1 style single references.
Change-Id: I7644338bd536d16777d330a64764eb26ecda5da5
diff --git a/sc/qa/unit/ucalc.hxx b/sc/qa/unit/ucalc.hxx
index b9c1d42..19c94d7 100644
--- a/sc/qa/unit/ucalc.hxx
+++ b/sc/qa/unit/ucalc.hxx
@@ -84,6 +84,7 @@ public:
void testRangeList();
void testInput();
+ void testFormulaParseReference();
void testFetchVectorRefArray();
void testFormulaHashAndTag();
void testFormulaRefData();
@@ -292,6 +293,7 @@ public:
CPPUNIT_TEST(testSharedStringPool);
CPPUNIT_TEST(testRangeList);
CPPUNIT_TEST(testInput);
+ CPPUNIT_TEST(testFormulaParseReference);
CPPUNIT_TEST(testFetchVectorRefArray);
CPPUNIT_TEST(testFormulaHashAndTag);
CPPUNIT_TEST(testFormulaRefData);
diff --git a/sc/qa/unit/ucalc_formula.cxx b/sc/qa/unit/ucalc_formula.cxx
index 9f824e5..ce407e7 100644
--- a/sc/qa/unit/ucalc_formula.cxx
+++ b/sc/qa/unit/ucalc_formula.cxx
@@ -73,6 +73,62 @@ bool equals( const formula::VectorRefArray& rArray, size_t nPos, const OUString&
}
+void Test::testFormulaParseReference()
+{
+ OUString aTab1("90's Music"), aTab2("90's and 70's"), aTab3("All Others"), aTab4("NoQuote");
+ m_pDoc->InsertTab(0, "Dummy"); // just to shift the sheet indices...
+ m_pDoc->InsertTab(1, aTab1); // name with a single quote.
+ m_pDoc->InsertTab(2, aTab2); // name with 2 single quotes.
+ m_pDoc->InsertTab(3, aTab3); // name without single quotes.
+ m_pDoc->InsertTab(4, aTab4); // name that doesn't require to be quoted.
+
+ OUString aTabName;
+ m_pDoc->GetName(1, aTabName);
+ CPPUNIT_ASSERT_EQUAL(aTab1, aTabName);
+ m_pDoc->GetName(2, aTabName);
+ CPPUNIT_ASSERT_EQUAL(aTab2, aTabName);
+ m_pDoc->GetName(3, aTabName);
+ CPPUNIT_ASSERT_EQUAL(aTab3, aTabName);
+ m_pDoc->GetName(4, aTabName);
+ CPPUNIT_ASSERT_EQUAL(aTab4, aTabName);
+
+ ScAddress aPos;
+ ScAddress::ExternalInfo aExtInfo;
+ sal_uInt16 nRes = aPos.Parse("'90''s Music'.D10", m_pDoc, formula::FormulaGrammar::CONV_OOO, &aExtInfo);
+ CPPUNIT_ASSERT_MESSAGE("Failed to parse.", (nRes & SCA_VALID) != 0);
+ CPPUNIT_ASSERT_EQUAL(static_cast<SCTAB>(1), aPos.Tab());
+ CPPUNIT_ASSERT_EQUAL(static_cast<SCCOL>(3), aPos.Col());
+ CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(9), aPos.Row());
+ CPPUNIT_ASSERT_MESSAGE("This is not an external address.", !aExtInfo.mbExternal);
+
+ nRes = aPos.Parse("'90''s and 70''s'.C100", m_pDoc, formula::FormulaGrammar::CONV_OOO, &aExtInfo);
+ CPPUNIT_ASSERT_MESSAGE("Failed to parse.", (nRes & SCA_VALID) != 0);
+ CPPUNIT_ASSERT_EQUAL(static_cast<SCTAB>(2), aPos.Tab());
+ CPPUNIT_ASSERT_EQUAL(static_cast<SCCOL>(2), aPos.Col());
+ CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(99), aPos.Row());
+ CPPUNIT_ASSERT_MESSAGE("This is not an external address.", !aExtInfo.mbExternal);
+
+ nRes = aPos.Parse("'All Others'.B3", m_pDoc, formula::FormulaGrammar::CONV_OOO, &aExtInfo);
+ CPPUNIT_ASSERT_MESSAGE("Failed to parse.", (nRes & SCA_VALID) != 0);
+ CPPUNIT_ASSERT_EQUAL(static_cast<SCTAB>(3), aPos.Tab());
+ CPPUNIT_ASSERT_EQUAL(static_cast<SCCOL>(1), aPos.Col());
+ CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(2), aPos.Row());
+ CPPUNIT_ASSERT_MESSAGE("This is not an external address.", !aExtInfo.mbExternal);
+
+ nRes = aPos.Parse("NoQuote.E13", m_pDoc, formula::FormulaGrammar::CONV_OOO, &aExtInfo);
+ CPPUNIT_ASSERT_MESSAGE("Failed to parse.", (nRes & SCA_VALID) != 0);
+ CPPUNIT_ASSERT_EQUAL(static_cast<SCTAB>(4), aPos.Tab());
+ CPPUNIT_ASSERT_EQUAL(static_cast<SCCOL>(4), aPos.Col());
+ CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(12), aPos.Row());
+ CPPUNIT_ASSERT_MESSAGE("This is not an external address.", !aExtInfo.mbExternal);
+
+ m_pDoc->DeleteTab(4);
+ m_pDoc->DeleteTab(3);
+ m_pDoc->DeleteTab(2);
+ m_pDoc->DeleteTab(1);
+ m_pDoc->DeleteTab(0);
+}
+
void Test::testFetchVectorRefArray()
{
m_pDoc->InsertTab(0, "Test");
commit eced6da7455c671807d60becf3b2b549f39e87da
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date: Mon Nov 4 23:31:51 2013 -0500
Using OUStringBuffer is faster than chained += operator.
Change-Id: I9991028ddd8ab6e2e43fe9a19428c9fdfbd38db6
diff --git a/sc/source/core/tool/address.cxx b/sc/source/core/tool/address.cxx
index 7426f95..41aae82 100644
--- a/sc/source/core/tool/address.cxx
+++ b/sc/source/core/tool/address.cxx
@@ -65,6 +65,7 @@ static const sal_Unicode* lcl_ParseQuotedName( const sal_Unicode* p, OUString& r
if (*p != '\'')
return p;
+ OUStringBuffer aBuf;
const sal_Unicode* pStart = p;
sal_Unicode cPrev = 0;
for (++p; *p; ++p)
@@ -74,19 +75,22 @@ static const sal_Unicode* lcl_ParseQuotedName( const sal_Unicode* p, OUString& r
if (cPrev == '\'')
{
// double single-quote equals one single quote.
- rName += OUString(*p);
+ aBuf.append(*p);
cPrev = 0;
continue;
}
}
else if (cPrev == '\'')
+ {
// We are past the closing quote. We're done!
+ rName = aBuf.makeStringAndClear();
return p;
+ }
else
- rName += OUString(*p);
+ aBuf.append(*p);
cPrev = *p;
}
- rName = "";
+
return pStart;
}
commit 04532617c7d264411563db24dc359326cc18eda7
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date: Mon Nov 4 22:52:26 2013 -0500
Avoid duplication of ScTokenArray during formula cell construction.
For slightly less overhead.
Change-Id: Ie5861d585d6e22fbd19dfd57edfebae4f4504839
diff --git a/sc/inc/documentimport.hxx b/sc/inc/documentimport.hxx
index d034292..d2aa994 100644
--- a/sc/inc/documentimport.hxx
+++ b/sc/inc/documentimport.hxx
@@ -67,7 +67,7 @@ public:
void setStringCell(const ScAddress& rPos, const OUString& rStr);
void setEditCell(const ScAddress& rPos, EditTextObject* pEditText);
void setFormulaCell(const ScAddress& rPos, const OUString& rFormula, formula::FormulaGrammar::Grammar eGrammar);
- void setFormulaCell(const ScAddress& rPos, const ScTokenArray& rArray);
+ void setFormulaCell(const ScAddress& rPos, ScTokenArray* pArray);
void setFormulaCell(const ScAddress& rPos, ScFormulaCell* pCell);
void setMatrixCells(
diff --git a/sc/inc/formulacell.hxx b/sc/inc/formulacell.hxx
index 46a68c4..c2e578b 100644
--- a/sc/inc/formulacell.hxx
+++ b/sc/inc/formulacell.hxx
@@ -153,6 +153,15 @@ public:
ScFormulaCell( ScDocument* pDoc, const ScAddress& rPos );
+ /**
+ * Transfer the ownership of the passed token array instance to the
+ * formula cell being constructed. The caller <i>must not</i> pass a NULL
+ * token array pointer.
+ */
+ ScFormulaCell( ScDocument* pDoc, const ScAddress& rPos, ScTokenArray* pArray,
+ const formula::FormulaGrammar::Grammar eGrammar = formula::FormulaGrammar::GRAM_DEFAULT,
+ sal_uInt8 cMatInd = MM_NONE );
+
ScFormulaCell( ScDocument* pDoc, const ScAddress& rPos, const ScTokenArray& rArray,
const formula::FormulaGrammar::Grammar eGrammar = formula::FormulaGrammar::GRAM_DEFAULT,
sal_uInt8 cMatInd = MM_NONE );
diff --git a/sc/source/core/data/documentimport.cxx b/sc/source/core/data/documentimport.cxx
index 93b43b0..7138795 100644
--- a/sc/source/core/data/documentimport.cxx
+++ b/sc/source/core/data/documentimport.cxx
@@ -202,7 +202,7 @@ void ScDocumentImport::setFormulaCell(
rCells.set(pBlockPos->miCellPos, rPos.Row(), new ScFormulaCell(&mpImpl->mrDoc, rPos, rFormula, eGrammar));
}
-void ScDocumentImport::setFormulaCell(const ScAddress& rPos, const ScTokenArray& rArray)
+void ScDocumentImport::setFormulaCell(const ScAddress& rPos, ScTokenArray* pArray)
{
ScTable* pTab = mpImpl->mrDoc.FetchTable(rPos.Tab());
if (!pTab)
@@ -216,7 +216,7 @@ void ScDocumentImport::setFormulaCell(const ScAddress& rPos, const ScTokenArray&
sc::CellStoreType& rCells = pTab->aCol[rPos.Col()].maCells;
pBlockPos->miCellPos =
- rCells.set(pBlockPos->miCellPos, rPos.Row(), new ScFormulaCell(&mpImpl->mrDoc, rPos, rArray));
+ rCells.set(pBlockPos->miCellPos, rPos.Row(), new ScFormulaCell(&mpImpl->mrDoc, rPos, pArray));
}
void ScDocumentImport::setFormulaCell(const ScAddress& rPos, ScFormulaCell* pCell)
diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx
index 15c3b98..b0ffb74 100644
--- a/sc/source/core/data/formulacell.cxx
+++ b/sc/source/core/data/formulacell.cxx
@@ -487,6 +487,54 @@ ScFormulaCell::ScFormulaCell( ScDocument* pDoc, const ScAddress& rPos,
}
ScFormulaCell::ScFormulaCell(
+ ScDocument* pDoc, const ScAddress& rPos, ScTokenArray* pArray,
+ const FormulaGrammar::Grammar eGrammar, sal_uInt8 cMatInd ) :
+ eTempGrammar( eGrammar),
+ pCode(pArray),
+ pDocument( pDoc ),
+ pPrevious(0),
+ pNext(0),
+ pPreviousTrack(0),
+ pNextTrack(0),
+ nSeenInIteration(0),
+ cMatrixFlag ( cMatInd ),
+ nFormatType ( NUMBERFORMAT_NUMBER ),
+ bDirty( true ),
+ bChanged( false ),
+ bRunning( false ),
+ bCompile( false ),
+ bSubTotal( false ),
+ bIsIterCell( false ),
+ bInChangeTrack( false ),
+ bTableOpDirty( false ),
+ bNeedListening( false ),
+ mbNeedsNumberFormat( false ),
+ aPos( rPos )
+{
+ assert(pArray); // Never pass a NULL pointer here.
+
+ // Generate RPN token array.
+ if (pCode->GetLen() && !pCode->GetCodeError() && !pCode->GetCodeLen())
+ {
+ ScCompiler aComp( pDocument, aPos, *pCode);
+ aComp.SetGrammar(eTempGrammar);
+ bSubTotal = aComp.CompileTokenArray();
+ nFormatType = aComp.GetNumFormatType();
+ }
+ else
+ {
+ pCode->Reset();
+ if (pCode->GetNextOpCodeRPN(ocSubTotal))
+ bSubTotal = true;
+ }
+
+ if (bSubTotal)
+ pDocument->AddSubTotalCell(this);
+
+ pCode->GenHash();
+}
+
+ScFormulaCell::ScFormulaCell(
ScDocument* pDoc, const ScAddress& rPos, const ScTokenArray& rArray,
const FormulaGrammar::Grammar eGrammar, sal_uInt8 cMatInd ) :
eTempGrammar( eGrammar),
diff --git a/sc/source/filter/oox/formulabuffer.cxx b/sc/source/filter/oox/formulabuffer.cxx
index 3dde87b..bc074a2 100644
--- a/sc/source/filter/oox/formulabuffer.cxx
+++ b/sc/source/filter/oox/formulabuffer.cxx
@@ -27,8 +27,6 @@
#include "externalrefmgr.hxx"
#include "oox/token/tokens.hxx"
-#include <boost/scoped_ptr.hpp>
-
using namespace com::sun::star;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::table;
@@ -99,11 +97,11 @@ void FormulaBuffer::applyCellFormulas( const std::vector< TokenAddressItem >& rV
ScExternalRefManager::ApiGuard aExtRefGuard(&rDoc.getDoc());
ScCompiler aCompiler(&rDoc.getDoc(), aPos);
aCompiler.SetGrammar(formula::FormulaGrammar::GRAM_ENGLISH_XL_OOX);
- boost::scoped_ptr<ScTokenArray> pCode(aCompiler.CompileString(it->maTokenStr));
+ ScTokenArray* pCode = aCompiler.CompileString(it->maTokenStr);
if (!pCode)
continue;
- rDoc.setFormulaCell(aPos, *pCode);
+ rDoc.setFormulaCell(aPos, pCode);
}
}
diff --git a/sc/source/filter/oox/worksheethelper.cxx b/sc/source/filter/oox/worksheethelper.cxx
index fb5eadd..148118b 100644
--- a/sc/source/filter/oox/worksheethelper.cxx
+++ b/sc/source/filter/oox/worksheethelper.cxx
@@ -1583,7 +1583,7 @@ void WorksheetHelper::putFormulaTokens( const CellAddress& rAddress, const ApiTo
ScAddress aCellPos;
ScUnoConversion::FillScAddress( aCellPos, rAddress );
ScTokenConversion::ConvertToTokenArray(rDoc.getDoc(), aTokenArray, rTokens);
- rDoc.setFormulaCell(aCellPos, aTokenArray);
+ rDoc.setFormulaCell(aCellPos, new ScTokenArray(aTokenArray));
}
void WorksheetHelper::initializeWorksheetImport()
commit a09f7fddb4e847b35e6d47a45403c649152dd671
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date: Mon Nov 4 22:24:39 2013 -0500
Modify ScFormulaCell's ctor to take a const reference to ScTokenArray.
Instead of a pointer to ScTokenArray, and then clone its instance. If
the token array gets cloned in ctor, take a const reference.
Change-Id: I280fd7eb9eaea9905dbf954a1ace904ab0814dfe
diff --git a/sc/inc/formulacell.hxx b/sc/inc/formulacell.hxx
index 9d27558..46a68c4 100644
--- a/sc/inc/formulacell.hxx
+++ b/sc/inc/formulacell.hxx
@@ -151,10 +151,11 @@ public:
ScFormulaCell* Clone() const;
- /** Empty formula cell, or with a preconstructed token array. */
- ScFormulaCell( ScDocument*, const ScAddress&, const ScTokenArray* = NULL,
- const formula::FormulaGrammar::Grammar = formula::FormulaGrammar::GRAM_DEFAULT,
- sal_uInt8 = MM_NONE );
+ ScFormulaCell( ScDocument* pDoc, const ScAddress& rPos );
+
+ ScFormulaCell( ScDocument* pDoc, const ScAddress& rPos, const ScTokenArray& rArray,
+ const formula::FormulaGrammar::Grammar eGrammar = formula::FormulaGrammar::GRAM_DEFAULT,
+ sal_uInt8 cMatInd = MM_NONE );
ScFormulaCell( ScDocument* pDoc, const ScAddress& rPos, const ScFormulaCellGroupRef& xGroup,
const formula::FormulaGrammar::Grammar = formula::FormulaGrammar::GRAM_DEFAULT,
diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx
index 512ccc5..12fc80a 100644
--- a/sc/source/core/data/column.cxx
+++ b/sc/source/core/data/column.cxx
@@ -1643,7 +1643,7 @@ class CopyAsLinkHandler
ScTokenArray aArr;
aArr.AddSingleReference(aRef);
- return new ScFormulaCell(&mrDestCol.GetDoc(), ScAddress(mrDestCol.GetCol(), nRow, mrDestCol.GetTab()), &aArr);
+ return new ScFormulaCell(&mrDestCol.GetDoc(), ScAddress(mrDestCol.GetCol(), nRow, mrDestCol.GetTab()), aArr);
}
void createRefBlock(const sc::CellStoreType::value_type& aNode, size_t nOffset, size_t nDataSize)
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index 61f5326..a400935 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -700,7 +700,7 @@ class CopyCellsFromClipHandler
aArr.AddSingleReference(aRef);
mrDestCol.SetFormulaCell(
- maDestBlockPos, nDestRow, new ScFormulaCell(&mrDestCol.GetDoc(), aDestPos, &aArr));
+ maDestBlockPos, nDestRow, new ScFormulaCell(&mrDestCol.GetDoc(), aDestPos, aArr));
}
void duplicateNotes(SCROW nStartRow, size_t nDataSize, bool bCloneCaption )
@@ -968,7 +968,7 @@ void ScColumn::CopyFromClip(
ScTokenArray aArr;
aArr.AddSingleReference( aRef );
- SetFormulaCell(nDestRow, new ScFormulaCell(pDocument, aDestPos, &aArr));
+ SetFormulaCell(nDestRow, new ScFormulaCell(pDocument, aDestPos, aArr));
}
return;
@@ -1117,7 +1117,7 @@ public:
miNewCellsPos = maNewCells.set(
miNewCellsPos, nRow-mnRowOffset,
new ScFormulaCell(
- &mrDestColumn.GetDoc(), ScAddress(mrDestColumn.GetCol(), nRow, mrDestColumn.GetTab()), &aArr));
+ &mrDestColumn.GetDoc(), ScAddress(mrDestColumn.GetCol(), nRow, mrDestColumn.GetTab()), aArr));
}
break;
case sc::element_type_string:
@@ -1174,7 +1174,7 @@ public:
miNewCellsPos = maNewCells.set(
miNewCellsPos, nRow-mnRowOffset,
new ScFormulaCell(
- &mrDestColumn.GetDoc(), ScAddress(mrDestColumn.GetCol(), nRow, mrDestColumn.GetTab()), &aArr));
+ &mrDestColumn.GetDoc(), ScAddress(mrDestColumn.GetCol(), nRow, mrDestColumn.GetTab()), aArr));
}
break;
case sc::element_type_formula:
@@ -1203,7 +1203,7 @@ public:
miNewCellsPos = maNewCells.set(
miNewCellsPos, nRow-mnRowOffset,
new ScFormulaCell(
- &mrDestColumn.GetDoc(), ScAddress(mrDestColumn.GetCol(), nRow, mrDestColumn.GetTab()), &aArr));
+ &mrDestColumn.GetDoc(), ScAddress(mrDestColumn.GetCol(), nRow, mrDestColumn.GetTab()), aArr));
}
break;
case sc::element_type_string:
@@ -1282,7 +1282,7 @@ public:
miNewCellsPos = maNewCells.set(
miNewCellsPos, nDestRow-mnRowOffset,
new ScFormulaCell(
- &mrDestColumn.GetDoc(), ScAddress(mrDestColumn.GetCol(), nDestRow, mrDestColumn.GetTab()), &aArr));
+ &mrDestColumn.GetDoc(), ScAddress(mrDestColumn.GetCol(), nDestRow, mrDestColumn.GetTab()), aArr));
}
break;
default:
@@ -1709,7 +1709,7 @@ void ScColumn::SetFormula( SCROW nRow, const ScTokenArray& rArray, formula::Form
ScAddress aPos(nCol, nRow, nTab);
sc::CellStoreType::iterator it = GetPositionToInsert(nRow);
- ScFormulaCell* pCell = new ScFormulaCell(pDocument, aPos, &rArray, eGram);
+ ScFormulaCell* pCell = new ScFormulaCell(pDocument, aPos, rArray, eGram);
sal_uInt32 nCellFormat = GetNumberFormat(nRow);
if( (nCellFormat % SV_COUNTRY_LANGUAGE_OFFSET) == 0)
pCell->SetNeedNumberFormat(true);
diff --git a/sc/source/core/data/conditio.cxx b/sc/source/core/data/conditio.cxx
index c0d6f0d..cd1d2df 100644
--- a/sc/source/core/data/conditio.cxx
+++ b/sc/source/core/data/conditio.cxx
@@ -414,13 +414,13 @@ void ScConditionEntry::MakeCells( const ScAddress& rPos ) // Formelzel
{
if ( pFormula1 && !pFCell1 && !bRelRef1 )
{
- pFCell1 = new ScFormulaCell( mpDoc, rPos, pFormula1 );
+ pFCell1 = new ScFormulaCell(mpDoc, rPos, *pFormula1);
pFCell1->StartListeningTo( mpDoc );
}
if ( pFormula2 && !pFCell2 && !bRelRef2 )
{
- pFCell2 = new ScFormulaCell( mpDoc, rPos, pFormula2 );
+ pFCell2 = new ScFormulaCell(mpDoc, rPos, *pFormula2);
pFCell2->StartListeningTo( mpDoc );
}
}
@@ -630,7 +630,7 @@ void ScConditionEntry::Interpret( const ScAddress& rPos )
ScFormulaCell* pEff1 = pFCell1;
if ( bRelRef1 )
{
- pTemp1 = new ScFormulaCell( mpDoc, rPos, pFormula1 ); // ohne Listening
+ pTemp1 = pFormula1 ? new ScFormulaCell(mpDoc, rPos, *pFormula1) : new ScFormulaCell(mpDoc, rPos);
pEff1 = pTemp1;
}
if ( pEff1 )
@@ -660,7 +660,7 @@ void ScConditionEntry::Interpret( const ScAddress& rPos )
ScFormulaCell* pEff2 = pFCell2; //@ 1!=2
if ( bRelRef2 )
{
- pTemp2 = new ScFormulaCell( mpDoc, rPos, pFormula2 ); // ohne Listening
+ pTemp2 = pFormula2 ? new ScFormulaCell(mpDoc, rPos, *pFormula2) : new ScFormulaCell(mpDoc, rPos);
pEff2 = pTemp2;
}
if ( pEff2 )
diff --git a/sc/source/core/data/documen4.cxx b/sc/source/core/data/documen4.cxx
index 65005bd..0aa6383 100644
--- a/sc/source/core/data/documen4.cxx
+++ b/sc/source/core/data/documen4.cxx
@@ -272,7 +272,7 @@ void ScDocument::InsertMatrixFormula(SCCOL nCol1, SCROW nRow1,
ScFormulaCell* pCell;
ScAddress aPos( nCol1, nRow1, nTab1 );
if (pArr)
- pCell = new ScFormulaCell( this, aPos, pArr, eGram, MM_FORMULA );
+ pCell = new ScFormulaCell(this, aPos, *pArr, eGram, MM_FORMULA);
else
pCell = new ScFormulaCell( this, aPos, rFormula, eGram, MM_FORMULA );
pCell->SetMatColsRows( nCol2 - nCol1 + 1, nRow2 - nRow1 + 1, bDirtyFlag );
@@ -336,7 +336,7 @@ void ScDocument::InsertMatrixFormula(SCCOL nCol1, SCROW nRow1,
aRefData.SetAddress(aBasePos, aPos);
t->GetSingleRef() = aRefData;
boost::scoped_ptr<ScTokenArray> pTokArr(aArr.Clone());
- pCell = new ScFormulaCell( this, aPos, pTokArr.get(), eGram, MM_REFERENCE );
+ pCell = new ScFormulaCell(this, aPos, *pTokArr, eGram, MM_REFERENCE);
pTab->SetFormulaCell(nCol, nRow, pCell);
}
}
diff --git a/sc/source/core/data/documentimport.cxx b/sc/source/core/data/documentimport.cxx
index a5fa521..93b43b0 100644
--- a/sc/source/core/data/documentimport.cxx
+++ b/sc/source/core/data/documentimport.cxx
@@ -216,7 +216,7 @@ void ScDocumentImport::setFormulaCell(const ScAddress& rPos, const ScTokenArray&
sc::CellStoreType& rCells = pTab->aCol[rPos.Col()].maCells;
pBlockPos->miCellPos =
- rCells.set(pBlockPos->miCellPos, rPos.Row(), new ScFormulaCell(&mpImpl->mrDoc, rPos, &rArray));
+ rCells.set(pBlockPos->miCellPos, rPos.Row(), new ScFormulaCell(&mpImpl->mrDoc, rPos, rArray));
}
void ScDocumentImport::setFormulaCell(const ScAddress& rPos, ScFormulaCell* pCell)
@@ -254,7 +254,7 @@ void ScDocumentImport::setMatrixCells(
sc::CellStoreType& rCells = pTab->aCol[rBasePos.Col()].maCells;
// Set the master cell.
- ScFormulaCell* pCell = new ScFormulaCell(&mpImpl->mrDoc, rBasePos, &rArray, eGram, MM_FORMULA);
+ ScFormulaCell* pCell = new ScFormulaCell(&mpImpl->mrDoc, rBasePos, rArray, eGram, MM_FORMULA);
pBlockPos->miCellPos =
rCells.set(pBlockPos->miCellPos, rBasePos.Row(), pCell);
@@ -283,7 +283,7 @@ void ScDocumentImport::setMatrixCells(
aRefData.SetAddress(rBasePos, aPos);
t->GetSingleRef() = aRefData;
boost::scoped_ptr<ScTokenArray> pTokArr(aArr.Clone());
- pCell = new ScFormulaCell(&mpImpl->mrDoc, aPos, pTokArr.get(), eGram, MM_REFERENCE);
+ pCell = new ScFormulaCell(&mpImpl->mrDoc, aPos, *pTokArr, eGram, MM_REFERENCE);
pBlockPos->miCellPos =
rCells.set(pBlockPos->miCellPos, aPos.Row(), pCell);
}
@@ -303,7 +303,7 @@ void ScDocumentImport::setMatrixCells(
aRefData.SetAddress(rBasePos, aPos);
t->GetSingleRef() = aRefData;
boost::scoped_ptr<ScTokenArray> pTokArr(aArr.Clone());
- pCell = new ScFormulaCell(&mpImpl->mrDoc, aPos, pTokArr.get(), eGram, MM_REFERENCE);
+ pCell = new ScFormulaCell(&mpImpl->mrDoc, aPos, *pTokArr, eGram, MM_REFERENCE);
pBlockPos->miCellPos =
rColCells.set(pBlockPos->miCellPos, aPos.Row(), pCell);
}
diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx
index 4f27592..15c3b98 100644
--- a/sc/source/core/data/formulacell.cxx
+++ b/sc/source/core/data/formulacell.cxx
@@ -429,6 +429,31 @@ void ScFormulaCellGroup::compileCode(
// ============================================================================
+ScFormulaCell::ScFormulaCell( ScDocument* pDoc, const ScAddress& rPos ) :
+ eTempGrammar(formula::FormulaGrammar::GRAM_DEFAULT),
+ pCode(new ScTokenArray),
+ pDocument(pDoc),
+ pPrevious(0),
+ pNext(0),
+ pPreviousTrack(0),
+ pNextTrack(0),
+ nSeenInIteration(0),
+ cMatrixFlag(MM_NONE),
+ nFormatType(NUMBERFORMAT_NUMBER),
+ bDirty(false),
+ bChanged(false),
+ bRunning(false),
+ bCompile(false),
+ bSubTotal(false),
+ bIsIterCell(false),
+ bInChangeTrack(false),
+ bTableOpDirty(false),
+ bNeedListening(false),
+ mbNeedsNumberFormat(false),
+ aPos(rPos)
+{
+}
+
ScFormulaCell::ScFormulaCell( ScDocument* pDoc, const ScAddress& rPos,
const OUString& rFormula,
const FormulaGrammar::Grammar eGrammar,
@@ -461,22 +486,20 @@ ScFormulaCell::ScFormulaCell( ScDocument* pDoc, const ScAddress& rPos,
pCode = new ScTokenArray;
}
-// Used by import filters
-
-ScFormulaCell::ScFormulaCell( ScDocument* pDoc, const ScAddress& rPos,
- const ScTokenArray* pArr,
- const FormulaGrammar::Grammar eGrammar, sal_uInt8 cInd ) :
+ScFormulaCell::ScFormulaCell(
+ ScDocument* pDoc, const ScAddress& rPos, const ScTokenArray& rArray,
+ const FormulaGrammar::Grammar eGrammar, sal_uInt8 cMatInd ) :
eTempGrammar( eGrammar),
- pCode( pArr ? new ScTokenArray( *pArr ) : new ScTokenArray ),
+ pCode(new ScTokenArray(rArray)),
pDocument( pDoc ),
pPrevious(0),
pNext(0),
pPreviousTrack(0),
pNextTrack(0),
nSeenInIteration(0),
- cMatrixFlag ( cInd ),
+ cMatrixFlag ( cMatInd ),
nFormatType ( NUMBERFORMAT_NUMBER ),
- bDirty( NULL != pArr ), // -> Because of the use of the Auto Pilot Function was: cInd != 0
+ bDirty( true ),
bChanged( false ),
bRunning( false ),
bCompile( false ),
@@ -2319,7 +2342,10 @@ void setOldCodeToUndo(
if (pUndoDoc->GetCellType(aUndoPos) == CELLTYPE_FORMULA)
return;
- ScFormulaCell* pFCell = new ScFormulaCell(pUndoDoc, aUndoPos, pOldCode, eTempGrammar, cMatrixFlag);
+ ScFormulaCell* pFCell =
+ new ScFormulaCell(
+ pUndoDoc, aUndoPos, pOldCode ? *pOldCode : ScTokenArray(), eTempGrammar, cMatrixFlag);
+
pFCell->SetResultToken(NULL); // to recognize it as changed later (Cut/Paste!)
pUndoDoc->SetFormulaCell(aUndoPos, pFCell);
}
@@ -2919,8 +2945,9 @@ void ScFormulaCell::UpdateTranspose( const ScRange& rSource, const ScAddress& rD
{
if (pUndoDoc)
{
- ScFormulaCell* pFCell = new ScFormulaCell( pUndoDoc, aPos, pOld,
- eTempGrammar, cMatrixFlag);
+ ScFormulaCell* pFCell = new ScFormulaCell(
+ pUndoDoc, aPos, pOld ? *pOld : ScTokenArray(), eTempGrammar, cMatrixFlag);
+
pFCell->aResult.SetToken( NULL); // to recognize it as changed later (Cut/Paste!)
pUndoDoc->SetFormulaCell(aPos, pFCell);
}
diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx
index c94d66a..b44122e 100644
--- a/sc/source/core/data/table2.cxx
+++ b/sc/source/core/data/table2.cxx
@@ -751,7 +751,7 @@ class TransClipHandler
ScTokenArray aArr;
aArr.AddSingleReference(aRef);
- return new ScFormulaCell(&mrClipTab.GetDoc(), rDestPos, &aArr);
+ return new ScFormulaCell(&mrClipTab.GetDoc(), rDestPos, aArr);
}
void setLink(size_t nRow)
@@ -853,7 +853,7 @@ void ScTable::TransposeClip( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
pTransClip->SetFormulaCell(
static_cast<SCCOL>(nRow-nRow1), static_cast<SCROW>(nCol-nCol1),
- new ScFormulaCell(pDestDoc, aDestPos, &aArr));
+ new ScFormulaCell(pDestDoc, aDestPos, aArr));
}
}
else
diff --git a/sc/source/core/data/table3.cxx b/sc/source/core/data/table3.cxx
index a79add4..99d1c8e 100644
--- a/sc/source/core/data/table3.cxx
+++ b/sc/source/core/data/table3.cxx
@@ -1056,7 +1056,7 @@ bool ScTable::DoSubTotals( ScSubTotalParam& rParam )
aArr.AddOpCode( ocClose );
aArr.AddOpCode( ocStop );
ScFormulaCell* pCell = new ScFormulaCell(
- pDocument, ScAddress(nResCols[nResult], iEntry->nDestRow, nTab), &aArr);
+ pDocument, ScAddress(nResCols[nResult], iEntry->nDestRow, nTab), aArr);
SetFormulaCell(nResCols[nResult], iEntry->nDestRow, pCell);
diff --git a/sc/source/core/data/validat.cxx b/sc/source/core/data/validat.cxx
index 5a12649..0adc60a 100644
--- a/sc/source/core/data/validat.cxx
+++ b/sc/source/core/data/validat.cxx
@@ -632,8 +632,8 @@ bool ScValidationData::GetSelectionFromFormula(
if( NULL == pDocument )
return false;
- ScFormulaCell aValidationSrc( pDocument, rPos, &rTokArr,
- formula::FormulaGrammar::GRAM_DEFAULT, MM_FORMULA);
+ ScFormulaCell aValidationSrc(
+ pDocument, rPos, rTokArr, formula::FormulaGrammar::GRAM_DEFAULT, MM_FORMULA);
// Make sure the formula gets interpreted and a result is delivered,
// regardless of the AutoCalc setting.
diff --git a/sc/source/core/tool/consoli.cxx b/sc/source/core/tool/consoli.cxx
index 25492bb..3dbe8f9 100644
--- a/sc/source/core/tool/consoli.cxx
+++ b/sc/source/core/tool/consoli.cxx
@@ -735,7 +735,7 @@ void ScConsData::OutputToDocument( ScDocument* pDestDoc, SCCOL nCol, SCROW nRow,
aRefArr.AddOpCode(ocStop);
ScAddress aDest( sal::static_int_cast<SCCOL>(nCol+nArrX),
sal::static_int_cast<SCROW>(nRow+nArrY+nPos), nTab );
- ScFormulaCell* pCell = new ScFormulaCell( pDestDoc, aDest, &aRefArr );
+ ScFormulaCell* pCell = new ScFormulaCell(pDestDoc, aDest, aRefArr);
pDestDoc->SetFormulaCell(aDest, pCell);
}
}
@@ -755,7 +755,7 @@ void ScConsData::OutputToDocument( ScDocument* pDestDoc, SCCOL nCol, SCROW nRow,
aArr.AddDoubleReference(aCRef);
aArr.AddOpCode(ocClose);
aArr.AddOpCode(ocStop);
- ScFormulaCell* pCell = new ScFormulaCell( pDestDoc, aDest, &aArr );
+ ScFormulaCell* pCell = new ScFormulaCell(pDestDoc, aDest, aArr);
pDestDoc->SetFormulaCell(aDest, pCell);
}
}
diff --git a/sc/source/filter/excel/excform.cxx b/sc/source/filter/excel/excform.cxx
index 74b0ea0..e2e2470 100644
--- a/sc/source/filter/excel/excform.cxx
+++ b/sc/source/filter/excel/excform.cxx
@@ -174,7 +174,7 @@ void ImportExcel::Formula(
if (pResult)
{
- pCell = new ScFormulaCell(&rDoc.getDoc(), aScPos, pResult);
+ pCell = new ScFormulaCell(&rDoc.getDoc(), aScPos, *pResult);
rDoc.getDoc().EnsureTable(aScPos.Tab());
rDoc.setFormulaCell(aScPos, pCell);
SetLastFormula(aScPos.Col(), aScPos.Row(), fCurVal, nXF, pCell);
diff --git a/sc/source/filter/excel/impop.cxx b/sc/source/filter/excel/impop.cxx
index b86ea72..8db86c3 100644
--- a/sc/source/filter/excel/impop.cxx
+++ b/sc/source/filter/excel/impop.cxx
@@ -390,7 +390,7 @@ void ImportExcel::ReadBoolErr()
double fValue;
const ScTokenArray* pScTokArr = ErrorToFormula( nType, nValue, fValue );
- ScFormulaCell* pCell = new ScFormulaCell( pD, aScPos, pScTokArr );
+ ScFormulaCell* pCell = pScTokArr ? new ScFormulaCell(pD, aScPos, *pScTokArr) : new ScFormulaCell(pD, aScPos);
pCell->SetHybridDouble( fValue );
GetDoc().SetFormulaCell(aScPos, pCell);
}
diff --git a/sc/source/filter/excel/xipivot.cxx b/sc/source/filter/excel/xipivot.cxx
index 99ceb86..30af343 100644
--- a/sc/source/filter/excel/xipivot.cxx
+++ b/sc/source/filter/excel/xipivot.cxx
@@ -121,7 +121,7 @@ void XclImpPCItem::WriteToSource( XclImpRoot& rRoot, const ScAddress& rScPos ) c
sal_uInt8 nErrCode = static_cast< sal_uInt8 >( *pnError );
const ScTokenArray* pScTokArr = rRoot.GetOldFmlaConverter().GetBoolErr(
XclTools::ErrorToEnum( fValue, EXC_BOOLERR_ERROR, nErrCode ) );
- ScFormulaCell* pCell = new ScFormulaCell(&rDoc.getDoc(), rScPos, pScTokArr);
+ ScFormulaCell* pCell = pScTokArr ? new ScFormulaCell(&rDoc.getDoc(), rScPos, *pScTokArr) : new ScFormulaCell(&rDoc.getDoc(), rScPos);
pCell->SetHybridDouble( fValue );
rDoc.setFormulaCell(rScPos, pCell);
}
diff --git a/sc/source/filter/lotus/lotimpop.cxx b/sc/source/filter/lotus/lotimpop.cxx
index ad27360..f8fc773 100644
--- a/sc/source/filter/lotus/lotimpop.cxx
+++ b/sc/source/filter/lotus/lotimpop.cxx
@@ -290,7 +290,7 @@ ScFormulaCell *ImportLotus::Formulacell( sal_uInt16 n )
aConv.SetWK3();
aConv.Convert( pErg, nRest );
- ScFormulaCell* pCell = new ScFormulaCell( pD, aAddr, pErg );
+ ScFormulaCell* pCell = pErg ? new ScFormulaCell(pD, aAddr, *pErg) : new ScFormulaCell(pD, aAddr);
pCell->AddRecalcMode( RECALCMODE_ONLOAD_ONCE );
pD->EnsureTable(aAddr.Tab());
pD->SetFormulaCell(aAddr, pCell);
diff --git a/sc/source/filter/lotus/op.cxx b/sc/source/filter/lotus/op.cxx
index 9e777a7..c42211d 100644
--- a/sc/source/filter/lotus/op.cxx
+++ b/sc/source/filter/lotus/op.cxx
@@ -169,7 +169,7 @@ void OP_Formula( SvStream& r, sal_uInt16 /*n*/ )
if (ValidColRow( static_cast<SCCOL>(nCol), nRow))
{
- ScFormulaCell* pCell = new ScFormulaCell( pLotusRoot->pDoc, aAddress, pErg );
+ ScFormulaCell* pCell = new ScFormulaCell(pLotusRoot->pDoc, aAddress, *pErg);
pCell->AddRecalcMode( RECALCMODE_ONLOAD_ONCE );
pDoc->EnsureTable(nTab);
pDoc->SetFormulaCell(ScAddress(nCol,nRow,nTab), pCell);
@@ -413,7 +413,7 @@ void OP_Formula123( SvStream& r, sal_uInt16 n )
if (ValidColRow( static_cast<SCCOL>(nCol), nRow) && nTab <= pDoc->GetMaxTableNumber())
{
- ScFormulaCell* pCell = new ScFormulaCell( pLotusRoot->pDoc, aAddress, pErg );
+ ScFormulaCell* pCell = new ScFormulaCell(pLotusRoot->pDoc, aAddress, *pErg);
pCell->AddRecalcMode( RECALCMODE_ONLOAD_ONCE );
pDoc->EnsureTable(nTab);
pDoc->SetFormulaCell(ScAddress(nCol,nRow,nTab), pCell);
diff --git a/sc/source/filter/oox/formulabuffer.cxx b/sc/source/filter/oox/formulabuffer.cxx
index cf5b73e..3dde87b 100644
--- a/sc/source/filter/oox/formulabuffer.cxx
+++ b/sc/source/filter/oox/formulabuffer.cxx
@@ -173,7 +173,7 @@ void FormulaBuffer::applySharedFormulas( sal_Int32 nTab )
ScAddress aPos;
ScUnoConversion::FillScAddress(aPos, rAddr);
- ScFormulaCell* pCell = new ScFormulaCell(&rDoc.getDoc(), aPos, pArray);
+ ScFormulaCell* pCell = new ScFormulaCell(&rDoc.getDoc(), aPos, *pArray);
rDoc.setFormulaCell(aPos, pCell);
if (it->maCellValue.isEmpty())
{
diff --git a/sc/source/filter/orcus/interface.cxx b/sc/source/filter/orcus/interface.cxx
index 1372d775..df8c992 100644
--- a/sc/source/filter/orcus/interface.cxx
+++ b/sc/source/filter/orcus/interface.cxx
@@ -358,7 +358,7 @@ void ScOrcusSheet::set_shared_formula(
maFormulaGroups.set(sindex, pArray);
- ScFormulaCell* pCell = new ScFormulaCell(&mrDoc.getDoc(), aPos, pArray);
+ ScFormulaCell* pCell = new ScFormulaCell(&mrDoc.getDoc(), aPos, *pArray);
mrDoc.setFormulaCell(aPos, pCell);
cellInserted();
@@ -381,7 +381,7 @@ void ScOrcusSheet::set_shared_formula(os::row_t row, os::col_t col, size_t sinde
if (!pArray)
return;
- ScFormulaCell* pCell = new ScFormulaCell(&mrDoc.getDoc(), aPos, pArray);
+ ScFormulaCell* pCell = new ScFormulaCell(&mrDoc.getDoc(), aPos, *pArray);
mrDoc.setFormulaCell(aPos, pCell);
cellInserted();
diff --git a/sc/source/filter/qpro/qpro.cxx b/sc/source/filter/qpro/qpro.cxx
index bff702b..77dc5dca 100644
--- a/sc/source/filter/qpro/qpro.cxx
+++ b/sc/source/filter/qpro/qpro.cxx
@@ -110,7 +110,7 @@ FltError ScQProReader::readSheet( SCTAB nTab, ScDocument* pDoc, ScQProStyle *pSt
eRet = eERR_FORMAT;
else
{
- ScFormulaCell *pFormula = new ScFormulaCell( pDoc, aAddr, pArray );
+ ScFormulaCell* pFormula = new ScFormulaCell(pDoc, aAddr, *pArray);
nStyle = nStyle >> 3;
pFormula->AddRecalcMode( RECALCMODE_ONLOAD_ONCE );
pStyle->SetFormat( pDoc, nCol, nRow, nTab, nStyle );
diff --git a/sc/source/filter/xcl97/XclImpChangeTrack.cxx b/sc/source/filter/xcl97/XclImpChangeTrack.cxx
index a2f1dde..4892861 100644
--- a/sc/source/filter/xcl97/XclImpChangeTrack.cxx
+++ b/sc/source/filter/xcl97/XclImpChangeTrack.cxx
@@ -272,7 +272,7 @@ void XclImpChangeTrack::ReadCell(
if( pStrm->IsValid() && pTokenArray )
{
rCell.meType = CELLTYPE_FORMULA;
- rCell.mpFormula = new ScFormulaCell(GetDocPtr(), rPosition, pTokenArray);
+ rCell.mpFormula = new ScFormulaCell(GetDocPtr(), rPosition, *pTokenArray);
}
delete pTokenArray;
}
... etc. - the rest is truncated
More information about the Libreoffice-commits
mailing list