diff options
author | Eike Rathke <erack@redhat.com> | 2018-07-14 14:09:12 +0200 |
---|---|---|
committer | Eike Rathke <erack@redhat.com> | 2018-07-14 15:38:47 +0200 |
commit | 4247120b0edc0429a228dc8ea0ea820aa2f09214 (patch) | |
tree | 84cba4aa192afc0c8b473a4d4b256f600a757e49 | |
parent | db2d8301613f2eb95b76f3468d92a06dfd49fff4 (diff) |
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 <erack@redhat.com>
Tested-by: Jenkins
-rw-r--r-- | sc/inc/documentimport.hxx | 7 | ||||
-rw-r--r-- | sc/source/core/data/documentimport.cxx | 52 | ||||
-rw-r--r-- | sc/source/filter/oox/workbookfragment.cxx | 3 |
3 files changed, 62 insertions, 0 deletions
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 <listenercontext.hxx> #include <attarray.hxx> #include <sharedformula.hxx> +#include <bcaslot.hxx> +#include <scopetools.hxx> #include <svl/sharedstringpool.hxx> #include <svl/languageoptions.hxx> @@ -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 -------------------------------------------------------------------- |