summaryrefslogtreecommitdiff
path: root/sc/source/core/tool/sharedformula.cxx
diff options
context:
space:
mode:
authorKohei Yoshida <kohei.yoshida@collabora.com>2014-11-12 22:18:49 -0500
committerKohei Yoshida <kohei.yoshida@collabora.com>2014-11-18 08:31:55 -0500
commit2030b9ac6c68ba6f15b0283e0b4e57ae49bd67b0 (patch)
treedc7ad2b2f890ea0ac614d7820c2e655c84327c3f /sc/source/core/tool/sharedformula.cxx
parent192f6a41444b62feae03185975c120f770e2938f (diff)
Dedicated listener type tailored for formula groups.
Right now, it's only used when loading an xlsx file. But eventually this one should be used everywhere. Change-Id: I216c3a9a33c4b8040e8284d59299e0637471fb50
Diffstat (limited to 'sc/source/core/tool/sharedformula.cxx')
-rw-r--r--sc/source/core/tool/sharedformula.cxx78
1 files changed, 77 insertions, 1 deletions
diff --git a/sc/source/core/tool/sharedformula.cxx b/sc/source/core/tool/sharedformula.cxx
index 65d91a73d7dc..ce00fc31421e 100644
--- a/sc/source/core/tool/sharedformula.cxx
+++ b/sc/source/core/tool/sharedformula.cxx
@@ -10,6 +10,11 @@
#include "sharedformula.hxx"
#include "calcmacros.hxx"
#include "tokenarray.hxx"
+#include <listenercontext.hxx>
+#include <document.hxx>
+#include <grouparealistener.hxx>
+
+#define USE_FORMULA_GROUP_LISTENER 1
namespace sc {
@@ -328,15 +333,86 @@ void SharedFormulaUtil::unshareFormulaCells(CellStoreType& rCells, std::vector<S
void SharedFormulaUtil::startListeningAsGroup( sc::StartListeningContext& rCxt, ScFormulaCell** ppSharedTop )
{
- assert((**ppSharedTop).IsSharedTop());
+ ScFormulaCell& rTopCell = **ppSharedTop;
+ assert(rTopCell.IsSharedTop());
+
+#if USE_FORMULA_GROUP_LISTENER
+ ScDocument& rDoc = rCxt.getDoc();
+ rDoc.SetDetectiveDirty(true);
+
+ ScFormulaCellGroupRef xGroup = rTopCell.GetCellGroup();
+ const ScTokenArray* pCode = xGroup->mpCode;
+ assert(pCode == rTopCell.GetCode());
+ if (pCode->IsRecalcModeAlways())
+ {
+ rDoc.StartListeningArea(
+ BCA_LISTEN_ALWAYS, false,
+ xGroup->getAreaListener(ppSharedTop, BCA_LISTEN_ALWAYS, true, true));
+ }
+
+ formula::FormulaToken** p = pCode->GetCode();
+ formula::FormulaToken** pEnd = p + pCode->GetCodeLen();
+ for (; p != pEnd; ++p)
+ {
+ const formula::FormulaToken* t = *p;
+ switch (t->GetType())
+ {
+ case formula::svSingleRef:
+ {
+ ScAddress aPos = t->GetSingleRef()->toAbs(rTopCell.aPos);
+ ScFormulaCell** pp = ppSharedTop;
+ ScFormulaCell** ppEnd = ppSharedTop + xGroup->mnLength;
+ for (; pp != ppEnd; ++pp, aPos.IncRow())
+ {
+ if (!aPos.IsValid())
+ break;
+
+ rDoc.StartListeningCell(rCxt, aPos, **pp);
+ }
+ }
+ break;
+ case formula::svDoubleRef:
+ {
+ const ScSingleRefData& rRef1 = *t->GetSingleRef();
+ const ScSingleRefData& rRef2 = *t->GetSingleRef2();
+ ScAddress aPos1 = rRef1.toAbs(rTopCell.aPos);
+ ScAddress aPos2 = rRef2.toAbs(rTopCell.aPos);
+
+ ScRange aOrigRange = ScRange(aPos1, aPos2);
+ ScRange aListenedRange = aOrigRange;
+ if (rRef2.IsRowRel())
+ aListenedRange.aEnd.IncRow(xGroup->mnLength-1);
+
+ if (aPos1.IsValid() && aPos2.IsValid())
+ {
+ rDoc.StartListeningArea(
+ aListenedRange, true,
+ xGroup->getAreaListener(ppSharedTop, aOrigRange, !rRef1.IsRowRel(), !rRef2.IsRowRel()));
+ }
+ }
+ break;
+ default:
+ ;
+ }
+ }
ScFormulaCell** pp = ppSharedTop;
+ ScFormulaCell** ppEnd = ppSharedTop + xGroup->mnLength;
+ for (; pp != ppEnd; ++pp)
+ {
+ ScFormulaCell& rCell = **pp;
+ rCell.SetNeedsListening(false);
+ }
+
+#else
+ ScFormulaCell** pp = ppSharedTop;
ScFormulaCell** ppEnd = ppSharedTop + (**ppSharedTop).GetSharedLength();
for (; pp != ppEnd; ++pp)
{
ScFormulaCell& rFC = **pp;
rFC.StartListeningTo(rCxt);
}
+#endif
}
}