20#include <config_feature_opencl.h>
24#include <osl/diagnose.h>
32#include <compiler.hxx>
33#include <document.hxx>
43#include <progress.hxx>
50#include <tokenarray.hxx>
68#include <com/sun/star/sheet/FormulaLanguage.hpp>
70#if HAVE_FEATURE_OPENCL
79#define DEBUG_CALCULATION 0
81static bool bDebugCalculationActive =
false;
82static ScAddress aDebugCalculationTriggerAddress(1,2,0);
84struct DebugCalculationEntry
90 sal_uInt16 mnRecursion;
96 mnRecursion(rDoc.GetRecursionHelper().GetRecursionCount())
107static struct DebugCalculation
109 std::vector< DebugCalculationEntry > mvPos;
110 std::vector< DebugCalculationEntry > mvResults;
118 DebugCalculation() : mnGroup(0),
mbActive(bDebugCalculationActive), mbSwitchOff(false),
119 mbPrint(true), mbPrintResults(false) {}
124 for (
auto const& it : mvPos)
127 " [" + OUString::number( it.mnRecursion) +
"," + OUString::number( it.mnGroup) +
"]");
128 fprintf( stderr,
"%s -> ",
aStr.toUtf8().getStr());
130 fprintf( stderr,
"%s",
"END\n");
134 void printResults()
const
136 for (
auto const& it : mvResults)
139 aStr +=
" (" + it.maResult +
")";
140 fprintf( stderr,
"%s, ",
aStr.toUtf8().getStr());
142 fprintf( stderr,
"%s",
"END\n");
147 if (mbActive && !mvPos.empty())
148 mvPos.back().maResult =
"\"" + rStr.
getString() +
"\"";
151 void storeResult(
const double& fVal )
153 if (mbActive && !mvPos.empty())
154 mvPos.back().maResult = rtl::math::doubleToUString( fVal, rtl_math_StringFormat_G, 2,
'.',
true);
159 if (mbActive && !mvPos.empty())
160 mvPos.back().maResult =
"Err:" + OUString::number(
int( nErr ));
175struct DebugCalculationStacker
179 if (!aDC.mbActive && rPos == aDC.maTrigger)
180 aDC.mbActive = aDC.mbSwitchOff =
true;
183 aDC.mvPos.push_back( DebugCalculationEntry( rPos, rDoc, aDC.mnGroup));
188 ~DebugCalculationStacker()
192 if (!aDC.mvPos.empty())
199 if (aDC.mbPrintResults)
202 aDC.mvResults.push_back( aDC.mvPos.back());
204 aDC.mvPos.pop_back();
205 if (aDC.mbPrintResults && aDC.mvPos.empty())
208 std::vector< DebugCalculationEntry >().swap( aDC.mvResults);
210 if (aDC.mbSwitchOff && aDC.mvPos.empty())
211 aDC.mbActive =
false;
233 return rData.
toAbs(rDoc, rPos).
Col();
238 return rData.
toAbs(rDoc, rPos).
Row();
243 return rData.
toAbs(rDoc, rPos).
Tab();
249lcl_checkRangeDimension(
252 const DimensionSelector aWhich)
254 return aWhich(rDoc, rPos, rRef1.
Ref1) == aWhich(rDoc, rPos, rRef2.
Ref1) &&
255 aWhich(rDoc, rPos, rRef1.
Ref2) == aWhich(rDoc, rPos, rRef2.
Ref2);
259lcl_checkRangeDimensions(
262 bool& bCol,
bool& bRow,
bool& bTab)
264 const bool bSameCols(lcl_checkRangeDimension(rDoc, rPos, rRef1, rRef2, lcl_GetCol));
265 const bool bSameRows(lcl_checkRangeDimension(rDoc, rPos, rRef1, rRef2, lcl_GetRow));
266 const bool bSameTabs(lcl_checkRangeDimension(rDoc, rPos, rRef1, rRef2, lcl_GetTab));
269 if (
int(bSameCols) +
int(bSameRows) +
int(bSameTabs) == 2)
283lcl_checkRangeDimensions(
285 const std::vector<formula::FormulaToken*>::const_iterator& rBegin,
286 const std::vector<formula::FormulaToken*>::const_iterator& rEnd,
287 bool& bCol,
bool& bRow,
bool& bTab)
289 std::vector<formula::FormulaToken*>::const_iterator aCur(rBegin);
295 bOk = lcl_checkRangeDimensions(rDoc, rPos, aRef, aRefCur, bCol, bRow, bTab);
297 while (bOk && aCur != rEnd)
303 bOk = lcl_checkRangeDimensions(rDoc, rPos, aRef, aRefCur, bColTmp, bRowTmp, bTabTmp);
304 bOk = bOk && (bCol == bColTmp && bRow == bRowTmp && bTab == bTabTmp);
308 return bOk && aCur == rEnd;
317 LessByReference(
const ScDocument& rDoc,
const ScAddress& rPos,
const DimensionSelector& rFunc) :
318 mrDoc(rDoc), maPos(rPos),
maFunc(rFunc) {}
324 return maFunc(mrDoc, maPos, aRef1.Ref1) <
maFunc(mrDoc, maPos, aRef2.Ref1);
333class AdjacentByReference
339 AdjacentByReference(
const ScDocument& rDoc,
const ScAddress& rPos, DimensionSelector aFunc) :
340 mrDoc(rDoc), maPos(rPos),
maFunc(aFunc) {}
346 return maFunc(mrDoc, maPos, aRef2.Ref1) -
maFunc(mrDoc, maPos, aRef1.Ref2) == 1;
353 const ScAddress& rPos,
const std::vector<formula::FormulaToken*>& rReferences,
const DimensionSelector aWhich)
355 auto aBegin(rReferences.cbegin());
356 auto aEnd(rReferences.cend());
357 auto aBegin1(aBegin);
360 return std::equal(aBegin, aEnd, aBegin1, AdjacentByReference(rDoc, rPos, aWhich));
364lcl_fillRangeFromRefList(
366 const ScAddress& aPos,
const std::vector<formula::FormulaToken*>& rReferences,
ScRange& rRange)
370 rRange.
aStart = aStart.toAbs(rDoc, aPos);
373 rRange.
aEnd = aEnd.toAbs(rDoc, aPos);
377lcl_refListFormsOneRange(
379 const ScAddress& rPos, std::vector<formula::FormulaToken*>& rReferences,
382 if (rReferences.size() == 1)
384 lcl_fillRangeFromRefList(rDoc, rPos, rReferences, rRange);
391 if (lcl_checkRangeDimensions(rDoc, rPos, rReferences.begin(), rReferences.end(), bCell, bRow, bTab))
393 DimensionSelector aWhich;
408 OSL_FAIL(
"lcl_checkRangeDimensions shouldn't allow that!");
413 std::sort(rReferences.begin(), rReferences.end(), LessByReference(rDoc, rPos, aWhich));
414 if (lcl_checkIfAdjacent(rDoc, rPos, rReferences, aWhich))
416 lcl_fillRangeFromRefList(rDoc, rPos, rReferences, rRange);
436 if (!rOldDoc.
CopyAdjustRangeName( nSheet, nIndex, pRangeData, rNewDoc, rNewPos, rOldPos, bGlobalNamesToLocal,
true))
443 assert(!
"inserting the range name should not fail");
454 if (!pOldDBCollection)
464 if (!pNewDBCollection)
473 pNewDBData =
new ScDBData(*pDBData);
474 bool ins = aNewNamedDBs.
insert(std::unique_ptr<ScDBData>(pNewDBData));
475 assert(ins); (void)ins;
512 mbPartOfCycle(false),
534 if (
mpCode->GetLen() &&
mpCode->GetCodeError() == FormulaError::NONE && !
mpCode->GetCodeLen())
557 it, std::piecewise_construct,
558 std::forward_as_tuple(aKey),
559 std::forward_as_tuple(
560 rRange, (*ppTopCell)->GetDocument(), (*ppTopCell)->aPos,
mnLength, bStartFixed, bEndFixed));
582 bTableOpDirty(false),
588 bInChangeTrack(false),
589 bNeedListening(false),
590 mbNeedsNumberFormat(false),
591 mbAllowNumberFormatChange(false),
592 mbPostponedDirty(false),
604 pPreviousTrack(nullptr),
611 const OUString& rFormula,
615 bTableOpDirty( false ),
620 bIsIterCell( false ),
621 bInChangeTrack( false ),
622 bNeedListening( false ),
623 mbNeedsNumberFormat( false ),
624 mbAllowNumberFormatChange(false),
625 mbPostponedDirty(false),
629 cMatrixFlag ( cMatInd ),
632 eTempGrammar( eGrammar),
637 pPreviousTrack(nullptr),
641 Compile( rFormula,
true, eGrammar );
651 bTableOpDirty( false ),
656 bIsIterCell( false ),
657 bInChangeTrack( false ),
658 bNeedListening( false ),
659 mbNeedsNumberFormat( false ),
660 mbAllowNumberFormatChange(false),
661 mbPostponedDirty(false),
665 cMatrixFlag ( cMatInd ),
668 eTempGrammar( eGrammar),
669 pCode(pArray.release()),
673 pPreviousTrack(nullptr),
704 bTableOpDirty( false ),
709 bIsIterCell( false ),
710 bInChangeTrack( false ),
711 bNeedListening( false ),
712 mbNeedsNumberFormat( false ),
713 mbAllowNumberFormatChange(false),
714 mbPostponedDirty(false),
718 cMatrixFlag ( cMatInd ),
721 eTempGrammar( eGrammar),
726 pPreviousTrack(nullptr),
754 bTableOpDirty( false ),
758 bSubTotal(xGroup->mbSubTotal),
759 bIsIterCell( false ),
760 bInChangeTrack( false ),
761 bNeedListening( false ),
762 mbNeedsNumberFormat( false ),
763 mbAllowNumberFormatChange(false),
764 mbPostponedDirty(false),
768 cMatrixFlag ( cInd ),
770 nFormatType(xGroup->mnFormatType),
771 eTempGrammar( eGrammar),
772 pCode(xGroup->mpCode ? &*xGroup->mpCode : new
ScTokenArray(rDoc)),
776 pPreviousTrack(nullptr),
785 bDirty( rCell.bDirty ),
786 bTableOpDirty( false ),
787 bChanged( rCell.bChanged ),
789 bCompile( rCell.bCompile ),
790 bSubTotal( rCell.bSubTotal ),
791 bIsIterCell( false ),
792 bInChangeTrack( false ),
793 bNeedListening( false ),
794 mbNeedsNumberFormat( rCell.mbNeedsNumberFormat ),
795 mbAllowNumberFormatChange(false),
796 mbPostponedDirty(false),
800 cMatrixFlag ( rCell.cMatrixFlag ),
802 nFormatType( rCell.nFormatType ),
803 aResult( rCell.aResult ),
804 eTempGrammar( rCell.eTempGrammar),
808 pPreviousTrack(nullptr),
823 bool bCompileLater =
false;
838 adjustRangeName(pToken, rDoc, rCell.
rDocument,
aPos, rCell.
aPos, bGlobalNamesToLocal);
840 adjustDBRange(pToken, rDoc, rCell.
rDocument);
868 if (
t->IsExternalRef() )
887 bCompileLater = bClipMode;
893 if ( !bCompileLater && bClipMode )
901 if ( !bCompileLater )
956 OUStringBuffer buffer;
976 return pCell->
GetFormula( eGrammar, pContext );
986 OSL_FAIL(
"ScFormulaCell::GetFormula: not a matrix");
995 buffer.insert( 0,
'=');
998 buffer.insert( 0,
'{');
1001 return buffer.makeStringAndClear();
1006 OUStringBuffer
aBuf;
1013 return aBuf.makeStringAndClear();
1044 OSL_FAIL(
"ScFormulaCell::GetFormula: not a matrix");
1053 aBuf.insert( 0,
'=');
1056 aBuf.insert( 0,
'{');
1060 return aBuf.makeStringAndClear();
1106 if ( bWasInFormulaTree )
1120 if ( rFormula[0] ==
'=' )
1131 if ( bWasInFormulaTree )
1141 if ( bWasInFormulaTree )
1155 if ( rFormula[0] ==
'=' )
1166 if ( bWasInFormulaTree )
1181 if ( bWasInFormulaTree )
1186 bNoListening =
true;
1198 if ( !bNoListening )
1201 if ( bWasInFormulaTree )
1221 if ( bWasInFormulaTree )
1226 bNoListening =
true;
1238 if ( !bNoListening )
1241 if ( bWasInFormulaTree )
1265 if (bWasInFormulaTree)
1269 OUString aFormula, aFormulaNmsp;
1276 bool bDoCompile =
true;
1278 if ( !
mxGroup && aFormulaNmsp.isEmpty() )
1281 aPreviousCell.
IncRow( -1 );
1288 OUStringBuffer aShouldBeBuf;
1292 const sal_Int32 nLeadingEqual = (aFormula.getLength() > 0 && aFormula[0] ==
'=') ? 1 : 0;
1293 if (aFormula.getLength() == aShouldBeBuf.getLength() + nLeadingEqual &&
1294 aFormula.match( aShouldBeBuf, nLeadingEqual))
1332 if ( !aFormula.isEmpty() && aFormula[0] ==
'=' )
1366 else if (bWasInFormulaTree)
1372 bool bNewCompiled =
false;
1380 bNewCompiled =
true;
1390 bNewCompiled =
true;
1401 OSL_FAIL(
"Formula cell INFINITY!!! Where does this document come from?");
1419 if (bStartListening)
1439class RecursionCounter
1442 bool bStackedInIteration;
1443#if defined DBG_UTIL && !defined NDEBUG
1449#
if defined DBG_UTIL && !defined NDEBUG
1454 if (bStackedInIteration)
1461 if (bStackedInIteration)
1463#if defined DBG_UTIL && !defined NDEBUG
1477struct TemporaryCellGroupMaker
1481 , mEnabled( enable )
1483 if( mEnabled && mCell->GetCellGroup() ==
nullptr )
1485 mCell->CreateCellGroup( 1,
false );
1486 mCell->GetDocument().GetRecursionHelper().AddTemporaryGroupCell( mCell );
1489 ~TemporaryCellGroupMaker() COVERITY_NOEXCEPT_FALSE
1492 mCell->GetDocument().GetRecursionHelper().CleanTemporaryGroupCells();
1495 const bool mEnabled;
1503 bool bGroupInterpreted =
false;
1511 return bGroupInterpreted;
1531 return bGroupInterpreted;
1534#if DEBUG_CALCULATION
1535 static bool bDebugCalculationInit =
true;
1536 if (bDebugCalculationInit)
1538 aDC.maTrigger = aDebugCalculationTriggerAddress;
1539 aDC.mbPrintResults =
true;
1540 bDebugCalculationInit =
false;
1546 return bGroupInterpreted;
1552 return bGroupInterpreted;
1559 return bGroupInterpreted;
1570 return bGroupInterpreted;
1577 return bGroupInterpreted;
1589#if DEBUG_CALCULATION
1596#if DEBUG_CALCULATION
1599 if (!bGroupInterpreted)
1606 return bGroupInterpreted;
1611 if (!bPartOfCycleBefore && bPartOfCycleAfter && rRecursionHelper.
AnyParentFGInCycle())
1614 return bGroupInterpreted;
1629 bool bFreeFlyingInserted =
false;
1635 bool bIterationFromRecursion =
false;
1636 bool bResumeIteration =
false;
1642 bIterationFromRecursion || bResumeIteration)
1646 if (!bIterationFromRecursion && bResumeIteration)
1648 bResumeIteration =
false;
1650 ScFormulaRecursionList::const_iterator aOldStart(
1654 for (ScFormulaRecursionList::const_iterator aIter(
1665 sal_uInt16 nIteration = rRecursionHelper.
GetIteration();
1666 for (ScFormulaRecursionList::const_iterator aIter(
1667 aOldStart); aIter !=
1673 if (!pIterCell->
bDirty || aIter == aOldStart)
1675 pIterCell->
aResult = (*aIter).aPreviousResult;
1679 pIterCell->
bDirty =
true;
1684 bResumeIteration =
false;
1691 if (rRecursionHelper.
GetList().size() > 1)
1694 if (pLastCell !=
this)
1708 for (ScFormulaRecursionList::const_iterator aIter(
1713 pIterCell->
aResult = (*aIter).aPreviousResult;
1717 bIterationFromRecursion =
false;
1719 for ( ; rRecursionHelper.
GetIteration() <= nIterMax && !rDone;
1724 for ( ScFormulaRecursionList::iterator aIter(
1734 (*aIter).aPreviousResult = pIterCell->
aResult;
1752 bResumeIteration =
true;
1757 if (!bResumeIteration)
1761 for (ScFormulaRecursionList::const_iterator aIter(
1769 pIterCell->
bRunning = (*aIter).bOldRunning;
1774 for (ScFormulaRecursionList::const_iterator aIter(
1782 pIterCell->
bRunning = (*aIter).bOldRunning;
1814 bIterationFromRecursion =
false;
1822 for (ScFormulaRecursionList::const_iterator aIter(
1835 pCell->
bRunning = (*aIter).bOldRunning;
1842 if (!bResumeIteration)
1843 bIterationFromRecursion =
true;
1845 else if (bResumeIteration ||
1847 rRecursionHelper.
GetList().erase(
1851 rRecursionHelper.
Clear();
1853 }
while (bIterationFromRecursion || bResumeIteration);
1855 if (bFreeFlyingInserted)
1861 const bool bOnlyThis = (rRecursionHelper.
GetList().size() == 1);
1865 assert(rRecursionHelper.
GetList().empty());
1866 if (rRecursionHelper.
GetList().empty())
1872#if DEBUG_CALCULATION
1874 if (nErr != FormulaError::NONE)
1875 aDC.storeResultError( nErr);
1882 return bGroupInterpreted;
1914 std::unique_ptr<ScInterpreter> pScopedInterpreter;
1924 pInterpreter = pScopedInterpreter.get();
1938 case FormulaError::CircularReference :
1967 bool bContentChanged =
false;
1973 if( pInterpreter->
GetError() != FormulaError::NONE && pInterpreter->
GetError() != FormulaError::CircularReference)
1977 if (pInterpreter->
GetError() == FormulaError::RetryCircular)
2016 if( pInterpreter->
GetError() != nOldErrCode )
2021 bContentChanged =
true;
2050 if (bForceNumberFormat)
2054 if (nRetType == SvNumFormatType::LOGICAL)
2057 if (fVal != 1.0 && fVal != 0.0)
2058 bForceNumberFormat =
false;
2065 case SvNumFormatType::PERCENT:
2066 case SvNumFormatType::CURRENCY:
2067 case SvNumFormatType::SCIENTIFIC:
2068 case SvNumFormatType::FRACTION:
2069 bForceNumberFormat =
false;
2071 case SvNumFormatType::NUMBER:
2073 bForceNumberFormat =
false;
2079 else if (nRetType == SvNumFormatType::TEXT)
2081 bForceNumberFormat =
false;
2083 if (bForceNumberFormat)
2090 if (nOldFormatIndex !=
2092 bForceNumberFormat =
false;
2098 bool bSetFormat =
true;
2123 if (eNewCellResultType !=
svDouble)
2131 if (fVal != 1.0 && fVal != 0.0)
2198 bContentChanged = (eOld != eNew ||
2227 bContentChanged =
true;
2283 pData->DoCalcError(
this );
2291 if (pProgress && pProgress->
Enabled())
2331 OSL_ENSURE(
pCode->
GetCodeError() != FormulaError::NONE,
"no RPN code and no errors ?!?!" );
2346 std::unique_ptr<ScInterpreter> pScopedInterpreter;
2352 pInterpreter = pScopedInterpreter.get();
2393 else if (nCols || nRows)
2425 if (nHint == SfxHintId::ScReference)
2475 if (!(nHint == SfxHintId::ScDataChanged || nHint == SfxHintId::ScTableOpDirty || (
bSubTotal && nHint == SfxHintId::ScHiddenRowsChanged)))
2478 bool bForceTrack =
false;
2479 if ( nHint == SfxHintId::ScTableOpDirty )
2509 switch (rQuery.
getId())
2565 mxGroup->mbPartOfCycle =
false;
2650 if ( (nBits & ScRecalcMode::EMask) != ScRecalcMode::NORMAL )
2684 OUString aCellString;
2686 const Color* pColor;
2698 pFormatter->
GetOutputString( fValue, nCellFormat, rCellText, &pColor );
2703 pFormatter->
GetOutputString( aCellString, nCellFormat, rCellText, &pColor );
2709 if (!xMat->IsValue(0, 1))
2710 rURL = xMat->GetString(0, 1).getString();
2713 xMat->GetDouble(0, 1), nURLFormat, rURL, &pColor);
2721 pFormatter->
GetOutputString( aCellString, nURLFormat, rURL, &pColor );
2861 static thread_local SCCOL nC;
2862 static thread_local SCROW nR;
2866 if ( aOrg != rOrgPos )
2878 if ( nC == 0 || nR == 0 )
2921#if OSL_DEBUG_LEVEL > 0
2922 SAL_WARN(
"sc",
"broken Matrix, no MatFormula at origin, Pos: "
2934 if ( dC >= 0 && dR >= 0 && dC < nC && dR < nR )
2949 SAL_WARN(
"sc",
"broken Matrix, Pos: "
2953 <<
", MatCols: " <<
static_cast<sal_Int32
>( nC )
2954 <<
", MatRows: " <<
static_cast<sal_Int32
>( nR )
2955 <<
", DiffCols: " <<
static_cast<sal_Int32
>( dC )
2956 <<
", DiffRows: " <<
static_cast<sal_Int32
>( dR ));
2973 if (nErr != FormulaError::NONE)
2981 if (nErr != FormulaError::NONE)
2991 if (rErr != FormulaError::NONE)
3002 if (nErr != FormulaError::NONE)
3011 if (nErr != FormulaError::NONE)
3052 if (pFirstReference)
3056 std::vector<formula::FormulaToken*> aReferences { pFirstReference };
3061 if (lcl_isReference(*pToken))
3063 aReferences.push_back(pToken);
3078 return lcl_refListFormsOneRange(
rDocument,
aPos, aReferences, rRange);
3091 switch (
t->GetType())
3098 if (
t->GetDoubleRef()->Ref1.IsRelName() ||
t->GetDoubleRef()->Ref2.IsRelName())
3132 assert(!
"can't move ScFormulaCell");
3143bool checkCompileColRowName(
3158 while ((t = aIter.GetNextColRowName()) !=
nullptr)
3197 bool bMoved = (aPos != aOldPos);
3203 for (;
t;
t = aIter.GetNextColRowName())
3224void setOldCodeToUndo(
3239 rUndoDoc, aUndoPos, pOldCode ? *pOldCode :
ScTokenArray(rUndoDoc), eTempGrammar, cMatrixFlag);
3254 bool bCellStateChanged =
false;
3257 aUndoPos = *pUndoCellPos;
3263 bool bHasColRowNames =
false;
3267 bHasRefs = bHasColRowNames;
3271 if (!bHasRefs && !bOnRefMove)
3274 return bCellStateChanged;
3276 std::unique_ptr<ScTokenArray> pOldCode;
3280 bool bValChanged =
false;
3281 bool bRefModified =
false;
3294 if (bValChanged || bRefModified)
3295 bCellStateChanged =
true;
3299 bOnRefMove = (bValChanged || (
aPos != aOldPos) || bRefModified);
3301 bool bNewListening =
false;
3302 bool bInDeleteUndo =
false;
3308 if (bHasColRowNames && !bRecompile)
3309 bRecompile = checkCompileColRowName(rCxt,
rDocument, *
pCode, aOldPos,
aPos, bValChanged);
3312 bInDeleteUndo = (pChangeTrack && pChangeTrack->
IsInDeleteUndo());
3315 bool bHasRelName =
false;
3324 bNewListening = (bRefModified || bRecompile
3325 || (bValChanged && bInDeleteUndo) || bHasRelName);
3327 if ( bNewListening )
3332 bool bNeedDirty = (bValChanged || bRecompile || bOnRefMove);
3334 if (pUndoDoc && (bValChanged || bOnRefMove))
3344 if ( !bInDeleteUndo )
3347 if ( bNewListening )
3364 return bCellStateChanged;
3375 aUndoPos = *pUndoCellPos;
3380 if ( bCellInMoveTarget )
3391 bool bHasColRowNames =
false;
3395 bHasRefs = bHasColRowNames;
3399 if (!bHasRefs && !bOnRefMove)
3404 bool bCellStateChanged =
false;
3405 std::unique_ptr<ScTokenArray> pOldCode;
3409 bool bValChanged =
false;
3410 bool bRefModified =
false;
3423 if (bValChanged || bRefModified)
3424 bCellStateChanged =
true;
3428 bOnRefMove = (bValChanged || (
aPos != aOldPos));
3430 bool bColRowNameCompile =
false;
3431 bool bHasRelName =
false;
3432 bool bNewListening =
false;
3433 bool bInDeleteUndo =
false;
3439 if (bHasColRowNames)
3440 bColRowNameCompile = checkCompileColRowName(rCxt,
rDocument, *
pCode, aOldPos,
aPos, bValChanged);
3443 bInDeleteUndo = (pChangeTrack && pChangeTrack->
IsInDeleteUndo());
3451 bNewListening = (bRefModified || bColRowNameCompile
3452 || bValChanged || bHasRelName)
3458 if ( bNewListening )
3462 bool bNeedDirty =
false;
3464 if ( bRefModified || bColRowNameCompile ||
3465 (bValChanged && bHasRelName ) || bOnRefMove)
3468 if (pUndoDoc && !bCellInMoveTarget && (bValChanged || bRefModified || bOnRefMove))
3471 bValChanged =
false;
3480 if ( !bInDeleteUndo )
3483 if ( bNewListening )
3495 return bCellStateChanged;
3506 aUndoPos = *pUndoCellPos;
3521 bHasRefs = bHasRefs || bHasColRowNames;
3524 if (!bHasRefs && !bOnRefMove)
3529 std::unique_ptr<ScTokenArray> pOldCode;
3535 bOnRefMove = (
aPos != aOldPos);
3537 bool bNeedDirty = bOnRefMove;
3539 if (pUndoDoc && bOnRefMove)
3719 if (nTable != rRef1.
Tab())
3721 else if (nTable !=
aPos.
Tab())
3729 if(nTable != rRef2.
Tab())
3731 else if (nTable !=
aPos.
Tab())
3742 if ( bForceIfNameInUse && !
bCompile )
3761 bool bFound =
false;
3793 bool bPosChanged =
false;
3802 if ( aDestRange.
Contains( aOldPos ) )
3810 aOldPos.
Set( nRelPosX, nRelPosY, nRelPosZ );
3814 std::unique_ptr<ScTokenArray> pOld;
3817 bool bRefChanged =
false;
3823 if(
t->GetOpCode() ==
ocName )
3877 bool bRefChanged =
false;
3884 if(
t->GetOpCode() ==
ocName )
3923 sal_uInt16 nTokenIndex =
p->GetIndex();
3924 SCTAB nTab =
p->GetSheet();
3927 if (nRecursion < 126)
3951 pCode = pNew.release();
4001 SAL_INFO(
"sc.opencl",
"You can't create a new group if the cell is already a part of a group");
4007 mxGroup->mbInvariant = bInvariant;
4055 if ( !pThis || !pOther )
4061 if ( nThisLen != nOtherLen )
4071 bool bInvariant =
true;
4074 for ( sal_uInt16
i = 0;
i < nThisLen;
i++ )
4176 if ( !pThis || !pOther )
4182 if ( nThisLen != nOtherLen )
4185 for ( sal_uInt16
i = 0;
i < nThisLen;
i++ )
4267int splitup(
int N,
int K,
int&
A)
4277 const int ideal_num_parts =
N / K;
4278 if (ideal_num_parts * K == N)
4279 return ideal_num_parts;
4281 const int num_parts = ideal_num_parts + 1;
4282 const int nominal_part_size =
N / num_parts;
4284 A =
N - num_parts * nominal_part_size;
4289struct ScDependantsCalculator
4296 const bool mFromFirstRow;
4297 const SCROW mnStartOffset;
4298 const SCROW mnEndOffset;
4299 const SCROW mnSpanLen;
4305 mxGroup(rCell.GetCellGroup()),
4306 mnLen(mxGroup->mnLength),
4311 mFromFirstRow(fromFirstRow),
4312 mnStartOffset(nStartOffset),
4313 mnEndOffset(nEndOffset),
4314 mnSpanLen(nEndOffset - nStartOffset + 1)
4324 bool isSelfReferenceRelative(
const ScAddress& rRefPos,
SCROW nRelRow)
4333 SCROW nTest = nEndRow;
4342 if (nTest <= nEndRow)
4357 bool isSelfReferenceAbsolute(
const ScAddress& rRefPos)
4368 if (rRefPos.
Row() > nEndRow && !mFromFirstRow)
4377 bool isDoubleRefSpanGroupRange(
const ScRange& rAbs,
bool bIsRef1RowRel,
bool bIsRef2RowRel)
4386 SCROW nEndRow = nStartRow + mnLen - 1;
4390 if (bIsRef1RowRel && bIsRef2RowRel &&
4391 ((nRefStartRow <= nStartRow && nRefEndRow >= nEndRow) ||
4392 ((nRefStartRow + mnLen - 1) <= nStartRow &&
4393 (nRefEndRow + mnLen - 1) >= nEndRow)))
4396 if (!bIsRef1RowRel && nRefStartRow <= nStartRow &&
4397 (nRefEndRow >= nEndRow || (nRefEndRow + mnLen - 1) >= nEndRow))
4400 if (!bIsRef2RowRel &&
4401 nRefStartRow <= nStartRow && nRefEndRow >= nEndRow)
4406 if (mFromFirstRow && nRefEndRow >= nStartRow)
4415 SCROW nLastRow = nRow + nRowLen - 1;
4417 if (nLastRow < (nRow + nRowLen - 1))
4422 nRowLen = nLastRow - nRow + 1;
4428 else if (nLastRow == 0)
4442 bool bHasSelfReferences =
false;
4447 for (sal_Int32 nTokenIdx = nCodeLen-1; nTokenIdx >= 0; --nTokenIdx)
4449 auto p = pRPNArray[nTokenIdx];
4450 if (!bInDocShellRecalc)
4458 OpCode nOpCode =
p->GetOpCode();
4459 if (nOpCode == ocIf || nOpCode == ocIfs_MS || nOpCode == ocSwitch_MS)
4463 switch (
p->GetType())
4477 if (isSelfReferenceRelative(aRefPos, aRef.
Row()))
4479 bHasSelfReferences =
true;
4484 SCROW nTrimLen = trimLength(aRefPos.
Tab(), aRefPos.
Col(), aRefPos.
Col(), aRefPos.
Row() + mnStartOffset, mnSpanLen);
4487 aRefPos.
Col(), aRefPos.
Row() + mnStartOffset + nTrimLen - 1, aRefPos.
Tab()));
4491 if (isSelfReferenceAbsolute(aRefPos))
4493 bHasSelfReferences =
true;
4518 bHasSelfReferences =
true;
4522 else if (isSelfReferenceAbsolute(aAbs.
aStart))
4524 bHasSelfReferences =
true;
4531 if (isSelfReferenceRelative(aAbs.
aEnd, aRef.
Ref2.
Row()))
4533 bHasSelfReferences =
true;
4537 else if (isSelfReferenceAbsolute(aAbs.
aEnd))
4539 bHasSelfReferences =
true;
4543 if (isDoubleRefSpanGroupRange(aAbs, bIsRef1RowRel, bIsRef2RowRel))
4545 bHasSelfReferences =
true;
4554 SCROW nArrayLength = nLastRefRow - nFirstRefRow + 1;
4555 assert(nArrayLength > 0);
4561 aAbs.
aEnd.
Col(), nFirstRefRow + nArrayLength - 1, aAbs.
aEnd.
Tab()));
4572 for (
size_t i = 0;
i < aRangeList.
size(); ++
i)
4574 const ScRange & rRange = aRangeList[
i];
4591 if (bHasSelfReferences)
4592 mxGroup->mbPartOfCycle =
true;
4594 return !bHasSelfReferences;
4610 aScope.addMessage(
"This formula-group is part of a cycle");
4616 static constexpr OUStringLiteral MESSAGE =
u"group calc disabled";
4617 aScope.addMessage(MESSAGE);
4629 aScope.addGroupSizeThresholdMessage(*
this);
4636 aScope.addMessage(
"matrix skipped");
4650 aScope.addMessage(
"cell not in document");
4657 nStartOffset = nStartOffset < 0 ? 0 : std::min(nStartOffset, nMaxOffset);
4658 nEndOffset = nEndOffset < 0 ? nMaxOffset : std::min(nEndOffset, nMaxOffset);
4660 if (nEndOffset < nStartOffset)
4663 nEndOffset = nMaxOffset;
4673 RecursionCounter aRecursionCounter( rRecursionHelper,
this);
4675 bool bDependencyComputed =
false;
4676 bool bDependencyCheckFailed =
false;
4691 bool bCalcDependencyOnly)
4697 if (bCalcDependencyOnly)
4703 ScDependantsCalculator aCalculator(
rDocument, *
pCode, *
this,
mxGroup->mpTopCell->aPos, fromFirstRow, nStartOffset, nEndOffset);
4704 return aCalculator.DoIt();
4707 bool bOKToParallelize =
false;
4713 rScope.
addMessage(
"found circular formula-group dependencies");
4718 ScDependantsCalculator aCalculator(
rDocument, *
pCode, *
this,
mxGroup->mpTopCell->aPos, fromFirstRow, nStartOffset, nEndOffset);
4719 bOKToParallelize = aCalculator.DoIt();
4726 rScope.
addMessage(
"Recursion limit reached, cannot thread this formula group now");
4733 rScope.
addMessage(
"found circular formula-group dependencies");
4741 rScope.
addMessage(
"multi-group-dependency failed");
4745 if (!bOKToParallelize)
4748 rScope.
addMessage(
"could not do new dependencies calculation thing");
4757 std::map<SCCOL, ScFormulaCell*>& rFGMap,
bool bLeft)
4759 const SCROW nLen = xGroup->mnLength;
4760 const sal_Int32 nWt = xGroup->mnWeight;
4761 ScAddress aAddr(xGroup->mpTopCell->aPos);
4771 while (nColRet >= 0 && nColRet <= nMaxCol)
4788 if (xNGroup->mpTopCell->aPos.Row() != aAddr.
Row())
4791 const SCROW nNLen = xNGroup->mnLength;
4792 const sal_Int32 nNWt = pCell->
GetWeight();
4793 if (nNLen != nLen || nNWt != nWt)
4796 rFGSet.
insert(xNGroup.get());
4797 rFGMap[nColRet] = xNGroup->mpTopCell;
4815 bool& bDependencyComputed,
4816 bool& bDependencyCheckFailed,
4820 static const bool bThreadingProhibited = std::getenv(
"SC_NO_THREADED_CALCULATION");
4821 if (!bDependencyCheckFailed && !bThreadingProhibited &&
4827 bDependencyComputed =
true;
4828 bDependencyCheckFailed =
true;
4832 bDependencyComputed =
true;
4839 const unsigned mnThisThread;
4840 const unsigned mnThreadsTotal;
4846 SCROW mnStartOffset;
4850 Executor(
const std::shared_ptr<comphelper::ThreadTaskTag>& rTag,
4851 unsigned nThisThread,
4852 unsigned nThreadsTotal,
4861 mnThisThread(nThisThread),
4862 mnThreadsTotal(nThreadsTotal),
4863 mpDocument(pDocument2),
4866 mnStartCol(nStartCol),
4868 mnStartOffset(nStartOff),
4869 mnEndOffset(nEndOff)
4873 virtual void doWork()
override
4875 ScRange aCalcRange(mnStartCol, mrTopPos.
Row() + mnStartOffset, mrTopPos.
Tab(),
4876 mnEndCol, mrTopPos.
Row() + mnEndOffset, mrTopPos.
Tab());
4887 SAL_INFO(
"sc.threaded",
"Running " << nThreadCount <<
" threads");
4890 std::map<SCCOL, ScFormulaCell*> aFGMap;
4895 SCCOL nColEnd = nColStart;
4902 if (nColStart != nColEnd)
4905 for (
SCCOL nCurrCol = nColStart; nCurrCol <= nColEnd; ++nCurrCol)
4910 bool bFGOK = aFGMap[nCurrCol]->CheckComputeDependencies(aScope,
false, nStartOffset, nEndOffset,
true);
4913 nColEnd = nColStart =
aPos.
Col();
4919 std::vector<std::unique_ptr<ScInterpreter>> aInterpreters(nThreadCount);
4931 for (
int i = 0;
i < nThreadCount; ++
i)
4939 nColStart, nColEnd, nStartOffset, nEndOffset));
4942 SAL_INFO(
"sc.threaded",
"Waiting for threads to finish work");
4949 for (
int i = 0;
i < nThreadCount; ++
i)
4961 SCROW nSpanLen = nEndOffset - nStartOffset + 1;
4962 aStartPos.
SetRow(aStartPos.
Row() + nStartOffset);
4965 aStartPos.
Tab(), aInterpreters[0].get());
4975 bool& bDependencyComputed,
4976 bool& bDependencyCheckFailed)
4987 aScope.
addMessage(
"group calc disabled due to vector state (non-vector-supporting opcode)");
4990 aScope.
addMessage(
"group calc disabled due to vector state (non-vector-supporting stack variable)");
4993 aScope.
addMessage(
"group calc disabled due to vector state (opcode not in subset)");
4998 aScope.
addMessage(
"group calc disabled due to vector state (unknown)");
5015 if (bDependencyCheckFailed)
5020 bDependencyComputed =
true;
5021 bDependencyCheckFailed =
true;
5025 bDependencyComputed =
true;
5029 if (
mxGroup->mbInvariant &&
false)
5032 int nMaxGroupLength = INT_MAX;
5039 nMaxGroupLength = 1000;
5042 if (std::getenv(
"SC_MAX_GROUP_LENGTH"))
5043 nMaxGroupLength = std::atoi(std::getenv(
"SC_MAX_GROUP_LENGTH"));
5046 const int nNumParts = splitup(
GetSharedLength(), nMaxGroupLength, nNumOnePlus);
5051 for (
int i = 0;
i < nNumParts;
i++, nOffset += nCurChunkSize)
5063 xGroup->mpTopCell =
mxGroup->mpTopCell;
5064 xGroup->mpTopCell->aPos = aOrigPos;
5065 xGroup->mpTopCell->aPos.
IncRow(nOffset);
5066 xGroup->mbInvariant =
mxGroup->mbInvariant;
5067 xGroup->mnLength = nCurChunkSize;
5068 xGroup->mpCode = std::move(
mxGroup->mpCode);
5080 SAL_INFO(
"sc.opencl",
"group " << xGroup->mpTopCell->aPos <<
" has unhandled implicit intersections, disabling");
5084 SAL_INFO(
"sc.opencl",
"unhandled implicit intersection opcode "
5086 <<
"(" <<
int(opcode) <<
")");
5091 SAL_INFO(
"sc.opencl",
"conversion of group " << xGroup->mpTopCell->aPos <<
" failed, disabling");
5098 mxGroup->mpTopCell->aPos = aOrigPos;
5099 xGroup->mpTopCell =
nullptr;
5100 mxGroup->mpCode = std::move(xGroup->mpCode);
5103 aScope.
addMessage(
"group token conversion failed");
5112 if (pInterpreter ==
nullptr ||
5115 SAL_INFO(
"sc.opencl",
"interpreting group " <<
mxGroup->mpTopCell->aPos
5116 <<
" (state " <<
static_cast<int>(
mxGroup->meCalcState) <<
") failed, disabling");
5122 mxGroup->mpTopCell->aPos = aOrigPos;
5123 xGroup->mpTopCell =
nullptr;
5124 mxGroup->mpCode = std::move(xGroup->mpCode);
5127 aScope.
addMessage(
"group interpretation unsuccessful");
5135 xGroup->mpTopCell =
nullptr;
5136 mxGroup->mpCode = std::move(xGroup->mpCode);
5141 mxGroup->mpTopCell->aPos = aOrigPos;
5157 switch (
p->GetType())
5200 for ( sal_Int32
i = 0;
i <
mxGroup->mnLength;
i++ )
5207 SAL_WARN(
"sc.core.formulacell",
"GetFormulaCell not found");
5224void startListeningArea(
5234 if (rToken.
GetOpCode() == ocColRowNameAuto)
5253 mxGroup->endAllGroupListening(rDoc);
5272 switch (
t->GetType())
5282 startListeningArea(
this, rDoc,
aPos, *
t);
5296 mxGroup->endAllGroupListening(rDoc);
5315 switch (
t->GetType())
5325 startListeningArea(
this, rDoc,
aPos, *
t);
5336void endListeningArea(
5346 if (rToken.
GetOpCode() == ocColRowNameAuto)
5367 mxGroup->endAllGroupListening(rDoc);
5377 if (
GetCode()->IsRecalcModeAlways() )
5392 switch (
t->GetType())
5402 endListeningArea(
this, rDoc, aCellPos, *
t);
5439 switch (
t->GetType())
5449 endListeningArea(
this, rDoc, aCellPos, *
t);
5467 return mxGroup->mpTopCell ==
this;
5517#if DUMP_COLUMN_STORAGE
5522 cout <<
" * shared: " << (
mxGroup ?
"true" :
"false") << endl;
5525 cout <<
" * shared length: " <<
mxGroup->mnLength <<
endl;
5526 cout <<
" * shared calc state: " <<
mxGroup->meCalcState <<
endl;
5533 cout <<
" * code error: ";
5534 if (nErrCode == FormulaError::NONE)
5539 cout <<
" * code error: " <<
aStr <<
" (" <<
int(nErrCode) <<
")";
5543 cout <<
" * result: ";
5548 cout << aRV.
mfValue <<
" (value)";
5557 cout <<
"(invalid)";
size_t SCSIZE
size_t typedef to be able to find places where code was changed from USHORT to size_t and is used to ...
#define BCA_LISTEN_ALWAYS
triangulator::B2DTriangleVector maResult
@ ForceCalculationThreads
void IncTab(SCTAB nDelta=1)
void Set(SCCOL nCol, SCROW nRow, SCTAB nTab)
SC_DLLPUBLIC void Format(OStringBuffer &r, ScRefFlags nFlags, const ScDocument *pDocument=nullptr, const Details &rDetails=detailsOOOa1) const
SC_DLLPUBLIC bool Move(SCCOL nDeltaX, SCROW nDeltaY, SCTAB nDeltaZ, ScAddress &rErrorPos, const ScDocument &rDoc)
void IncCol(SCCOL nDelta=1)
void IncRow(SCROW nDelta=1)
bool IsInDeleteUndo() const
bool AreGroupsIndependent()
bool HasUnhandledPossibleImplicitIntersections() const
void CreateStringFromXMLTokenArray(OUString &rFormula, OUString &rFormulaNmsp)
const std::set< OpCode > & UnhandledPossibleImplicitIntersectionsOpCodes()
std::unique_ptr< ScTokenArray > CompileString(const OUString &rFormula)
Tokenize formula expression string into an array of tokens.
Stores global named database ranges.
bool insert(std::unique_ptr< ScDBData > p)
Takes ownership of p and attempts to insert it into the collection.
ScDBData * findByIndex(sal_uInt16 nIndex)
ScDBData * findByUpperName(const OUString &rName)
const OUString & GetUpperName() const
sal_uInt16 GetIndex() const
sal_uInt16 GetIterCount() const
bool IsCalcAsShown() const
double GetIterEps() const
bool IsInFormulaTree(const ScFormulaCell *pCell) const
SC_DLLPUBLIC SCCOL GetAllocatedColumnsCount(SCTAB nTab) const
void TrackFormulas(SfxHintId nHintId=SfxHintId::ScDataChanged)
void SetThreadedGroupCalcInProgress(bool set)
ScSheetLimits & GetSheetLimits() const
SC_DLLPUBLIC sal_uInt32 GetNumberFormat(SCCOL nCol, SCROW nRow, SCTAB nTab) const
bool IsInFormulaTrack(const ScFormulaCell *pCell) const
SC_DLLPUBLIC ScFormulaCell * SetFormulaCell(const ScAddress &rPos, ScFormulaCell *pCell)
Set formula cell, and transfer its ownership to the document.
bool IsInInterpreterTableOp() const
static sal_uInt16 GetSrcVersion()
bool IsInDocShellRecalc() const
sal_uInt64 GetFormulaCodeInTree() const
void SetDetectiveDirty(bool bSet)
ScRangePairList * GetRowNameRanges()
void EndListeningArea(const ScRange &rRange, bool bGroupListening, SvtListener *pListener)
SC_DLLPUBLIC SCCOL MaxCol() const
SC_DLLPUBLIC const ScValidationData * GetValidationEntry(sal_uInt32 nIndex) const
HardRecalcState GetHardRecalcState() const
SC_DLLPUBLIC ScMacroManager * GetMacroManager()
SC_DLLPUBLIC ScDocumentPool * GetPool()
bool ValidAddress(const ScAddress &rAddress) const
void DecXMLImportedFormulaCount(sal_uInt64 nVal)
ScRangeData * FindRangeNameBySheetAndIndex(SCTAB nTab, sal_uInt16 nIndex) const
Find a named expression / range name in either global or a local scope.
SC_DLLPUBLIC SCROW MaxRow() const
void RemoveFromFormulaTree(ScFormulaCell *pCell)
SC_DLLPUBLIC void CheckLinkFormulaNeedingCheck(const ScTokenArray &rCode)
Check token array and set link check if ocDde/ocWebservice is contained.
bool IsInDdeLinkUpdate() const
void MergeContextBackIntoNonThreadedContext(ScInterpreterContext &threadedContext, int threadNumber)
void AddTableOpFormulaCell(ScFormulaCell *)
SC_DLLPUBLIC double RoundValueAsShown(double fVal, sal_uInt32 nFormat, const ScInterpreterContext *pContext=nullptr) const
SC_DLLPUBLIC SCROW GetLastDataRow(SCTAB nTab, SCCOL nCol1, SCCOL nCol2, SCROW nLastRow) const
Return the last non-empty row position in given columns that's no greater than the initial last row p...
ScInterpreterContext & GetNonThreadedContext() const
SC_DLLPUBLIC ScExternalRefManager * GetExternalRefManager() const
bool IsInLayoutStrings() const
void SetStreamValid(SCTAB nTab, bool bSet, bool bIgnoreLock=false)
bool GetNoListening() const
void AddSubTotalCell(ScFormulaCell *pCell)
ScRecursionHelper & GetRecursionHelper()
SC_DLLPUBLIC bool GetAutoCalc() const
SC_DLLPUBLIC void SetNumberFormat(const ScAddress &rPos, sal_uInt32 nNumberFormat)
ScRangePairList * GetColNameRanges()
bool IsStreamValid(SCTAB nTab) const
void RemoveFromFormulaTrack(ScFormulaCell *pCell)
SC_DLLPUBLIC formula::FormulaGrammar::Grammar GetGrammar() const
void MarkUsedExternalReferences()
void StartListeningArea(const ScRange &rRange, bool bGroupListening, SvtListener *pListener)
void EndListeningCell(const ScAddress &rAddress, SvtListener *pListener)
bool IsClipOrUndo() const
SC_DLLPUBLIC ScDBCollection * GetDBCollection() const
sal_uInt64 GetXMLImportedFormulaCount() const
void SetupContextFromNonThreadedContext(ScInterpreterContext &threadedContext, int threadNumber)
bool IsInsertingFromOtherDoc() const
SC_DLLPUBLIC svl::SharedStringPool & GetSharedStringPool()
void AppendToFormulaTrack(ScFormulaCell *pCell)
void RemoveSubTotalCell(ScFormulaCell *pCell)
void HandleStuffAfterParallelCalculation(SCCOL nColStart, SCCOL nColEnd, SCROW nRow, size_t nLen, SCTAB nTab, ScInterpreter *pInterpreter)
bool IsThreadedGroupCalcInProgress() const
SC_DLLPUBLIC SvNumberFormatter * GetFormatTable() const
bool HasExternalRefManager() const
bool IsInDtorClear() const
bool HandleRefArrayForParallelism(const ScAddress &rPos, SCROW nLength, const ScFormulaCellGroupRef &mxGroup)
SC_DLLPUBLIC const ScFormulaCell * GetFormulaCell(const ScAddress &rPos) const
void SetDBCollection(std::unique_ptr< ScDBCollection > pNewDBCollection, bool bRemoveAutoFilter=false)
ScChangeTrack * GetChangeTrack() const
SC_DLLPUBLIC CellType GetCellType(SCCOL nCol, SCROW nRow, SCTAB nTab) const
SC_DLLPUBLIC bool HasTable(SCTAB nTab) const
bool CopyAdjustRangeName(SCTAB &rSheet, sal_uInt16 &rIndex, ScRangeData *&rpRangeData, ScDocument &rNewDoc, const ScAddress &rNewPos, const ScAddress &rOldPos, const bool bGlobalNamesToLocal, const bool bUsedByFormula) const
If necessary (name references sheet rOldPos.Tab()) copy and adjust named expression/range from sheet-...
bool IsClipboardSource() const
void PutInFormulaTree(ScFormulaCell *pCell)
SC_DLLPUBLIC const SfxPoolItem * GetAttr(SCCOL nCol, SCROW nRow, SCTAB nTab, sal_uInt16 nWhich) const
formula::FormulaTokenRef ResolveStaticReference(const ScAddress &rPos)
SC_DLLPUBLIC const ScDocOptions & GetDocOptions() const
void StartListeningCell(const ScAddress &rAddress, SvtListener *pListener)
void CalculateInColumnInThread(ScInterpreterContext &rContext, const ScRange &rCalcRange, unsigned nThisThread, unsigned nThreadsTotal)
bool IsImportingXML() const
static std::unique_ptr< EditTextObject > CreateURLObjectFromURL(ScDocument &rDoc, const OUString &rURL, const OUString &rText)
void insertRefCellFromTemplate(ScFormulaCell *pTemplateCell, ScFormulaCell *pCell)
Add a cell to reference the same files as the template cell.
void removeRefCell(ScFormulaCell *pCell)
Stop tracking a specific formula cell.
static SC_DLLPUBLIC sal_uInt32 GetStandardFormat(SvNumberFormatter &, sal_uInt32 nFormat, SvNumFormatType nType)
static OUString GetErrorString(FormulaError nErrNumber)
bool convert(const ScTokenArray &rCode, sc::FormulaLogger::GroupScope &rScope)
ScInterpreterContext * GetInterpreterContext() const
sal_uLong GetRetFormatIndex() const
formula::StackVar Interpret()
formula::StackVar GetResultType() const
const svl::SharedString & GetStringResult() const
const formula::FormulaConstTokenRef & GetResultToken() const
static const ScCalcConfig & GetGlobalConfig()
void Init(ScFormulaCell *pCell, const ScAddress &rPos, ScTokenArray &rTokArray)
double GetNumResult() const
SvNumFormatType GetRetFormatType() const
FormulaError GetError() const
VolatileType GetVolatileType() const
void RemoveDependentCell(const ScFormulaCell *pCell)
Matrix data type that can store values of mixed types.
void GetDimensions(SCSIZE &rC, SCSIZE &rR) const
void SetStateCountDownOnPercent(sal_uInt64 nVal)
static ScProgress * GetInterpretProgress()
bool HasReferences() const
void Join(const ScRange &, bool bIsInList=false)
ScRangePair * Find(const ScAddress &)
const ScRange & GetRange(sal_uInt16 n) const
bool Contains(const ScAddress &) const
is Address& fully in Range?
bool IsInRecursionReturn() const
A pure recursion return, no iteration.
void SetDoingRecursion(bool b)
void SetInRecursionReturn(bool b)
const ScFormulaRecursionList::iterator & GetLastIterationStart() const
sal_uInt16 GetIteration() const
sal_uInt16 GetDepComputeLevel() const
bool IsInIterationReturn() const
ScRecursionInIterationStack & GetRecursionInIterationStack()
const ScFormulaRecursionList & GetList() const
bool CheckFGIndependence(ScFormulaCellGroup *pFG)
bool AnyParentFGInCycle()
void SetInIterationReturn(bool b)
bool & GetConvergingReference()
ScFormulaRecursionList::iterator GetIterationStart()
void AbortDependencyComputation()
bool IsDoingRecursion() const
void Insert(ScFormulaCell *p, bool bOldRunning, const ScFormulaResult &rRes)
bool AreGroupsIndependent()
bool IsDoingIteration() const
bool HasFormulaGroupSet() const
bool IsAbortingDependencyComputation() const
bool AnyCycleMemberInDependencyEvalMode(const ScFormulaCell *pCell)
bool IsInReturn() const
Any return, recursion or iteration, iteration is always coupled with recursion.
sal_uInt16 GetRecursionCount() const
ScFormulaRecursionList::iterator GetIterationEnd()
static ScRefUpdateRes UpdateTranspose(const ScDocument &rDoc, const ScRange &rSource, const ScAddress &rDest, ScRange &rRef)
static void DoTranspose(SCCOL &rCol, SCROW &rRow, SCTAB &rTab, const ScDocument &rDoc, const ScRange &rSource, const ScAddress &rDest)
static ScRefUpdateRes UpdateGrow(const ScRange &rArea, SCCOL nGrowX, SCROW nGrowY, ScRange &rRef)
ScInterpreterContext * GetInterpreterContextForThreadIdx(size_t nThreadIdx) const
sc::RefUpdateResult AdjustReferenceOnMovedTab(const sc::RefUpdateMoveTabContext &rCxt, const ScAddress &rOldPos)
void AdjustReferenceOnCopy(const ScAddress &rNewPos)
Adjust internal range references on base position change to justify / put in order the relative refer...
ScTokenArray CloneValue() const
True copy!
sc::RefUpdateResult AdjustReferenceOnShift(const sc::RefUpdateContext &rCxt, const ScAddress &rOldPos)
Adjust all references in response to shifting of cells during cell insertion and deletion.
std::unique_ptr< ScTokenArray > Clone() const
bool IsEnabledForThreading() const
ScFormulaVectorState GetVectorState() const
void MoveReferenceColReorder(const ScAddress &rPos, SCTAB nTab, SCROW nRow1, SCROW nRow2, const sc::ColRowReorderMapType &rColMap)
Move reference positions in response to column reordering.
bool IsEnabledForOpenCL() const
sc::RefUpdateResult AdjustReferenceOnDeletedTab(const sc::RefUpdateDeleteTabContext &rCxt, const ScAddress &rOldPos)
Adjust all references on sheet deletion.
sc::RefUpdateResult AdjustReferenceOnInsertedTab(const sc::RefUpdateInsertTabContext &rCxt, const ScAddress &rOldPos)
sc::RefUpdateResult AdjustReferenceOnMove(const sc::RefUpdateContext &rCxt, const ScAddress &rOldPos, const ScAddress &rNewPos)
OUString CreateString(sc::TokenStringContext &rCxt, const ScAddress &rPos) const
Create a string representation of formula token array without modifying the internal state of the tok...
sal_Int32 GetWeight() const
void MoveReferenceRowReorder(const ScAddress &rPos, SCTAB nTab, SCCOL nCol1, SCCOL nCol2, const sc::ColRowReorderMapType &rRowMap)
void AdjustAbsoluteRefs(const ScDocument &rOldDoc, const ScAddress &rOldPos, const ScAddress &rNewPos, bool bCheckCopyArea)
Make all absolute references pointing to the copied range if the range is copied too.
void ReadjustAbsolute3DReferences(const ScDocument &rOldDoc, ScDocument &rNewDoc, const ScAddress &rPos, bool bRangeName=false)
Make all absolute references external references pointing to the old document.
virtual void Clear() override
const ScSingleRefData & Ref2
const ScSingleRefData & Ref1
bool HasBroadcaster() const
static ThreadPool & getSharedOptimalPool()
void waitUntilDone(const std::shared_ptr< ThreadTaskTag > &, bool bJoin=true)
static std::shared_ptr< ThreadTaskTag > createThreadTaskTag()
void pushTask(std::unique_ptr< ThreadTask > pTask)
sal_Int32 getWorkerCount() const
std::pair< const_iterator, bool > insert(Value &&x)
Temporarily switch on/off auto calculation mode.
void setGrammar(formula::FormulaGrammar::Grammar eGram)
ScAddress getOldPosition(const ScAddress &rPos) const
ScTokenArray * getOldCode()
const sc::ColRowReorderMapType & getColMap() const
SCROW getStartRow() const
const sc::ColRowReorderMapType & getRowMap() const
SCCOL getEndColumn() const
SCCOL getStartColumn() const
Keep track of all named expressions that have been updated during reference update.
void setUpdatedName(SCTAB nTab, sal_uInt16 nIndex)
const OUString & getString() const
static const SharedString & getEmptyString()
FormulaError GetDoubleErrorValue(double fVal)
@ StartListening
If set, cloned formula cells will start to listen to the document.
@ NoMakeAbsExternal
If set, absolute refs will not transformed to external references.
@ Default
Default cell clone flags: do not start listening, do not adjust 3D refs to old position,...
@ NamesToLocal
If set, global named expressions will be converted to sheet-local named expressions.
#define SC_LISTENER_QUERY_FORMULA_GROUP_POS
#define SAL_WARN(area, stream)
#define SAL_INFO(area, stream)
if(aStr !=aBuf) UpdateName_Impl(m_xFollowLb.get()
std::unique_ptr< sal_Int32[]> pData
CAUTION! The following defines must be in the same namespace as the respective type.
const std::function< void()> maFunc
#define MIN_NO_CODES_PER_PROGRESS_UPDATE
#define SC_MATRIX_DOUBLEREF
@ UR_NOTHING
Reference not affected, no change at all.
const wchar_t *typedef int(__stdcall *DllNativeUnregProc)(int
constexpr TypedWhichId< SfxUInt32Item > ATTR_VALIDDATA(153)
ParserContextSharedPtr mpContext
TOOLS_DLLPUBLIC SvStream & endl(SvStream &rStr)
bool operator<(const AreaListenerKey &r) const
static bool isOpenCLEnabled()
static ForceCalculationType getForceCalculationType()
static bool isThreadingEnabled()
Complex reference (a range) into the sheet.
SC_DLLPUBLIC ScRange toAbs(const ScSheetLimits &rLimits, const ScAddress &rPos) const
void SetRange(const ScSheetLimits &rLimits, const ScRange &rRange, const ScAddress &rPos)
Set a new range, assuming that the ordering of the range matches the ordering of the reference data f...
SvNumberFormatter * GetFormatTable() const
std::vector< DelayedSetNumberFormat > maDelayedSetNumberFormat
ScInterpreter * pInterpreter
Instantiate this to ensure that subsequent modification of the document will cause an assertion failu...
This is very similar to ScCellValue, except that it references the original value instead of copying ...
Single reference (one address) into the sheet.
void SetAbsTab(SCTAB nVal)
void SetRelRow(SCROW nVal)
ScAddress toAbs(const ScSheetLimits &rLimits, const ScAddress &rPos) const
void SetRelCol(SCCOL nVal)
void SetFlag3D(bool bVal)
Context for reference update during shifting, moving or copying of cell ranges.
SCROW mnRowDelta
Amount and direction of movement in the row direction.
UpdateRefMode meMode
update mode - insert/delete, copy, or move.
SCCOL mnColDelta
Amount and direction of movement in the column direction.
SCTAB mnTabDelta
Amount and direction of movement in the sheet direction.
ScRange maRange
Range of cells that are about to be moved for insert/delete/move modes.
bool mbReferenceModified
This flag indicates whether any reference in the token array has been modified.
bool mbValueChanged
When this flag is true, the result of the formula needs to be re-calculated either because it contain...
bool mbNameModified
When this flag is true, it indicates that the token array contains a range name that's been updated.
Context for creating string from an array of formula tokens, used in ScTokenArray::CreateString().
sal_Int32 SCCOLROW
a type capable of holding either SCCOL or SCROW
::boost::intrusive_ptr< ScFormulaCellGroup > ScFormulaCellGroupRef
::boost::intrusive_ptr< const ScMatrix > ScConstMatrixRef
@ FormulaVectorDisabledByOpCode
@ FormulaVectorDisabledByStackVariable
@ FormulaVectorDisabledNotInSubSet
@ FormulaVectorCheckReference
#define SV_COUNTRY_LANGUAGE_OFFSET
constexpr sal_uInt32 NUMBERFORMAT_ENTRY_NOT_FOUND