From a5803a66fd9d71b72521d712ba4391ddd570bffa Mon Sep 17 00:00:00 2001 From: Eike Rathke Date: Fri, 13 Jul 2018 19:29:12 +0200 Subject: Rework FormulaTokenArray ScRecalcMode in preparation for tdf#94925 Strictly order the exclusive bits by priority, let AddRecalcMode() handle all sets except forced ALWAYS or NORMAL. Introduce ONLOAD_LENIENT and ONLOAD_MUST splitting ONLOAD to be able to distinguish later during OOXML import. Change-Id: I188de2d53a2d54df32d24eeeb148c4f9e87e7cfc Reviewed-on: https://gerrit.libreoffice.org/57402 Reviewed-by: Eike Rathke Tested-by: Jenkins --- formula/source/core/api/FormulaCompiler.cxx | 17 +++++++++-------- formula/source/core/api/token.cxx | 28 ++++++++++++++++++++-------- 2 files changed, 29 insertions(+), 16 deletions(-) (limited to 'formula') diff --git a/formula/source/core/api/FormulaCompiler.cxx b/formula/source/core/api/FormulaCompiler.cxx index 671d2c2b9f62..ac42bd3df588 100644 --- a/formula/source/core/api/FormulaCompiler.cxx +++ b/formula/source/core/api/FormulaCompiler.cxx @@ -1428,14 +1428,15 @@ void FormulaCompiler::Factor() switch( eOp ) { // Functions recalculated on every document load. - // Don't use SetExclusiveRecalcModeOnLoad() which would - // override ModeAlways, use - // AddRecalcMode(ScRecalcMode::ONLOAD) instead. + // ONLOAD_LENIENT here to be able to distinguish and not + // force a recalc (if not in an ALWAYS or ONLOAD_MUST + // context) but keep an imported result from for example + // OOXML a DDE call. Will be recalculated for ODFF. case ocConvertOOo : case ocDde: case ocMacro: case ocExternal: - pArr->AddRecalcMode( ScRecalcMode::ONLOAD ); + pArr->AddRecalcMode( ScRecalcMode::ONLOAD_LENIENT ); break; // If the referred cell is moved the value changes. case ocColumn : @@ -1443,15 +1444,15 @@ void FormulaCompiler::Factor() pArr->SetRecalcModeOnRefMove(); break; // ocCell needs recalc on move for some possible type values. - // and recalc mode on load, fdo#60646 + // And recalc mode on load, tdf#60645 case ocCell : pArr->SetRecalcModeOnRefMove(); - pArr->AddRecalcMode( ScRecalcMode::ONLOAD ); + pArr->AddRecalcMode( ScRecalcMode::ONLOAD_MUST ); break; case ocHyperLink : - // cell with hyperlink needs to be calculated on load to + // Cell with hyperlink needs to be calculated on load to // get its matrix result generated. - pArr->AddRecalcMode( ScRecalcMode::ONLOAD ); + pArr->AddRecalcMode( ScRecalcMode::ONLOAD_MUST ); pArr->SetHyperLink( true); break; default: diff --git a/formula/source/core/api/token.cxx b/formula/source/core/api/token.cxx index 42b19f8543c0..a8fb0b42541d 100644 --- a/formula/source/core/api/token.cxx +++ b/formula/source/core/api/token.cxx @@ -845,15 +845,27 @@ FormulaToken* FormulaTokenArray::AddStringXML( const OUString& rStr ) void FormulaTokenArray::AddRecalcMode( ScRecalcMode nBits ) { - //! Order is important. - if ( nBits & ScRecalcMode::ALWAYS ) - SetExclusiveRecalcModeAlways(); - else if ( !IsRecalcModeAlways() ) + const unsigned nExclusive = static_cast(nBits & ScRecalcMode::EMask); + if (nExclusive) { - if ( nBits & ScRecalcMode::ONLOAD ) - SetExclusiveRecalcModeOnLoad(); - else if ( nBits & ScRecalcMode::ONLOAD_ONCE && !IsRecalcModeOnLoad() ) - SetExclusiveRecalcModeOnLoadOnce(); + unsigned nExBit; + if (nExclusive & (nExclusive - 1)) + { + // More than one bit set, use highest priority. + for (nExBit = 1; (nExBit & static_cast(ScRecalcMode::EMask)) != 0; nExBit <<= 1) + { + if (nExclusive & nExBit) + break; + } + } + else + { + // Only one bit is set. + nExBit = nExclusive; + } + // Set exclusive bit if priority is higher than existing. + if (nExBit < static_cast(nMode & ScRecalcMode::EMask)) + SetMaskedRecalcMode( static_cast(nExBit)); } SetCombinedBitsRecalcMode( nBits ); } -- cgit