summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEike Rathke <erack@redhat.com>2018-07-14 14:09:12 +0200
committerEike Rathke <erack@redhat.com>2018-07-14 15:38:47 +0200
commit4247120b0edc0429a228dc8ea0ea820aa2f09214 (patch)
tree84cba4aa192afc0c8b473a4d4b256f600a757e49
parentdb2d8301613f2eb95b76f3468d92a06dfd49fff4 (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.hxx7
-rw-r--r--sc/source/core/data/documentimport.cxx52
-rw-r--r--sc/source/filter/oox/workbookfragment.cxx3
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 --------------------------------------------------------------------