From 4247120b0edc0429a228dc8ea0ea820aa2f09214 Mon Sep 17 00:00:00 2001 From: Eike Rathke Date: Sat, 14 Jul 2018 14:09:12 +0200 Subject: Broadcast formula cells marked for recalc, tdf#94925 related In fact the ScDocument::CalcFormulaTree() call in WorkbookFragment::recalcFormulaCells() never did anything because no formula cell was added to the tree. Only visible dirty cells were recalculated, but not their dependents. Change-Id: I11217fa19adb766f509d0d6854502112de547c59 Reviewed-on: https://gerrit.libreoffice.org/57431 Reviewed-by: Eike Rathke Tested-by: Jenkins --- sc/inc/documentimport.hxx | 7 +++++ sc/source/core/data/documentimport.cxx | 52 +++++++++++++++++++++++++++++++ sc/source/filter/oox/workbookfragment.cxx | 3 ++ 3 files changed, 62 insertions(+) diff --git a/sc/inc/documentimport.hxx b/sc/inc/documentimport.hxx index f902e1858741..1a8b1cbd514f 100644 --- a/sc/inc/documentimport.hxx +++ b/sc/inc/documentimport.hxx @@ -125,8 +125,15 @@ public: void finalize(); + /** Broadcast all formula cells that are marked with + FormulaTokenArray::IsRecalcModeMustAfterImport() for a subsequent + ScDocument::CalcFormulaTree(). + */ + void broadcastRecalcAfterImport(); + private: void initColumn(ScColumn& rCol); + void broadcastRecalcAfterImportColumn(ScColumn& rCol); }; #endif diff --git a/sc/source/core/data/documentimport.cxx b/sc/source/core/data/documentimport.cxx index c51acb900d81..1c0ce77c3102 100644 --- a/sc/source/core/data/documentimport.cxx +++ b/sc/source/core/data/documentimport.cxx @@ -22,6 +22,8 @@ #include #include #include +#include +#include #include #include @@ -720,4 +722,54 @@ void ScDocumentImport::initColumn(ScColumn& rCol) rCol.CellStorageModified(); } +namespace { + +class CellStoreAfterImportBroadcaster +{ +public: + + CellStoreAfterImportBroadcaster() {} + + void operator() (const sc::CellStoreType::value_type& node) + { + if (node.type == sc::element_type_formula) + { + // Broadcast all formula cells marked for recalc. + ScFormulaCell** pp = &sc::formula_block::at(*node.data, 0); + ScFormulaCell** ppEnd = pp + node.size; + for (; pp != ppEnd; ++pp) + { + if ((*pp)->GetCode()->IsRecalcModeMustAfterImport()) + (*pp)->SetDirty(); + } + } + } +}; + +} + +void ScDocumentImport::broadcastRecalcAfterImport() +{ + sc::AutoCalcSwitch aACSwitch( mpImpl->mrDoc, false); + ScBulkBroadcast aBulkBroadcast( mpImpl->mrDoc.GetBASM(), SfxHintId::ScDataChanged); + + ScDocument::TableContainer::iterator itTab = mpImpl->mrDoc.maTabs.begin(), itTabEnd = mpImpl->mrDoc.maTabs.end(); + for (; itTab != itTabEnd; ++itTab) + { + if (!*itTab) + continue; + + ScTable& rTab = **itTab; + SCCOL nNumCols = rTab.aCol.size(); + for (SCCOL nColIdx = 0; nColIdx < nNumCols; ++nColIdx) + broadcastRecalcAfterImportColumn(rTab.aCol[nColIdx]); + } +} + +void ScDocumentImport::broadcastRecalcAfterImportColumn(ScColumn& rCol) +{ + CellStoreAfterImportBroadcaster aFunc; + std::for_each(rCol.maCells.begin(), rCol.maCells.end(), aFunc); +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/filter/oox/workbookfragment.cxx b/sc/source/filter/oox/workbookfragment.cxx index 068df46ff443..330dcb073b2d 100644 --- a/sc/source/filter/oox/workbookfragment.cxx +++ b/sc/source/filter/oox/workbookfragment.cxx @@ -577,7 +577,10 @@ void WorkbookFragment::recalcFormulaCells() if (bHardRecalc) rDocSh.DoHardRecalc(); else + { + getDocImport().broadcastRecalcAfterImport(); rDoc.CalcFormulaTree(false, true, false); + } } // private -------------------------------------------------------------------- -- cgit