summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTor Lillqvist <tml@collabora.com>2017-10-04 00:12:31 +0300
committerDennis Francis <dennis.francis@collabora.co.uk>2017-11-21 13:49:51 +0530
commitae4067e9054f2aba8a8c65a5ae78bf551c0cdd10 (patch)
tree2101d336fae67d448448ddc6a72e671394894d8a
parentd2e2f4b7b69c97f8741bbaadbf2a88219c4ce483 (diff)
Introduce ScInterpreterContext
Possibly later things that need to be thread-local can be handled through the ScInterpreterContext. Why handle some thread-local things through the ScDocument::maNonThreaded and ScDocument::maThreadSpecific mechanism, and others through this ScInterpreterContext? Good question. Share SvNumberFormatter across worker threads and use mutex to protect SvNumberFormatter::IsNumberFormat() Change-Id: I372e5fbd9a19785f55f0faf4a4bedc5fc1ef3e03
-rw-r--r--sc/inc/column.hxx5
-rw-r--r--sc/inc/dociter.hxx11
-rw-r--r--sc/inc/document.hxx9
-rw-r--r--sc/inc/formulacell.hxx4
-rw-r--r--sc/inc/interpretercontext.hxx39
-rw-r--r--sc/inc/table.hxx5
-rw-r--r--sc/source/core/data/column.cxx8
-rw-r--r--sc/source/core/data/column2.cxx7
-rw-r--r--sc/source/core/data/column3.cxx18
-rw-r--r--sc/source/core/data/dociter.cxx24
-rw-r--r--sc/source/core/data/documen2.cxx1
-rw-r--r--sc/source/core/data/documen8.cxx4
-rw-r--r--sc/source/core/data/document.cxx17
-rw-r--r--sc/source/core/data/formulacell.cxx38
-rw-r--r--sc/source/core/data/simpleformulacalc.cxx2
-rw-r--r--sc/source/core/data/table1.cxx4
-rw-r--r--sc/source/core/data/table2.cxx6
-rw-r--r--sc/source/core/data/table4.cxx4
-rw-r--r--sc/source/core/inc/interpre.hxx4
-rw-r--r--sc/source/core/tool/formulagroup.cxx2
-rw-r--r--sc/source/core/tool/interpr1.cxx34
-rw-r--r--sc/source/core/tool/interpr4.cxx13
-rw-r--r--sc/source/core/tool/interpr5.cxx4
-rw-r--r--sc/source/core/tool/interpr6.cxx16
-rw-r--r--sc/source/filter/excel/xepivot.cxx2
-rw-r--r--sc/source/filter/excel/xicontent.cxx2
-rw-r--r--sc/source/ui/docshell/externalrefmgr.cxx2
-rw-r--r--svl/source/numbers/zforlist.cxx2
28 files changed, 181 insertions, 106 deletions
diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index 67bc6c348c5e..44bee716bf18 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -106,6 +106,7 @@ class ScDocumentImport;
class ScHint;
enum class ScMF;
struct ScFilterEntries;
+struct ScInterpreterContext;
struct ScNeededSizeOptions
{
@@ -447,7 +448,7 @@ public:
const ScPatternAttr* GetPattern( SCROW nRow ) const;
const ScPatternAttr* GetMostUsedPattern( SCROW nStartRow, SCROW nEndRow ) const;
- sal_uInt32 GetNumberFormat( SCROW nRow ) const;
+ sal_uInt32 GetNumberFormat( const ScInterpreterContext& rContext, SCROW nRow ) const;
sal_uInt32 GetNumberFormat( SCROW nStartRow, SCROW nEndRow ) const;
void MergeSelectionPattern( ScMergePatternState& rState, const ScMarkData& rMark, bool bDeep ) const;
@@ -582,7 +583,7 @@ public:
void SetFormulaResults( SCROW nRow, const double* pResults, size_t nLen );
void SetFormulaResults( SCROW nRow, const formula::FormulaConstTokenRef* pResults, size_t nLen );
- void CalculateInThread( SCROW nRow, size_t nLen, unsigned nThisThread, unsigned nThreadsTotal);
+ void CalculateInThread( const ScInterpreterContext& rContext, SCROW nRow, size_t nLen, unsigned nThisThread, unsigned nThreadsTotal );
void HandleStuffAfterParallelCalculation( SCROW nRow, size_t nLen );
void SetNumberFormat( SCROW nRow, sal_uInt32 nNumberFormat );
diff --git a/sc/inc/dociter.hxx b/sc/inc/dociter.hxx
index 544e64ebc9c1..904f471c3c4f 100644
--- a/sc/inc/dociter.hxx
+++ b/sc/inc/dociter.hxx
@@ -45,6 +45,7 @@ struct ScQueryParam;
struct ScDBQueryParamInternal;
struct ScDBQueryParamMatrix;
class ScFormulaCell;
+struct ScInterpreterContext;
class ScValueIterator // walk through all values in an area
{
@@ -84,7 +85,7 @@ public:
ScDocument* pDocument, const ScRange& rRange, SubtotalFlags nSubTotalFlags = SubtotalFlags::NONE,
bool bTextAsZero = false );
- void GetCurNumFmtInfo( short& nType, sal_uLong& nIndex );
+ void GetCurNumFmtInfo( const ScInterpreterContext& rContext, short& nType, sal_uLong& nIndex );
/// Does NOT reset rValue if no value found!
bool GetFirst( double& rValue, FormulaError& rErr );
@@ -125,7 +126,7 @@ private:
{
typedef std::pair<sc::CellStoreType::const_iterator,size_t> PositionType;
public:
- DataAccessInternal(ScDBQueryParamInternal* pParam, ScDocument* pDoc);
+ DataAccessInternal(ScDBQueryParamInternal* pParam, ScDocument* pDoc, const ScInterpreterContext& rContext);
virtual ~DataAccessInternal() override;
virtual bool getCurrent(Value& rValue) override;
virtual bool getFirst(Value& rValue) override;
@@ -139,6 +140,7 @@ private:
PositionType maCurPos;
ScDBQueryParamInternal* mpParam;
ScDocument* mpDoc;
+ const ScInterpreterContext& mrContext;
const ScAttrArray* pAttrArray;
sal_uLong nNumFormat; // for CalcAsShown
sal_uLong nNumFmtIndex;
@@ -171,7 +173,7 @@ private:
::std::unique_ptr<DataAccess> mpData;
public:
- ScDBQueryDataIterator(ScDocument* pDocument, ScDBQueryParamBase* pParam);
+ ScDBQueryDataIterator(ScDocument* pDocument, const ScInterpreterContext& rContext, ScDBQueryParamBase* pParam);
/// Does NOT reset rValue if no value found!
bool GetFirst(Value& rValue);
/// Does NOT reset rValue if no value found!
@@ -266,6 +268,7 @@ class ScQueryCellIterator // walk through all non-empty cells in an ar
std::unique_ptr<ScQueryParam> mpParam;
ScDocument* pDoc;
+ const ScInterpreterContext& mrContext;
SCTAB nTab;
SCCOL nCol;
SCROW nRow;
@@ -292,7 +295,7 @@ class ScQueryCellIterator // walk through all non-empty cells in an ar
bool BinarySearch();
public:
- ScQueryCellIterator(ScDocument* pDocument, SCTAB nTable,
+ ScQueryCellIterator(ScDocument* pDocument, const ScInterpreterContext& rContext, SCTAB nTable,
const ScQueryParam& aParam, bool bMod);
// when !bMod, the QueryParam has to be filled
// (bIsString)
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index eef7c4c8df07..f37e8e7d856e 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -26,6 +26,7 @@
#include <com/sun/star/uno/Reference.hxx>
#include <vcl/vclptr.hxx>
#include "scdllapi.h"
+#include "interpretercontext.hxx"
#include "rangelst.hxx"
#include "rangenam.hxx"
#include "tabopparams.hxx"
@@ -559,6 +560,8 @@ public:
SC_DLLPUBLIC void InitDrawLayer( SfxObjectShell* pDocShell = nullptr );
+ SC_DLLPUBLIC ScInterpreterContext GetNonThreadedContext() const;
+
SC_DLLPUBLIC sfx2::LinkManager* GetLinkManager();
SC_DLLPUBLIC const sfx2::LinkManager* GetLinkManager() const;
@@ -1111,10 +1114,10 @@ public:
SC_DLLPUBLIC void GetNumberFormat( SCCOL nCol, SCROW nRow, SCTAB nTab,
sal_uInt32& rFormat ) const;
sal_uInt32 GetNumberFormat( const ScRange& rRange ) const;
- SC_DLLPUBLIC sal_uInt32 GetNumberFormat( const ScAddress& ) const;
+ SC_DLLPUBLIC sal_uInt32 GetNumberFormat( const ScInterpreterContext& rContext, const ScAddress& ) const;
void SetNumberFormat( const ScAddress& rPos, sal_uInt32 nNumberFormat );
- void GetNumberFormatInfo( short& nType, sal_uLong& nIndex, const ScAddress& rPos ) const;
+ void GetNumberFormatInfo( const ScInterpreterContext& rContext, short& nType, sal_uLong& nIndex, const ScAddress& rPos ) const;
SC_DLLPUBLIC const ScFormulaCell* GetFormulaCell( const ScAddress& rPos ) const;
SC_DLLPUBLIC ScFormulaCell* GetFormulaCell( const ScAddress& rPos );
SC_DLLPUBLIC void GetFormula( SCCOL nCol, SCROW nRow, SCTAB nTab, OUString& rFormula ) const;
@@ -2049,7 +2052,7 @@ public:
void SC_DLLPUBLIC SetFormulaResults( const ScAddress& rTopPos, const double* pResults, size_t nLen );
void SC_DLLPUBLIC SetFormulaResults( const ScAddress& rTopPos, const formula::FormulaConstTokenRef* pResults, size_t nLen );
- ScDocumentThreadSpecific CalculateInColumnInThread( const ScAddress& rTopPos, size_t nLen, unsigned nThisThread, unsigned nThreadsTotal);
+ ScDocumentThreadSpecific CalculateInColumnInThread( const ScInterpreterContext& rContext, const ScAddress& rTopPos, size_t nLen, unsigned nThisThread, unsigned nThreadsTotal);
void HandleStuffAfterParallelCalculation( const ScAddress& rTopPos, size_t nLen );
/**
diff --git a/sc/inc/formulacell.hxx b/sc/inc/formulacell.hxx
index 40fe21598e28..0185e2629010 100644
--- a/sc/inc/formulacell.hxx
+++ b/sc/inc/formulacell.hxx
@@ -30,7 +30,7 @@
#include <svl/listener.hxx>
#include "types.hxx"
-
+#include "interpretercontext.hxx"
#include "formularesult.hxx"
namespace sc {
@@ -150,7 +150,7 @@ public:
SCITP_FROM_ITERATION,
SCITP_CLOSE_ITERATION_CIRCLE
};
- void InterpretTail( ScInterpretTailParameter );
+ void InterpretTail( const ScInterpreterContext&, ScInterpretTailParameter );
void HandleStuffAfterParallelCalculation();
diff --git a/sc/inc/interpretercontext.hxx b/sc/inc/interpretercontext.hxx
new file mode 100644
index 000000000000..cbf05349ca5f
--- /dev/null
+++ b/sc/inc/interpretercontext.hxx
@@ -0,0 +1,39 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDED_SC_INC_INTERPRETERCONTEXT_HXX
+#define INCLUDED_SC_INC_INTERPRETERCONTEXT_HXX
+
+class ScDocument;
+class SvNumberFormatter;
+
+struct ScInterpreterContext
+{
+ const ScDocument& mrDoc;
+ SvNumberFormatter* mpFormatter;
+
+ ScInterpreterContext(const ScDocument& rDoc, SvNumberFormatter* pFormatter) :
+ mrDoc(rDoc),
+ mpFormatter(pFormatter)
+ {
+ }
+
+ ~ScInterpreterContext()
+ {
+ }
+
+ SvNumberFormatter* GetFormatTable() const
+ {
+ return mpFormatter;
+ }
+};
+
+#endif // INCLUDED_SC_INC_INTERPRETERCONTEXT_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index 9b04a4d019a4..1f77ae4d2e39 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -116,6 +116,7 @@ class ScRangeName;
class ScDBData;
class ScDocumentImport;
class ScHint;
+struct ScInterpreterContext;
class ScColumnsRange final
{
@@ -672,7 +673,7 @@ public:
const ScPatternAttr* GetPattern( SCCOL nCol, SCROW nRow ) const;
const ScPatternAttr* GetMostUsedPattern( SCCOL nCol, SCROW nStartRow, SCROW nEndRow ) const;
- sal_uInt32 GetNumberFormat( const ScAddress& rPos ) const;
+ sal_uInt32 GetNumberFormat( const ScInterpreterContext& rContext, const ScAddress& rPos ) const;
sal_uInt32 GetNumberFormat( SCCOL nCol, SCROW nRow ) const;
sal_uInt32 GetNumberFormat( SCCOL nCol, SCROW nStartRow, SCROW nEndRow ) const;
@@ -997,7 +998,7 @@ public:
void SetFormulaResults( SCCOL nCol, SCROW nRow, const double* pResults, size_t nLen );
void SetFormulaResults( SCCOL nCol, SCROW nRow, const formula::FormulaConstTokenRef* pResults, size_t nLen );
- void CalculateInColumnInThread( SCCOL nCol, SCROW nRow, size_t nLen, unsigned nThisThread, unsigned nThreadsTotal);
+ void CalculateInColumnInThread( const ScInterpreterContext& rContext, SCCOL nCol, SCROW nRow, size_t nLen, unsigned nThisThread, unsigned nThreadsTotal);
void HandleStuffAfterParallelCalculation( SCCOL nCol, SCROW nRow, size_t nLen);
/**
diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx
index ea93b02156f1..5d021d41aec4 100644
--- a/sc/source/core/data/column.cxx
+++ b/sc/source/core/data/column.cxx
@@ -418,9 +418,9 @@ sal_uInt32 ScColumn::GetNumberFormat( SCROW nStartRow, SCROW nEndRow ) const
return nFormat;
}
-sal_uInt32 ScColumn::GetNumberFormat( SCROW nRow ) const
+sal_uInt32 ScColumn::GetNumberFormat( const ScInterpreterContext& rContext, SCROW nRow ) const
{
- return pAttrArray->GetPattern( nRow )->GetNumberFormat( pDocument->GetFormatTable() );
+ return pAttrArray->GetPattern( nRow )->GetNumberFormat( rContext.GetFormatTable() );
}
SCROW ScColumn::ApplySelectionCache( SfxItemPoolCache* pCache, const ScMarkData& rMark, ScEditDataArray* pDataArray, bool* const pIsChanged )
@@ -1151,7 +1151,7 @@ void ScColumn::CopyStaticToDocument(
// Dont' forget to copy the number formats over. Charts may reference them.
for (SCROW nRow = nRow1; nRow <= nRow2; ++nRow)
{
- sal_uInt32 nNumFmt = GetNumberFormat(nRow);
+ sal_uInt32 nNumFmt = GetNumberFormat(pDocument->GetNonThreadedContext(), nRow);
SvNumberFormatterMergeMap::const_iterator itNum = rMap.find(nNumFmt);
if (itNum != rMap.end())
nNumFmt = itNum->second;
@@ -2890,7 +2890,7 @@ public:
void operator() (size_t nRow, ScFormulaCell* pCell)
{
- sal_uInt32 nFormat = mrCol.GetNumberFormat(nRow);
+ sal_uInt32 nFormat = mrCol.GetNumberFormat(mrCol.GetDoc().GetNonThreadedContext(), nRow);
if( (nFormat % SV_COUNTRY_LANGUAGE_OFFSET) != 0)
// Non-default number format is set.
pCell->SetNeedNumberFormat(false);
diff --git a/sc/source/core/data/column2.cxx b/sc/source/core/data/column2.cxx
index aaa897889603..daeda62bd881 100644
--- a/sc/source/core/data/column2.cxx
+++ b/sc/source/core/data/column2.cxx
@@ -2877,8 +2877,10 @@ void ScColumn::SetFormulaResults( SCROW nRow, const formula::FormulaConstTokenRe
}
}
-void ScColumn::CalculateInThread( SCROW nRow, size_t nLen, unsigned nThisThread, unsigned nThreadsTotal)
+void ScColumn::CalculateInThread( const ScInterpreterContext& rContext, SCROW nRow, size_t nLen, unsigned nThisThread, unsigned nThreadsTotal)
{
+ assert(pDocument->mbThreadedGroupCalcInProgress);
+
sc::CellStoreType::position_type aPos = maCells.position(nRow);
sc::CellStoreType::iterator it = aPos.first;
if (it->type != sc::element_type_formula)
@@ -2901,8 +2903,7 @@ void ScColumn::CalculateInThread( SCROW nRow, size_t nLen, unsigned nThisThread,
ScFormulaCell& rCell = **itCell;
// Here we don't call IncInterpretLevel() and DecInterpretLevel() as this call site is
// always in a threaded calculation.
- assert(pDocument->mbThreadedGroupCalcInProgress);
- rCell.InterpretTail(ScFormulaCell::SCITP_NORMAL);
+ rCell.InterpretTail(rContext, ScFormulaCell::SCITP_NORMAL);
}
}
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index 646210a8e679..9a5a57205436 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -1700,7 +1700,7 @@ bool ScColumn::ParseString(
if (!aParam.mpNumFormatter)
aParam.mpNumFormatter = pDocument->GetFormatTable();
- nIndex = nOldIndex = GetNumberFormat( nRow );
+ nIndex = nOldIndex = GetNumberFormat( pDocument->GetNonThreadedContext(), nRow );
if ( rString.getLength() > 1
&& aParam.mpNumFormatter->GetType(nIndex) != css::util::NumberFormat::TEXT )
cFirstChar = rString[0];
@@ -1922,7 +1922,7 @@ void ScColumn::SetFormula( SCROW nRow, const ScTokenArray& rArray, formula::Form
sc::CellStoreType::iterator it = GetPositionToInsert(nRow);
ScFormulaCell* pCell = new ScFormulaCell(pDocument, aPos, rArray, eGram);
- sal_uInt32 nCellFormat = GetNumberFormat(nRow);
+ sal_uInt32 nCellFormat = GetNumberFormat(pDocument->GetNonThreadedContext(), nRow);
if( (nCellFormat % SV_COUNTRY_LANGUAGE_OFFSET) == 0)
pCell->SetNeedNumberFormat(true);
it = maCells.set(it, nRow, pCell);
@@ -1939,7 +1939,7 @@ void ScColumn::SetFormula( SCROW nRow, const OUString& rFormula, formula::Formul
sc::CellStoreType::iterator it = GetPositionToInsert(nRow);
ScFormulaCell* pCell = new ScFormulaCell(pDocument, aPos, rFormula, eGram);
- sal_uInt32 nCellFormat = GetNumberFormat(nRow);
+ sal_uInt32 nCellFormat = GetNumberFormat(pDocument->GetNonThreadedContext(), nRow);
if( (nCellFormat % SV_COUNTRY_LANGUAGE_OFFSET) == 0)
pCell->SetNeedNumberFormat(true);
it = maCells.set(it, nRow, pCell);
@@ -1954,7 +1954,7 @@ ScFormulaCell* ScColumn::SetFormulaCell(
SCROW nRow, ScFormulaCell* pCell, sc::StartListeningType eListenType )
{
sc::CellStoreType::iterator it = GetPositionToInsert(nRow);
- sal_uInt32 nCellFormat = GetNumberFormat(nRow);
+ sal_uInt32 nCellFormat = GetNumberFormat(pDocument->GetNonThreadedContext(), nRow);
if( (nCellFormat % SV_COUNTRY_LANGUAGE_OFFSET) == 0)
pCell->SetNeedNumberFormat(true);
it = maCells.set(it, nRow, pCell);
@@ -1971,7 +1971,7 @@ void ScColumn::SetFormulaCell(
sc::StartListeningType eListenType )
{
rBlockPos.miCellPos = GetPositionToInsert(rBlockPos.miCellPos, nRow);
- sal_uInt32 nCellFormat = GetNumberFormat(nRow);
+ sal_uInt32 nCellFormat = GetNumberFormat(pDocument->GetNonThreadedContext(), nRow);
if( (nCellFormat % SV_COUNTRY_LANGUAGE_OFFSET) == 0)
pCell->SetNeedNumberFormat(true);
rBlockPos.miCellPos = maCells.set(rBlockPos.miCellPos, nRow, pCell);
@@ -2002,7 +2002,7 @@ bool ScColumn::SetFormulaCells( SCROW nRow, std::vector<ScFormulaCell*>& rCells
for (size_t i = 0, n = rCells.size(); i < n; ++i)
{
SCROW nThisRow = nRow + i;
- sal_uInt32 nFmt = GetNumberFormat(nThisRow);
+ sal_uInt32 nFmt = GetNumberFormat(pDocument->GetNonThreadedContext(), nThisRow);
if ((nFmt % SV_COUNTRY_LANGUAGE_OFFSET) == 0)
rCells[i]->SetNeedNumberFormat(true);
}
@@ -2055,7 +2055,7 @@ class FilterEntriesHandler
{
SvNumberFormatter* pFormatter = mrColumn.GetDoc().GetFormatTable();
OUString aStr;
- sal_uLong nFormat = mrColumn.GetNumberFormat(nRow);
+ sal_uLong nFormat = mrColumn.GetNumberFormat(mrColumn.GetDoc().GetNonThreadedContext(), nRow);
ScCellFormat::GetInputString(rCell, nFormat, aStr, *pFormatter, &mrColumn.GetDoc());
if (rCell.hasString())
@@ -2543,7 +2543,7 @@ void ScColumn::GetString( SCROW nRow, OUString& rString ) const
if (aCell.meType == CELLTYPE_FORMULA)
aCell.mpFormula->MaybeInterpret();
- sal_uLong nFormat = GetNumberFormat(nRow);
+ sal_uLong nFormat = GetNumberFormat(pDocument->GetNonThreadedContext(), nRow);
Color* pColor = nullptr;
ScCellFormat::GetString(aCell, nFormat, rString, &pColor, *(pDocument->GetFormatTable()), pDocument);
}
@@ -2564,7 +2564,7 @@ double* ScColumn::GetValueCell( SCROW nRow )
void ScColumn::GetInputString( SCROW nRow, OUString& rString ) const
{
ScRefCellValue aCell = GetCellValue(nRow);
- sal_uLong nFormat = GetNumberFormat(nRow);
+ sal_uLong nFormat = GetNumberFormat(pDocument->GetNonThreadedContext(), nRow);
ScCellFormat::GetInputString(aCell, nFormat, rString, *(pDocument->GetFormatTable()), pDocument);
}
diff --git a/sc/source/core/data/dociter.cxx b/sc/source/core/data/dociter.cxx
index 358774153027..fa7f9dfb8c05 100644
--- a/sc/source/core/data/dociter.cxx
+++ b/sc/source/core/data/dociter.cxx
@@ -262,14 +262,14 @@ bool ScValueIterator::GetThis(double& rValue, FormulaError& rErr)
}
}
-void ScValueIterator::GetCurNumFmtInfo( short& nType, sal_uLong& nIndex )
+void ScValueIterator::GetCurNumFmtInfo( const ScInterpreterContext& rContext, short& nType, sal_uLong& nIndex )
{
if (!bNumValid && mnTab < pDoc->GetTableCount())
{
SCROW nCurRow = GetRow();
const ScColumn* pCol = &(pDoc->maTabs[mnTab])->aCol[mnCol];
- nNumFmtIndex = pCol->GetNumberFormat(nCurRow);
- nNumFmtType = pDoc->GetFormatTable()->GetType( nNumFmtIndex );
+ nNumFmtIndex = pCol->GetNumberFormat(rContext, nCurRow);
+ nNumFmtType = rContext.GetFormatTable()->GetType( nNumFmtIndex );
bNumValid = true;
}
@@ -334,11 +334,12 @@ bool ScDBQueryDataIterator::IsQueryValid(
return rDoc.maTabs[nTab]->ValidQuery(nRow, rParam, pCell);
}
-ScDBQueryDataIterator::DataAccessInternal::DataAccessInternal(ScDBQueryParamInternal* pParam, ScDocument* pDoc)
+ScDBQueryDataIterator::DataAccessInternal::DataAccessInternal(ScDBQueryParamInternal* pParam, ScDocument* pDoc, const ScInterpreterContext& rContext)
: DataAccess()
, mpCells(nullptr)
, mpParam(pParam)
, mpDoc(pDoc)
+ , mrContext(rContext)
, pAttrArray(nullptr)
, nNumFormat(0) // Initialized in GetNumberFormat
, nNumFmtIndex(0)
@@ -432,7 +433,7 @@ bool ScDBQueryDataIterator::DataAccessInternal::getCurrent(Value& rValue)
rValue.mfValue = aCell.mpFormula->GetValue();
rValue.mbIsNumber = true;
mpDoc->GetNumberFormatInfo(
- nNumFmtType, nNumFmtIndex, ScAddress(nCol, nRow, nTab));
+ mrContext, nNumFmtType, nNumFmtIndex, ScAddress(nCol, nRow, nTab));
rValue.mnError = aCell.mpFormula->GetErrCode();
return true; // Found it!
}
@@ -744,7 +745,7 @@ ScDBQueryDataIterator::Value::Value() :
::rtl::math::setNan(&mfValue);
}
-ScDBQueryDataIterator::ScDBQueryDataIterator(ScDocument* pDocument, ScDBQueryParamBase* pParam) :
+ScDBQueryDataIterator::ScDBQueryDataIterator(ScDocument* pDocument, const ScInterpreterContext& rContext, ScDBQueryParamBase* pParam) :
mpParam (pParam)
{
switch (mpParam->GetType())
@@ -752,7 +753,7 @@ ScDBQueryDataIterator::ScDBQueryDataIterator(ScDocument* pDocument, ScDBQueryPar
case ScDBQueryParamBase::INTERNAL:
{
ScDBQueryParamInternal* p = static_cast<ScDBQueryParamInternal*>(pParam);
- mpData.reset(new DataAccessInternal(p, pDocument));
+ mpData.reset(new DataAccessInternal(p, pDocument, rContext));
}
break;
case ScDBQueryParamBase::MATRIX:
@@ -1046,10 +1047,11 @@ bool ScCellIterator::next()
return getCurrent();
}
-ScQueryCellIterator::ScQueryCellIterator(ScDocument* pDocument, SCTAB nTable,
+ScQueryCellIterator::ScQueryCellIterator(ScDocument* pDocument, const ScInterpreterContext& rContext, SCTAB nTable,
const ScQueryParam& rParam, bool bMod ) :
mpParam(new ScQueryParam(rParam)),
pDoc( pDocument ),
+ mrContext( rContext ),
nTab( nTable),
nStopOnMismatch( nStopOnMismatchDisabled ),
nTestEqualCondition( nTestEqualConditionDisabled ),
@@ -1681,7 +1683,7 @@ bool ScQueryCellIterator::BinarySearch()
if (aPos.first->type == sc::element_type_string || aPos.first->type == sc::element_type_edittext)
{
aCell = sc::toRefCell(aPos.first, aPos.second);
- sal_uLong nFormat = pCol->GetNumberFormat(nRow);
+ sal_uLong nFormat = pCol->GetNumberFormat(mrContext, nRow);
OUString aCellStr;
ScCellFormat::GetInputString(aCell, nFormat, aCellStr, rFormatter, pDoc);
sal_Int32 nTmp = pCollator->compareString(aCellStr, rEntry.GetQueryItem().maString.getString());
@@ -1715,7 +1717,7 @@ bool ScQueryCellIterator::BinarySearch()
aCell = aCellData.first;
if (aCell.hasString())
{
- sal_uLong nFormat = pCol->GetNumberFormat(aCellData.second);
+ sal_uLong nFormat = pCol->GetNumberFormat(mrContext, aCellData.second);
OUString aStr;
ScCellFormat::GetInputString(aCell, nFormat, aStr, rFormatter, pDoc);
aLastInRangeString = aStr;
@@ -1814,7 +1816,7 @@ bool ScQueryCellIterator::BinarySearch()
else if (bStr && bByString)
{
OUString aCellStr;
- sal_uLong nFormat = pCol->GetNumberFormat(aCellData.second);
+ sal_uLong nFormat = pCol->GetNumberFormat(mrContext, aCellData.second);
ScCellFormat::GetInputString(aCell, nFormat, aCellStr, rFormatter, pDoc);
nRes = pCollator->compareString(aCellStr, rEntry.GetQueryItem().maString.getString());
diff --git a/sc/source/core/data/documen2.cxx b/sc/source/core/data/documen2.cxx
index 283c082199b2..b15ee591a7e2 100644
--- a/sc/source/core/data/documen2.cxx
+++ b/sc/source/core/data/documen2.cxx
@@ -502,6 +502,7 @@ void ScDocument::InitClipPtrs( ScDocument* pSourceDoc )
SvNumberFormatter* ScDocument::GetFormatTable() const
{
+ assert(!mbThreadedGroupCalcInProgress);
return mxPoolHelper->GetFormTable();
}
diff --git a/sc/source/core/data/documen8.cxx b/sc/source/core/data/documen8.cxx
index b29de4004c90..8bf1de3fb191 100644
--- a/sc/source/core/data/documen8.cxx
+++ b/sc/source/core/data/documen8.cxx
@@ -427,7 +427,7 @@ void ScDocument::SetFormulaResults(
pTab->SetFormulaResults(rTopPos.Col(), rTopPos.Row(), pResults, nLen);
}
-ScDocumentThreadSpecific ScDocument::CalculateInColumnInThread( const ScAddress& rTopPos, size_t nLen, unsigned nThisThread, unsigned nThreadsTotal)
+ScDocumentThreadSpecific ScDocument::CalculateInColumnInThread( const ScInterpreterContext& rContext, const ScAddress& rTopPos, size_t nLen, unsigned nThisThread, unsigned nThreadsTotal)
{
ScTable* pTab = FetchTable(rTopPos.Tab());
if (!pTab)
@@ -436,7 +436,7 @@ ScDocumentThreadSpecific ScDocument::CalculateInColumnInThread( const ScAddress&
assert(mbThreadedGroupCalcInProgress);
maThreadSpecific.SetupFromNonThreadedData(maNonThreaded);
- pTab->CalculateInColumnInThread(rTopPos.Col(), rTopPos.Row(), nLen, nThisThread, nThreadsTotal);
+ pTab->CalculateInColumnInThread(rContext, rTopPos.Col(), rTopPos.Row(), nLen, nThisThread, nThreadsTotal);
assert(mbThreadedGroupCalcInProgress);
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index 185115ac8ad7..f15107bc3fe7 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -3702,13 +3702,13 @@ sal_uInt32 ScDocument::GetNumberFormat( const ScRange& rRange ) const
return nFormat;
}
-sal_uInt32 ScDocument::GetNumberFormat( const ScAddress& rPos ) const
+sal_uInt32 ScDocument::GetNumberFormat( const ScInterpreterContext& rContext, const ScAddress& rPos ) const
{
SCTAB nTab = rPos.Tab();
if (!TableExists(nTab))
return 0;
- return maTabs[nTab]->GetNumberFormat( rPos );
+ return maTabs[nTab]->GetNumberFormat( rContext, rPos );
}
void ScDocument::SetNumberFormat( const ScAddress& rPos, sal_uInt32 nNumberFormat )
@@ -3720,14 +3720,14 @@ void ScDocument::SetNumberFormat( const ScAddress& rPos, sal_uInt32 nNumberForma
maTabs[nTab]->SetNumberFormat(rPos.Col(), rPos.Row(), nNumberFormat);
}
-void ScDocument::GetNumberFormatInfo( short& nType, sal_uLong& nIndex,
+void ScDocument::GetNumberFormatInfo( const ScInterpreterContext& rContext, short& nType, sal_uLong& nIndex,
const ScAddress& rPos ) const
{
SCTAB nTab = rPos.Tab();
if ( nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] )
{
- nIndex = maTabs[nTab]->GetNumberFormat( rPos );
- nType = GetFormatTable()->GetType( nIndex );
+ nIndex = maTabs[nTab]->GetNumberFormat( rContext, rPos );
+ nType = rContext.GetFormatTable()->GetType( nIndex );
}
else
{
@@ -6769,6 +6769,13 @@ ScMutationGuard::~ScMutationGuard()
#endif
}
+ScInterpreterContext ScDocument::GetNonThreadedContext() const
+{
+ // GetFormatTable() asserts that we are not in a threaded calculation
+ ScInterpreterContext aResult(*this, GetFormatTable());
+ return aResult;
+}
+
thread_local ScDocumentThreadSpecific ScDocument::maThreadSpecific;
ScRecursionHelper& ScDocument::GetRecursionHelper()
diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx
index 7e4a92b1e146..fed52b93ddec 100644
--- a/sc/source/core/data/formulacell.cxx
+++ b/sc/source/core/data/formulacell.cxx
@@ -1528,10 +1528,10 @@ void ScFormulaCell::Interpret()
bool bGroupInterpreted = InterpretFormulaGroup();
aDC.leaveGroup();
if (!bGroupInterpreted)
- InterpretTail( SCITP_NORMAL);
+ InterpretTail( pDocument->GetNonThreadedContext(), SCITP_NORMAL);
#else
if (!InterpretFormulaGroup())
- InterpretTail( SCITP_NORMAL);
+ InterpretTail( pDocument->GetNonThreadedContext(), SCITP_NORMAL);
#endif
pDocument->DecInterpretLevel();
}
@@ -1595,8 +1595,8 @@ void ScFormulaCell::Interpret()
bResumeIteration = false;
// Close circle once.
pDocument->IncInterpretLevel();
- rRecursionHelper.GetList().back().pCell->InterpretTail(
- SCITP_CLOSE_ITERATION_CIRCLE);
+ rRecursionHelper.GetList().back().pCell->InterpretTail( pDocument->GetNonThreadedContext(),
+ SCITP_CLOSE_ITERATION_CIRCLE);
pDocument->DecInterpretLevel();
// Start at 1, init things.
rRecursionHelper.StartIteration();
@@ -1627,7 +1627,7 @@ void ScFormulaCell::Interpret()
{
(*aIter).aPreviousResult = pIterCell->aResult;
pDocument->IncInterpretLevel();
- pIterCell->InterpretTail( SCITP_FROM_ITERATION);
+ pIterCell->InterpretTail( pDocument->GetNonThreadedContext(), SCITP_FROM_ITERATION);
pDocument->DecInterpretLevel();
}
rDone = rDone && !pIterCell->IsDirtyOrInTableOpDirty();
@@ -1699,7 +1699,7 @@ void ScFormulaCell::Interpret()
if (pCell->IsDirtyOrInTableOpDirty())
{
pDocument->IncInterpretLevel();
- pCell->InterpretTail( SCITP_NORMAL);
+ pCell->InterpretTail( pDocument->GetNonThreadedContext(), SCITP_NORMAL);
pDocument->DecInterpretLevel();
if (!pCell->IsDirtyOrInTableOpDirty() && !pCell->IsIterCell())
pCell->bRunning = (*aIter).bOldRunning;
@@ -1744,7 +1744,7 @@ class StackCleaner
};
}
-void ScFormulaCell::InterpretTail( ScInterpretTailParameter eTailParam )
+void ScFormulaCell::InterpretTail( const ScInterpreterContext& rContext, ScInterpretTailParameter eTailParam )
{
RecursionCounter aRecursionCounter( pDocument->GetRecursionHelper(), this);
nSeenInIteration = pDocument->GetRecursionHelper().GetIteration();
@@ -1771,7 +1771,7 @@ void ScFormulaCell::InterpretTail( ScInterpretTailParameter eTailParam )
if( pCode->GetCodeLen() && pDocument )
{
- ScInterpreter* pInterpreter = new ScInterpreter( this, pDocument, aPos, *pCode );
+ ScInterpreter* pInterpreter = new ScInterpreter( this, pDocument, rContext, aPos, *pCode );
StackCleaner aStackCleaner(pInterpreter);
FormulaError nOldErrCode = aResult.GetResultError();
if ( nSeenInIteration == 0 )
@@ -1977,7 +1977,7 @@ void ScFormulaCell::InterpretTail( ScInterpretTailParameter eTailParam )
}
if (bSetFormat && (bForceNumberFormat || ((nFormatIndex % SV_COUNTRY_LANGUAGE_OFFSET) == 0)))
- nFormatIndex = ScGlobal::GetStandardFormat(*pDocument->GetFormatTable(),
+ nFormatIndex = ScGlobal::GetStandardFormat(*rContext.GetFormatTable(),
nFormatIndex, nFormatType);
// Do not replace a General format (which was the reason why
@@ -2164,7 +2164,7 @@ void ScFormulaCell::HandleStuffAfterParallelCalculation()
if ( !pCode->IsRecalcModeAlways() )
pDocument->RemoveFromFormulaTree( this );
- ScInterpreter* pInterpreter = new ScInterpreter( this, pDocument, aPos, *pCode );
+ ScInterpreter* pInterpreter = new ScInterpreter( this, pDocument, pDocument->GetNonThreadedContext(), aPos, *pCode );
StackCleaner aStackCleaner(pInterpreter);
switch (pInterpreter->GetVolatileType())
@@ -4324,6 +4324,9 @@ bool ScFormulaCell::InterpretFormulaGroup()
static const bool bThreadingRequested = std::getenv("CPU_THREADED_CALCULATION");
+ // To temporarilu use threading for sc unit tests regardless of the size of the formula group,
+ // add the condition !std::getenv("LO_TESTNAME") below (with &&), and run with
+ // CPU_THREADED_CALCULATION=yes
if (GetWeight() < ScInterpreter::GetGlobalConfig().mnOpenCLMinimumFormulaGroupSize)
{
mxGroup->meCalcState = sc::GroupCalcDisabled;
@@ -4363,6 +4366,7 @@ bool ScFormulaCell::InterpretFormulaGroup()
const unsigned mnThisThread;
const unsigned mnThreadsTotal;
ScDocument* mpDocument;
+ SvNumberFormatter* mpFormatter;
const ScAddress& mrTopPos;
SCROW mnLength;
@@ -4371,12 +4375,14 @@ bool ScFormulaCell::InterpretFormulaGroup()
unsigned nThisThread,
unsigned nThreadsTotal,
ScDocument* pDocument2,
+ SvNumberFormatter* pFormatter,
const ScAddress& rTopPos,
SCROW nLength) :
comphelper::ThreadTask(rTag),
mnThisThread(nThisThread),
mnThreadsTotal(nThreadsTotal),
mpDocument(pDocument2),
+ mpFormatter(pFormatter),
mrTopPos(rTopPos),
mnLength(nLength)
{
@@ -4384,11 +4390,15 @@ bool ScFormulaCell::InterpretFormulaGroup()
virtual void doWork() override
{
- mpDocument->CalculateInColumnInThread(mrTopPos, mnLength, mnThisThread, mnThreadsTotal).MergeBackIntoNonThreadedData(mpDocument->maNonThreaded);
+ ScInterpreterContext aContext(*mpDocument, mpFormatter);
+
+ mpDocument->CalculateInColumnInThread(aContext, mrTopPos, mnLength, mnThisThread, mnThreadsTotal).MergeBackIntoNonThreadedData(mpDocument->maNonThreaded);
}
};
+ SvNumberFormatter* pNonThreadedFormatter = pDocument->GetNonThreadedContext().GetFormatTable();
+
comphelper::ThreadPool& rThreadPool(comphelper::ThreadPool::getSharedOptimalPool());
sal_Int32 nThreadCount = rThreadPool.getWorkerCount();
@@ -4404,7 +4414,7 @@ bool ScFormulaCell::InterpretFormulaGroup()
std::shared_ptr<comphelper::ThreadTaskTag> aTag = comphelper::ThreadPool::createThreadTaskTag();
for (int i = 0; i < nThreadCount; ++i)
{
- rThreadPool.pushTask(new Executor(aTag, i, nThreadCount, pDocument, mxGroup->mpTopCell->aPos, mxGroup->mnLength));
+ rThreadPool.pushTask(new Executor(aTag, i, nThreadCount, pDocument, pNonThreadedFormatter, mxGroup->mpTopCell->aPos, mxGroup->mnLength));
}
SAL_INFO("sc.threaded", "Joining threads");
@@ -4602,14 +4612,14 @@ bool ScFormulaCell::InterpretInvariantFormulaGroup()
ScCompiler aComp(pDocument, aPos, aCode, pDocument->GetGrammar());
aComp.CompileTokenArray(); // Create RPN token array.
- ScInterpreter aInterpreter(this, pDocument, aPos, aCode);
+ ScInterpreter aInterpreter(this, pDocument, pDocument->GetNonThreadedContext(), aPos, aCode);
aInterpreter.Interpret();
aResult.SetToken(aInterpreter.GetResultToken().get());
}
else
{
// Formula contains no references.
- ScInterpreter aInterpreter(this, pDocument, aPos, *pCode);
+ ScInterpreter aInterpreter(this, pDocument, pDocument->GetNonThreadedContext(), aPos, *pCode);
aInterpreter.Interpret();
aResult.SetToken(aInterpreter.GetResultToken().get());
}
diff --git a/sc/source/core/data/simpleformulacalc.cxx b/sc/source/core/data/simpleformulacalc.cxx
index b1e0f65f9ff7..859114515e5c 100644
--- a/sc/source/core/data/simpleformulacalc.cxx
+++ b/sc/source/core/data/simpleformulacalc.cxx
@@ -44,7 +44,7 @@ void ScSimpleFormulaCalculator::Calculate()
return;
mbCalculated = true;
- ScInterpreter aInt(nullptr, mpDoc, maAddr, *mpCode.get());
+ ScInterpreter aInt(nullptr, mpDoc, mpDoc->GetNonThreadedContext(), maAddr, *mpCode.get());
std::unique_ptr<sfx2::LinkManager> pNewLinkMgr( new sfx2::LinkManager(mpDoc->GetDocumentShell()) );
aInt.SetLinkManager( pNewLinkMgr.get() );
diff --git a/sc/source/core/data/table1.cxx b/sc/source/core/data/table1.cxx
index 961b2f443568..e43ab0efc7ac 100644
--- a/sc/source/core/data/table1.cxx
+++ b/sc/source/core/data/table1.cxx
@@ -2338,12 +2338,12 @@ void ScTable::SetFormulaResults(
aCol[nCol].SetFormulaResults(nRow, pResults, nLen);
}
-void ScTable::CalculateInColumnInThread( SCCOL nCol, SCROW nRow, size_t nLen, unsigned nThisThread, unsigned nThreadsTotal)
+void ScTable::CalculateInColumnInThread( const ScInterpreterContext& rContext, SCCOL nCol, SCROW nRow, size_t nLen, unsigned nThisThread, unsigned nThreadsTotal)
{
if (!ValidCol(nCol))
return;
- aCol[nCol].CalculateInThread( nRow, nLen, nThisThread, nThreadsTotal );
+ aCol[nCol].CalculateInThread( rContext, nRow, nLen, nThisThread, nThreadsTotal );
}
void ScTable::HandleStuffAfterParallelCalculation( SCCOL nCol, SCROW nRow, size_t nLen)
diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx
index 60e05b323be9..56be6df03201 100644
--- a/sc/source/core/data/table2.cxx
+++ b/sc/source/core/data/table2.cxx
@@ -1899,17 +1899,17 @@ const SfxPoolItem* ScTable::GetAttr( SCCOL nCol, SCROW nRow, sal_uInt16 nWhich )
return nullptr;
}
-sal_uInt32 ScTable::GetNumberFormat( const ScAddress& rPos ) const
+sal_uInt32 ScTable::GetNumberFormat( const ScInterpreterContext& rContext, const ScAddress& rPos ) const
{
return ValidColRow(rPos.Col(),rPos.Row()) ?
- aCol[rPos.Col()].GetNumberFormat( rPos.Row() ) :
+ aCol[rPos.Col()].GetNumberFormat( rContext, rPos.Row() ) :
0;
}
sal_uInt32 ScTable::GetNumberFormat( SCCOL nCol, SCROW nRow ) const
{
if (ValidColRow(nCol,nRow))
- return aCol[nCol].GetNumberFormat( nRow );
+ return aCol[nCol].GetNumberFormat( pDocument->GetNonThreadedContext(), nRow );
else
return 0;
}
diff --git a/sc/source/core/data/table4.cxx b/sc/source/core/data/table4.cxx
index 2579545c4c91..45927fe4de8f 100644
--- a/sc/source/core/data/table4.cxx
+++ b/sc/source/core/data/table4.cxx
@@ -1380,14 +1380,14 @@ void ScTable::FillAutoSimple(
return;
}
bBooleanCell = (pDocument->GetFormatTable()->GetType(
- aCol[rCol].GetNumberFormat( nSource)) == css::util::NumberFormat::LOGICAL);
+ aCol[rCol].GetNumberFormat( pDocument->GetNonThreadedContext(), nSource)) == css::util::NumberFormat::LOGICAL);
}
else // rInner&:=nCol, rOuter&:=nRow
{
aSrcCell = aCol[nSource].GetCellValue(rRow);
bBooleanCell = (pDocument->GetFormatTable()->GetType(
- aCol[nSource].GetNumberFormat( rRow)) == css::util::NumberFormat::LOGICAL);
+ aCol[nSource].GetNumberFormat( pDocument->GetNonThreadedContext(), rRow)) == css::util::NumberFormat::LOGICAL);
}
bGetCell = false;
diff --git a/sc/source/core/inc/interpre.hxx b/sc/source/core/inc/interpre.hxx
index 566b3a183977..8a240e617261 100644
--- a/sc/source/core/inc/interpre.hxx
+++ b/sc/source/core/inc/interpre.hxx
@@ -29,6 +29,7 @@
#include <sfx2/linkmgr.hxx>
#include <scdll.hxx>
#include <scdllapi.h>
+#include <interpretercontext.hxx>
#include <types.hxx>
#include <externalrefmgr.hxx>
#include <calcconfig.hxx>
@@ -198,6 +199,7 @@ private:
formula::FormulaTokenIterator aCode;
ScAddress aPos;
ScTokenArray& rArr;
+ const ScInterpreterContext& mrContext;
ScDocument* pDok;
sfx2::LinkManager* mpLinkManager;
svl::SharedStringPool& mrStrPool;
@@ -988,7 +990,7 @@ private:
double GetTInv( double fAlpha, double fSize, int nType );
public:
- ScInterpreter( ScFormulaCell* pCell, ScDocument* pDoc,
+ ScInterpreter( ScFormulaCell* pCell, ScDocument* pDoc, const ScInterpreterContext& rContext,
const ScAddress&, ScTokenArray& );
~ScInterpreter();
diff --git a/sc/source/core/tool/formulagroup.cxx b/sc/source/core/tool/formulagroup.cxx
index 0730bae98a4d..f637ab5753bc 100644
--- a/sc/source/core/tool/formulagroup.cxx
+++ b/sc/source/core/tool/formulagroup.cxx
@@ -251,7 +251,7 @@ bool FormulaGroupInterpreterSoftware::interpret(ScDocument& rDoc, const ScAddres
ScCompiler aComp(&rDoc, aTmpPos, aCode2);
aComp.CompileTokenArray();
- ScInterpreter aInterpreter(pDest, &rDoc, aTmpPos, aCode2);
+ ScInterpreter aInterpreter(pDest, &rDoc, rDoc.GetNonThreadedContext(), aTmpPos, aCode2);
aInterpreter.Interpret();
aResults.push_back(aInterpreter.GetResultToken());
} // for loop end (xGroup->mnLength)
diff --git a/sc/source/core/tool/interpr1.cxx b/sc/source/core/tool/interpr1.cxx
index 157c8a2dcedd..9fac42814541 100644
--- a/sc/source/core/tool/interpr1.cxx
+++ b/sc/source/core/tool/interpr1.cxx
@@ -3550,7 +3550,7 @@ void ScInterpreter::ScMin( bool bTextAsZero )
{
if (nMin > nVal)
nMin = nVal;
- aValIter.GetCurNumFmtInfo( nFuncFmtType, nFuncFmtIndex );
+ aValIter.GetCurNumFmtInfo( mrContext, nFuncFmtType, nFuncFmtIndex );
while ((nErr == FormulaError::NONE) && aValIter.GetNext(nVal, nErr))
{
if (nMin > nVal)
@@ -3707,7 +3707,7 @@ void ScInterpreter::ScMax( bool bTextAsZero )
{
if (nMax < nVal)
nMax = nVal;
- aValIter.GetCurNumFmtInfo( nFuncFmtType, nFuncFmtIndex );
+ aValIter.GetCurNumFmtInfo( mrContext, nFuncFmtType, nFuncFmtIndex );
while ((nErr == FormulaError::NONE) && aValIter.GetNext(nVal, nErr))
{
if (nMax < nVal)
@@ -4864,7 +4864,7 @@ void ScInterpreter::ScMatch()
rParam.bByRow = false;
rParam.nRow2 = nRow1;
rEntry.nField = nCol1;
- ScQueryCellIterator aCellIter(pDok, nTab1, rParam, false);
+ ScQueryCellIterator aCellIter(pDok, mrContext, nTab1, rParam, false);
// Advance Entry.nField in Iterator if column changed
aCellIter.SetAdvanceQueryParamEntryField( true );
if (fTyp == 0.0)
@@ -5343,7 +5343,7 @@ void ScInterpreter::IterateParametersIf( ScIterFuncIf eFunc )
}
else
{
- ScQueryCellIterator aCellIter(pDok, nTab1, rParam, false);
+ ScQueryCellIterator aCellIter(pDok, mrContext, nTab1, rParam, false);
// Increment Entry.nField in iterator when switching to next column.
aCellIter.SetAdvanceQueryParamEntryField( true );
if ( aCellIter.GetFirst() )
@@ -5605,7 +5605,7 @@ void ScInterpreter::ScCountIf()
}
else
{
- ScQueryCellIterator aCellIter(pDok, nTab1, rParam, false);
+ ScQueryCellIterator aCellIter(pDok, mrContext, nTab1, rParam, false);
// Keep Entry.nField in iterator on column change
aCellIter.SetAdvanceQueryParamEntryField( true );
if ( aCellIter.GetFirst() )
@@ -5898,7 +5898,7 @@ void ScInterpreter::IterateParametersIfs( double(*ResultFunc)( const sc::ParamIf
}
else
{
- ScQueryCellIterator aCellIter(pDok, nTab1, rParam, false);
+ ScQueryCellIterator aCellIter(pDok, mrContext, nTab1, rParam, false);
// Increment Entry.nField in iterator when switching to next column.
aCellIter.SetAdvanceQueryParamEntryField( true );
if ( aCellIter.GetFirst() )
@@ -6724,7 +6724,7 @@ void ScInterpreter::ScLookup()
if (rItem.meType == ScQueryEntry::ByString)
aParam.eSearchType = DetectSearchType(rItem.maString.getString(), pDok);
- ScQueryCellIterator aCellIter(pDok, nTab1, aParam, false);
+ ScQueryCellIterator aCellIter(pDok, mrContext, nTab1, aParam, false);
SCCOL nC;
SCROW nR;
// Advance Entry.nField in iterator upon switching columns if
@@ -7071,7 +7071,7 @@ void ScInterpreter::CalculateLookup(bool bHLookup)
rEntry.eOp = SC_LESS_EQUAL;
if ( bHLookup )
{
- ScQueryCellIterator aCellIter(pDok, nTab1, aParam, false);
+ ScQueryCellIterator aCellIter(pDok, mrContext, nTab1, aParam, false);
// advance Entry.nField in Iterator upon switching columns
aCellIter.SetAdvanceQueryParamEntryField( true );
if ( bSorted )
@@ -7447,7 +7447,7 @@ void ScInterpreter::DBIterator( ScIterFunc eFunc )
SetError(FormulaError::NoValue);
return;
}
- ScDBQueryDataIterator aValIter(pDok, pQueryParam.release());
+ ScDBQueryDataIterator aValIter(pDok, mrContext, pQueryParam.release());
ScDBQueryDataIterator::Value aValue;
if ( aValIter.GetFirst(aValue) && aValue.mnError == FormulaError::NONE )
{
@@ -7535,7 +7535,7 @@ void ScInterpreter::ScDBCount()
// so the source range has to be restricted, like before the introduction
// of ScDBQueryParamBase.
p->nCol1 = p->nCol2 = p->mnField;
- ScQueryCellIterator aCellIter( pDok, nTab, *p, true);
+ ScQueryCellIterator aCellIter( pDok, mrContext, nTab, *p, true);
if ( aCellIter.GetFirst() )
{
do
@@ -7551,7 +7551,7 @@ void ScInterpreter::ScDBCount()
SetError(FormulaError::NoValue);
return;
}
- ScDBQueryDataIterator aValIter( pDok, pQueryParam.release());
+ ScDBQueryDataIterator aValIter( pDok, mrContext, pQueryParam.release());
ScDBQueryDataIterator::Value aValue;
if ( aValIter.GetFirst(aValue) && aValue.mnError == FormulaError::NONE )
{
@@ -7582,7 +7582,7 @@ void ScInterpreter::ScDBCount2()
}
sal_uLong nCount = 0;
pQueryParam->mbSkipString = false;
- ScDBQueryDataIterator aValIter( pDok, pQueryParam.release());
+ ScDBQueryDataIterator aValIter( pDok, mrContext, pQueryParam.release());
ScDBQueryDataIterator::Value aValue;
if ( aValIter.GetFirst(aValue) && aValue.mnError == FormulaError::NONE )
{
@@ -7636,7 +7636,7 @@ void ScInterpreter::GetDBStVarParams( double& rVal, double& rValCount )
SetError(FormulaError::NoValue);
return;
}
- ScDBQueryDataIterator aValIter(pDok, pQueryParam.release());
+ ScDBQueryDataIterator aValIter(pDok, mrContext, pQueryParam.release());
ScDBQueryDataIterator::Value aValue;
if (aValIter.GetFirst(aValue) && aValue.mnError == FormulaError::NONE)
{
@@ -9297,11 +9297,11 @@ utl::SearchParam::SearchType ScInterpreter::DetectSearchType( const OUString& rS
return utl::SearchParam::SearchType::Normal;
}
-static bool lcl_LookupQuery( ScAddress & o_rResultPos, ScDocument * pDoc,
+static bool lcl_LookupQuery( ScAddress & o_rResultPos, ScDocument * pDoc, const ScInterpreterContext& rContext,
const ScQueryParam & rParam, const ScQueryEntry & rEntry )
{
bool bFound = false;
- ScQueryCellIterator aCellIter( pDoc, rParam.nTab, rParam, false);
+ ScQueryCellIterator aCellIter( pDoc, rContext, rParam.nTab, rParam, false);
if (rEntry.eOp != SC_EQUAL)
{
// range lookup <= or >=
@@ -9338,7 +9338,7 @@ bool ScInterpreter::LookupQueryWithCache( ScAddress & o_rResultPos,
* direct lookups here. We could even further attribute volatility per
* parameter so it would affect only the lookup range parameter. */
if (!bColumnsMatch || GetVolatileType() != NOT_VOLATILE)
- bFound = lcl_LookupQuery( o_rResultPos, pDok, rParam, rEntry);
+ bFound = lcl_LookupQuery( o_rResultPos, pDok, mrContext, rParam, rEntry);
else
{
ScRange aLookupRange( rParam.nCol1, rParam.nRow1, rParam.nTab,
@@ -9351,7 +9351,7 @@ bool ScInterpreter::LookupQueryWithCache( ScAddress & o_rResultPos,
{
case ScLookupCache::NOT_CACHED :
case ScLookupCache::CRITERIA_DIFFERENT :
- bFound = lcl_LookupQuery( o_rResultPos, pDok, rParam, rEntry);
+ bFound = lcl_LookupQuery( o_rResultPos, pDok, mrContext, rParam, rEntry);
if (eCacheResult == ScLookupCache::NOT_CACHED)
rCache.insert( o_rResultPos, aCriteria, aPos, bFound);
break;
diff --git a/sc/source/core/tool/interpr4.cxx b/sc/source/core/tool/interpr4.cxx
index 7285d83b9beb..73e91cfb6271 100644
--- a/sc/source/core/tool/interpr4.cxx
+++ b/sc/source/core/tool/interpr4.cxx
@@ -203,7 +203,7 @@ double ScInterpreter::GetCellValueOrZero( const ScAddress& rPos, ScRefCellValue&
if (pFCell->IsValue())
{
fValue = pFCell->GetValue();
- pDok->GetNumberFormatInfo( nCurFmtType, nCurFmtIndex,
+ pDok->GetNumberFormatInfo( mrContext, nCurFmtType, nCurFmtIndex,
rPos );
}
else
@@ -221,7 +221,7 @@ double ScInterpreter::GetCellValueOrZero( const ScAddress& rPos, ScRefCellValue&
case CELLTYPE_VALUE:
{
fValue = rCell.mfValue;
- nCurFmtIndex = pDok->GetNumberFormat( rPos );
+ nCurFmtIndex = pDok->GetNumberFormat( mrContext, rPos );
nCurFmtType = pFormatter->GetType( nCurFmtIndex );
if ( bCalcAsShown && fValue != 0.0 )
fValue = pDok->RoundValueAsShown( fValue, nCurFmtIndex );
@@ -697,7 +697,7 @@ void ScInterpreter::PushCellResultToken( bool bDisplayEmptyAsString,
{
bool bInherited = (aCell.meType == CELLTYPE_FORMULA);
if (pRetTypeExpr && pRetIndexExpr)
- pDok->GetNumberFormatInfo(*pRetTypeExpr, *pRetIndexExpr, rAddress);
+ pDok->GetNumberFormatInfo(mrContext, *pRetTypeExpr, *pRetIndexExpr, rAddress);
PushTempToken( new ScEmptyCellToken( bInherited, bDisplayEmptyAsString));
return;
}
@@ -2503,7 +2503,7 @@ void ScInterpreter::ScDBGet()
}
pQueryParam->mbSkipString = false;
- ScDBQueryDataIterator aValIter(pDok, pQueryParam.release());
+ ScDBQueryDataIterator aValIter(pDok, mrContext, pQueryParam.release());
ScDBQueryDataIterator::Value aValue;
if (!aValIter.GetFirst(aValue) || aValue.mnError != FormulaError::NONE)
{
@@ -3783,18 +3783,19 @@ void ScInterpreter::ScTTT()
PushError(FormulaError::NoValue);
}
-ScInterpreter::ScInterpreter( ScFormulaCell* pCell, ScDocument* pDoc,
+ScInterpreter::ScInterpreter( ScFormulaCell* pCell, ScDocument* pDoc, const ScInterpreterContext& rContext,
const ScAddress& rPos, ScTokenArray& r )
: aCode(r)
, aPos(rPos)
, rArr(r)
+ , mrContext(rContext)
, pDok(pDoc)
, mpLinkManager(pDok->GetLinkManager())
, mrStrPool(pDoc->GetSharedStringPool())
, pJumpMatrix(nullptr)
, pTokenMatrixMap(nullptr)
, pMyFormulaCell(pCell)
- , pFormatter(pDoc->GetFormatTable())
+ , pFormatter(rContext.GetFormatTable())
, pCur(nullptr)
, nGlobalError(FormulaError::NONE)
, sp(0)
diff --git a/sc/source/core/tool/interpr5.cxx b/sc/source/core/tool/interpr5.cxx
index 0fe8cced4c6f..909965676139 100644
--- a/sc/source/core/tool/interpr5.cxx
+++ b/sc/source/core/tool/interpr5.cxx
@@ -3224,7 +3224,7 @@ void ScInterpreter::ScMatRef()
else
{
// Determine nFuncFmtType type before PushDouble().
- pDok->GetNumberFormatInfo(nCurFmtType, nCurFmtIndex, aAdr);
+ pDok->GetNumberFormatInfo(mrContext, nCurFmtType, nCurFmtIndex, aAdr);
nFuncFmtType = nCurFmtType;
nFuncFmtIndex = nCurFmtIndex;
PushDouble(nMatVal.fVal); // handles DoubleError
@@ -3234,7 +3234,7 @@ void ScInterpreter::ScMatRef()
else
{
// Determine nFuncFmtType type before PushDouble().
- pDok->GetNumberFormatInfo(nCurFmtType, nCurFmtIndex, aAdr);
+ pDok->GetNumberFormatInfo(mrContext, nCurFmtType, nCurFmtIndex, aAdr);
nFuncFmtType = nCurFmtType;
nFuncFmtIndex = nCurFmtIndex;
// If not a result matrix, obtain the cell value.
diff --git a/sc/source/core/tool/interpr6.cxx b/sc/source/core/tool/interpr6.cxx
index ea19289230a2..0f513c231327 100644
--- a/sc/source/core/tool/interpr6.cxx
+++ b/sc/source/core/tool/interpr6.cxx
@@ -319,13 +319,14 @@ public:
class FuncCount : public sc::ColumnSpanSet::ColumnAction
{
+ const ScInterpreterContext& mrContext;
sc::ColumnBlockConstPosition maPos;
ScColumn* mpCol;
size_t mnCount;
sal_uInt32 mnNumFmt;
public:
- FuncCount() : mpCol(nullptr), mnCount(0), mnNumFmt(0) {}
+ FuncCount(const ScInterpreterContext& rContext) : mrContext(rContext), mpCol(nullptr), mnCount(0), mnNumFmt(0) {}
virtual void startColumn(ScColumn* pCol) override
{
@@ -341,7 +342,7 @@ public:
NumericCellCounter aFunc;
maPos.miCellPos = sc::ParseBlock(maPos.miCellPos, mpCol->GetCellStore(), aFunc, nRow1, nRow2);
mnCount += aFunc.getCount();
- mnNumFmt = mpCol->GetNumberFormat(nRow2);
+ mnNumFmt = mpCol->GetNumberFormat(mrContext, nRow2);
};
size_t getCount() const { return mnCount; }
@@ -350,6 +351,7 @@ public:
class FuncSum : public sc::ColumnSpanSet::ColumnAction
{
+ const ScInterpreterContext& mrContext;
sc::ColumnBlockConstPosition maPos;
ScColumn* mpCol;
double mfSum;
@@ -357,7 +359,7 @@ class FuncSum : public sc::ColumnSpanSet::ColumnAction
sal_uInt32 mnNumFmt;
public:
- FuncSum() : mpCol(nullptr), mfSum(0.0), mnError(FormulaError::NONE), mnNumFmt(0) {}
+ FuncSum(const ScInterpreterContext& rContext) : mrContext(rContext), mpCol(nullptr), mfSum(0.0), mnError(FormulaError::NONE), mnNumFmt(0) {}
virtual void startColumn(ScColumn* pCol) override
{
@@ -389,7 +391,7 @@ public:
mfSum += aFunc.getRest();
}
- mnNumFmt = mpCol->GetNumberFormat(nRow2);
+ mnNumFmt = mpCol->GetNumberFormat(mrContext, nRow2);
};
FormulaError getError() const { return mnError; }
@@ -821,7 +823,7 @@ void ScInterpreter::IterateParameters( ScIterFunc eFunc, bool bTextAsZero )
if ( eFunc == ifSUM )
{
- FuncSum aAction;
+ FuncSum aAction(mrContext);
aSet.executeColumnAction( *pDok, aAction, fMem );
FormulaError nErr = aAction.getError();
if ( nErr != FormulaError::NONE )
@@ -836,7 +838,7 @@ void ScInterpreter::IterateParameters( ScIterFunc eFunc, bool bTextAsZero )
}
else
{
- FuncCount aAction;
+ FuncCount aAction(mrContext);
aSet.executeColumnAction(*pDok, aAction);
nCount += aAction.getCount();
@@ -853,7 +855,7 @@ void ScInterpreter::IterateParameters( ScIterFunc eFunc, bool bTextAsZero )
if (aValIter.GetFirst(fVal, nErr))
{
// placed the loop on the inside for performance reasons:
- aValIter.GetCurNumFmtInfo( nFuncFmtType, nFuncFmtIndex );
+ aValIter.GetCurNumFmtInfo( mrContext, nFuncFmtType, nFuncFmtIndex );
switch( eFunc )
{
case ifAVERAGE:
diff --git a/sc/source/filter/excel/xepivot.cxx b/sc/source/filter/excel/xepivot.cxx
index 999600c58cc3..21f2963f8abb 100644
--- a/sc/source/filter/excel/xepivot.cxx
+++ b/sc/source/filter/excel/xepivot.cxx
@@ -341,7 +341,7 @@ void XclExpPCField::InitStandardField( const ScRange& rRange )
if( rDoc.HasValueData( aPos.Col(), aPos.Row(), aPos.Tab() ) )
{
double fValue = rDoc.GetValue( aPos );
- short nFmtType = rFormatter.GetType( rDoc.GetNumberFormat( aPos ) );
+ short nFmtType = rFormatter.GetType( rDoc.GetNumberFormat( rDoc.GetNonThreadedContext(), aPos ) );
if( nFmtType == css::util::NumberFormat::LOGICAL )
InsertOrigBoolItem( fValue != 0, aText );
else if( nFmtType & css::util::NumberFormat::DATETIME )
diff --git a/sc/source/filter/excel/xicontent.cxx b/sc/source/filter/excel/xicontent.cxx
index ee178c72676b..27072e4dab12 100644
--- a/sc/source/filter/excel/xicontent.cxx
+++ b/sc/source/filter/excel/xicontent.cxx
@@ -173,7 +173,7 @@ void lclInsertUrl( XclImpRoot& rRoot, const OUString& rUrl, SCCOL nScCol, SCROW
case CELLTYPE_STRING:
case CELLTYPE_EDIT:
{
- sal_uLong nNumFmt = rDoc.getDoc().GetNumberFormat(aScPos);
+ sal_uLong nNumFmt = rDoc.getDoc().GetNumberFormat(rDoc.getDoc().GetNonThreadedContext(), aScPos);
SvNumberFormatter* pFormatter = rDoc.getDoc().GetFormatTable();
Color* pColor;
OUString aDisplText;
diff --git a/sc/source/ui/docshell/externalrefmgr.cxx b/sc/source/ui/docshell/externalrefmgr.cxx
index e1fc3d5a95d2..9cee85bee434 100644
--- a/sc/source/ui/docshell/externalrefmgr.cxx
+++ b/sc/source/ui/docshell/externalrefmgr.cxx
@@ -2879,7 +2879,7 @@ public:
if (pTok)
{
// Cache this cell.
- mpRefTab->setCell(mpCurCol->GetCol(), nRow, pTok, mpCurCol->GetNumberFormat(nRow));
+ mpRefTab->setCell(mpCurCol->GetCol(), nRow, pTok, mpCurCol->GetNumberFormat(mpCurCol->GetDoc().GetNonThreadedContext(), nRow));
mpRefTab->setCachedCell(mpCurCol->GetCol(), nRow);
}
}
diff --git a/svl/source/numbers/zforlist.cxx b/svl/source/numbers/zforlist.cxx
index dcca285d9f4b..70d16c13ccd3 100644
--- a/svl/source/numbers/zforlist.cxx
+++ b/svl/source/numbers/zforlist.cxx
@@ -1060,6 +1060,8 @@ bool SvNumberFormatter::IsNumberFormat(const OUString& sString,
sal_uInt32& F_Index,
double& fOutNumber)
{
+ ::osl::MutexGuard aGuard( GetMutex() );
+
short FType;
const SvNumberformat* pFormat = ImpSubstituteEntry( GetFormatEntry(F_Index));
if (!pFormat)