From ae4067e9054f2aba8a8c65a5ae78bf551c0cdd10 Mon Sep 17 00:00:00 2001 From: Tor Lillqvist Date: Wed, 4 Oct 2017 00:12:31 +0300 Subject: 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 --- sc/inc/column.hxx | 5 ++-- sc/inc/dociter.hxx | 11 +++++---- sc/inc/document.hxx | 9 ++++--- sc/inc/formulacell.hxx | 4 ++-- sc/inc/interpretercontext.hxx | 39 +++++++++++++++++++++++++++++++ sc/inc/table.hxx | 5 ++-- sc/source/core/data/column.cxx | 8 +++---- sc/source/core/data/column2.cxx | 7 +++--- sc/source/core/data/column3.cxx | 18 +++++++------- sc/source/core/data/dociter.cxx | 24 ++++++++++--------- sc/source/core/data/documen2.cxx | 1 + sc/source/core/data/documen8.cxx | 4 ++-- sc/source/core/data/document.cxx | 17 ++++++++++---- sc/source/core/data/formulacell.cxx | 38 +++++++++++++++++++----------- sc/source/core/data/simpleformulacalc.cxx | 2 +- sc/source/core/data/table1.cxx | 4 ++-- sc/source/core/data/table2.cxx | 6 ++--- sc/source/core/data/table4.cxx | 4 ++-- sc/source/core/inc/interpre.hxx | 4 +++- sc/source/core/tool/formulagroup.cxx | 2 +- sc/source/core/tool/interpr1.cxx | 34 +++++++++++++-------------- sc/source/core/tool/interpr4.cxx | 13 ++++++----- sc/source/core/tool/interpr5.cxx | 4 ++-- sc/source/core/tool/interpr6.cxx | 16 +++++++------ sc/source/filter/excel/xepivot.cxx | 2 +- sc/source/filter/excel/xicontent.cxx | 2 +- sc/source/ui/docshell/externalrefmgr.cxx | 2 +- svl/source/numbers/zforlist.cxx | 2 ++ 28 files changed, 181 insertions(+), 106 deletions(-) create mode 100644 sc/inc/interpretercontext.hxx 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 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 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 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 #include #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 #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& 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(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(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 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 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 #include #include +#include #include #include #include @@ -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) -- cgit v1.2.3