summaryrefslogtreecommitdiff
path: root/sc
diff options
context:
space:
mode:
authorEike Rathke <erack@redhat.com>2023-02-23 01:22:16 +0100
committerEike Rathke <erack@redhat.com>2023-02-23 01:33:48 +0000
commit05ac57f85eb622b798719db03bbdd07b79e1703a (patch)
tree3b1c11568d722d0aefd98a3e47d94be04b06abbd /sc
parente5a744851cb58da1ceeef623799274d73b60b030 (diff)
Resolves: tdf#153767 Try harder to import OOXML bool shared formula result
... by setting the result value or if necessary recalculating even if AutoCalc is turned off for the document. Similar for other implicitly recalculating formula types. Also set a boolean number format if none. Change-Id: I2f75735707180eccf4b2c525738ac0b763901230 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/147425 Reviewed-by: Eike Rathke <erack@redhat.com> Tested-by: Jenkins
Diffstat (limited to 'sc')
-rw-r--r--sc/inc/document.hxx2
-rw-r--r--sc/inc/formulacell.hxx3
-rw-r--r--sc/source/core/data/formulacell.cxx8
-rw-r--r--sc/source/filter/oox/formulabuffer.cxx31
-rw-r--r--sc/source/ui/view/output2.cxx13
5 files changed, 41 insertions, 16 deletions
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index 20e42a999ac8..c6b2f2289ddb 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -1224,7 +1224,7 @@ public:
SC_DLLPUBLIC sal_uInt32 GetNumberFormat( SCCOL nCol, SCROW nRow, SCTAB nTab ) const;
sal_uInt32 GetNumberFormat( const ScRange& rRange ) const;
SC_DLLPUBLIC sal_uInt32 GetNumberFormat( const ScInterpreterContext& rContext, const ScAddress& ) const;
- void SetNumberFormat( const ScAddress& rPos, sal_uInt32 nNumberFormat );
+ SC_DLLPUBLIC void SetNumberFormat( const ScAddress& rPos, sal_uInt32 nNumberFormat );
void GetNumberFormatInfo( const ScInterpreterContext& rContext, SvNumFormatType& nType, sal_uInt32& nIndex, const ScAddress& rPos ) const;
SC_DLLPUBLIC const ScFormulaCell* GetFormulaCell( const ScAddress& rPos ) const;
diff --git a/sc/inc/formulacell.hxx b/sc/inc/formulacell.hxx
index e4bc41772e0e..42b7f6120149 100644
--- a/sc/inc/formulacell.hxx
+++ b/sc/inc/formulacell.hxx
@@ -445,7 +445,8 @@ public:
if (!IsDirtyOrInTableOpDirty())
return false;
- return (rDocument.GetAutoCalc() || (cMatrixFlag != ScMatrixMode::NONE));
+ return rDocument.GetAutoCalc() || (cMatrixFlag != ScMatrixMode::NONE)
+ || (pCode->IsRecalcModeMustAfterImport() && !pCode->IsRecalcModeAlways());
}
void MaybeInterpret()
diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx
index 143b27579a83..0e2840284ec5 100644
--- a/sc/source/core/data/formulacell.cxx
+++ b/sc/source/core/data/formulacell.cxx
@@ -2331,6 +2331,8 @@ void ScFormulaCell::InterpretTail( ScInterpreterContext& rContext, ScInterpretTa
OSL_ENSURE( pCode->GetCodeError() != FormulaError::NONE, "no RPN code and no errors ?!?!" );
ResetDirty();
}
+
+ pCode->ClearRecalcModeMustAfterImport();
}
void ScFormulaCell::HandleStuffAfterParallelCalculation(ScInterpreter* pInterpreter)
@@ -2546,7 +2548,7 @@ void ScFormulaCell::SetDirty( bool bDirtyFlag )
// the FormulaTree, once in there it would be assumed that its
// dependents already had been tracked and it would be skipped on a
// subsequent notify. Postpone tracking until all listeners are set.
- if (!rDocument.IsImportingXML())
+ if (!rDocument.IsImportingXML() && !rDocument.IsInsertingFromOtherDoc())
rDocument.TrackFormulas();
}
@@ -2647,10 +2649,6 @@ void ScFormulaCell::AddRecalcMode( ScRecalcMode nBits )
{
if ( (nBits & ScRecalcMode::EMask) != ScRecalcMode::NORMAL )
SetDirtyVar();
- if ( nBits & ScRecalcMode::ONLOAD_ONCE )
- { // OnLoadOnce is used only to set Dirty after filter import.
- nBits = (nBits & ~ScRecalcMode::EMask) | ScRecalcMode::NORMAL;
- }
pCode->AddRecalcMode( nBits );
}
diff --git a/sc/source/filter/oox/formulabuffer.cxx b/sc/source/filter/oox/formulabuffer.cxx
index 3b81e89e45c2..dc934d1d41a4 100644
--- a/sc/source/filter/oox/formulabuffer.cxx
+++ b/sc/source/filter/oox/formulabuffer.cxx
@@ -22,6 +22,7 @@
#include <oox/token/tokens.hxx>
#include <oox/helper/progressbar.hxx>
#include <svl/sharedstringpool.hxx>
+#include <svl/numformat.hxx>
#include <sal/log.hxx>
using namespace ::com::sun::star::uno;
@@ -154,20 +155,41 @@ void applySharedFormulas(
pCell = new ScFormulaCell(rDoc.getDoc(), aPos, *pArray);
rDoc.setFormulaCell(aPos, pCell);
- if (rDoc.getDoc().GetNumberFormat(aPos.Col(), aPos.Row(), aPos.Tab()) % SV_COUNTRY_LANGUAGE_OFFSET == 0)
+ const bool bNeedNumberFormat = ((rDoc.getDoc().GetNumberFormat(
+ aPos.Col(), aPos.Row(), aPos.Tab()) % SV_COUNTRY_LANGUAGE_OFFSET) == 0);
+ if (bNeedNumberFormat)
pCell->SetNeedNumberFormat(true);
if (rDesc.maCellValue.isEmpty())
{
// No cached cell value. Mark it for re-calculation.
pCell->SetDirty();
+ // Recalc even if AutoCalc is disabled. Must be after
+ // SetDirty() as it also calls SetDirtyVar().
+ pCell->AddRecalcMode( ScRecalcMode::ONLOAD_ONCE);
continue;
}
- // Set cached formula results. For now, we only use numeric and string-formula
- // results. Find out how to utilize cached results of other types.
+ // Set cached formula results. For now, we only use boolean,
+ // numeric and string-formula results. Find out how to utilize
+ // cached results of other types.
switch (rDesc.mnValueType)
{
+ case XML_b:
+ // boolean value.
+ if (bNeedNumberFormat)
+ {
+ rDoc.getDoc().SetNumberFormat( aPos,
+ rDoc.getDoc().GetFormatTable()->GetStandardFormat( SvNumFormatType::LOGICAL));
+ }
+ if (rDesc.maCellValue == "1" || rDesc.maCellValue == "0")
+ pCell->SetResultDouble(rDesc.maCellValue == "1" ? 1.0 : 0.0);
+ else
+ {
+ // Recalc even if AutoCalc is disabled.
+ pCell->AddRecalcMode( ScRecalcMode::ONLOAD_ONCE);
+ }
+ break;
case XML_n:
// numeric value.
pCell->SetResultDouble(rDesc.maCellValue.toDouble());
@@ -193,6 +215,9 @@ void applySharedFormulas(
default:
// Mark it for re-calculation.
pCell->SetDirty();
+ // Recalc even if AutoCalc is disabled. Must be after
+ // SetDirty() as it also calls SetDirtyVar().
+ pCell->AddRecalcMode( ScRecalcMode::ONLOAD_ONCE);
}
}
}
diff --git a/sc/source/ui/view/output2.cxx b/sc/source/ui/view/output2.cxx
index 5f09c292c176..649ccdd7349e 100644
--- a/sc/source/ui/view/output2.cxx
+++ b/sc/source/ui/view/output2.cxx
@@ -1484,9 +1484,15 @@ tools::Rectangle ScOutputData::LayoutStrings(bool bPixelToLogic, bool bPaint, co
mpDev->GetMapMode().GetMapUnit() == mpRefDevice->GetMapMode().GetMapUnit(),
"LayoutStrings: different MapUnits ?!?!" );
+ sc::IdleSwitch aIdleSwitch(*mpDoc, false);
+
+ // Try to limit interpreting to only visible cells. Calling e.g. IsValue()
+ // on a formula cell that needs interpreting would call Interpret()
+ // for the entire formula group, which could be large.
+ mpDoc->InterpretCellsIfNeeded( ScRange( nX1, nY1, nTab, nX2, nY2, nTab ));
+
vcl::PDFExtOutDevData* pPDFData = dynamic_cast< vcl::PDFExtOutDevData* >(mpDev->GetExtOutDevData() );
- sc::IdleSwitch aIdleSwitch(*mpDoc, false);
ScDrawStringsVars aVars( this, bPixelToLogic );
bool bProgress = false;
@@ -1514,11 +1520,6 @@ tools::Rectangle ScOutputData::LayoutStrings(bool bPixelToLogic, bool bPaint, co
const SfxItemSet* pOldCondSet = nullptr;
SvtScriptType nOldScript = SvtScriptType::NONE;
- // Try to limit interpreting to only visible cells. Calling e.g. IsValue()
- // on a formula cell that needs interpreting would call Interpret()
- // for the entire formula group, which could be large.
- mpDoc->InterpretCellsIfNeeded( ScRange( nX1, nY1, nTab, nX2, nY2, nTab ));
-
// alternative pattern instances in case we need to modify the pattern
// before processing the cell value.
std::vector<std::unique_ptr<ScPatternAttr> > aAltPatterns;