summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDennis Francis <dennis.francis@collabora.co.uk>2017-07-13 11:35:41 +0530
committerEike Rathke <erack@redhat.com>2017-07-13 17:24:58 +0200
commit2caaf9bfe8d3f81517467daf36de0bd8ddd6b543 (patch)
tree3aaf50e4647dc023b98f580cf907c9b1b5b93f7a
parent3cf9b747141bc5f74dc64cefbc5d5b2611ab0a4d (diff)
tdf#108758 : do not write to undo document when...
...updating references during a block move, for formula cells that are in the target range of the move operation. The fix is for formula cells that are not grouped. For the grouped case, it was already doing correctly. Added two unit tests in ucalc_formula.cxx for grouped formula and non-grouped formula cases. Change-Id: I9f4d988f5e154f56670bd1c0cc366ee6704fb858 Reviewed-on: https://gerrit.libreoffice.org/39883 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Eike Rathke <erack@redhat.com>
-rw-r--r--sc/qa/unit/ucalc.hxx4
-rw-r--r--sc/qa/unit/ucalc_formula.cxx126
-rw-r--r--sc/source/core/data/formulacell.cxx6
3 files changed, 134 insertions, 2 deletions
diff --git a/sc/qa/unit/ucalc.hxx b/sc/qa/unit/ucalc.hxx
index 85efd25e7dc2..1a2ded57017f 100644
--- a/sc/qa/unit/ucalc.hxx
+++ b/sc/qa/unit/ucalc.hxx
@@ -152,6 +152,8 @@ public:
void testFormulaRefUpdateMove();
void testFormulaRefUpdateMoveUndo();
void testFormulaRefUpdateMoveUndo2();
+ void testFormulaRefUpdateMoveUndo3NonShared();
+ void testFormulaRefUpdateMoveUndo3Shared();
void testFormulaRefUpdateMoveToSheet();
void testFormulaRefUpdateDeleteContent();
void testFormulaRefUpdateDeleteAndShiftLeft();
@@ -566,6 +568,8 @@ public:
CPPUNIT_TEST(testFormulaRefUpdateMove);
CPPUNIT_TEST(testFormulaRefUpdateMoveUndo);
CPPUNIT_TEST(testFormulaRefUpdateMoveUndo2);
+ CPPUNIT_TEST(testFormulaRefUpdateMoveUndo3NonShared);
+ CPPUNIT_TEST(testFormulaRefUpdateMoveUndo3Shared);
CPPUNIT_TEST(testFormulaRefUpdateMoveToSheet);
CPPUNIT_TEST(testFormulaRefUpdateDeleteContent);
CPPUNIT_TEST(testFormulaRefUpdateDeleteAndShiftLeft);
diff --git a/sc/qa/unit/ucalc_formula.cxx b/sc/qa/unit/ucalc_formula.cxx
index 81e567fde3bb..407008dccd9c 100644
--- a/sc/qa/unit/ucalc_formula.cxx
+++ b/sc/qa/unit/ucalc_formula.cxx
@@ -2347,6 +2347,132 @@ void Test::testFormulaRefUpdateMoveUndo2()
m_pDoc->DeleteTab(0);
}
+void Test::testFormulaRefUpdateMoveUndo3NonShared()
+{
+ m_pDoc->InsertTab(0, "Test");
+
+ sc::AutoCalcSwitch aACSwitch(*m_pDoc, true); // turn auto calc on.
+
+ std::vector<std::vector<const char*>> aData = {
+ { "10", nullptr, nullptr },
+ { "=A1", nullptr, nullptr },
+ { "=A2+A1", nullptr, nullptr },
+ };
+
+ ScRange aOutRange = insertRangeData(m_pDoc, ScAddress(0,0,0), aData);
+
+ std::vector<std::vector<const char*>> aCheckInitial = {
+ { "10", nullptr, nullptr },
+ { "10", nullptr, nullptr },
+ { "20", nullptr, nullptr },
+ };
+
+ bool bGood = checkOutput(m_pDoc, aOutRange, aCheckInitial, "initial data");
+ CPPUNIT_ASSERT(bGood);
+
+ // Drag A2:A3 into C2:C3.
+ ScDocFunc& rFunc = getDocShell().GetDocFunc();
+ bool bMoved = rFunc.MoveBlock(ScRange(0,1,0,0,2,0), ScAddress(2,1,0), true, true, false, true);
+ CPPUNIT_ASSERT(bMoved);
+
+ std::vector<std::vector<const char*>> aCheckAfter = {
+ { "10", nullptr, nullptr},
+ { nullptr, nullptr, "10" },
+ { nullptr, nullptr, "20" },
+ };
+
+ bGood = checkOutput(m_pDoc, aOutRange, aCheckAfter, "A2:A3 moved to C2:C3");
+ CPPUNIT_ASSERT(bGood);
+
+ // Undo the move.
+ SfxUndoManager* pUndoMgr = m_pDoc->GetUndoManager();
+ CPPUNIT_ASSERT(pUndoMgr);
+ pUndoMgr->Undo();
+
+ bGood = checkOutput(m_pDoc, aOutRange, aCheckInitial, "after undo");
+ CPPUNIT_ASSERT(bGood);
+
+ // Redo and check.
+ pUndoMgr->Redo();
+
+ bGood = checkOutput(m_pDoc, aOutRange, aCheckAfter, "after redo");
+ CPPUNIT_ASSERT(bGood);
+
+ m_pDoc->DeleteTab(0);
+}
+
+void Test::testFormulaRefUpdateMoveUndo3Shared()
+{
+ m_pDoc->InsertTab(0, "Test");
+
+ sc::AutoCalcSwitch aACSwitch(*m_pDoc, true); // turn auto calc on.
+
+ std::vector<std::vector<const char*>> aData = {
+ { "10", nullptr, nullptr },
+ { "=A1", nullptr, nullptr },
+ { "=A2+$A$1", nullptr, nullptr },
+ { "=A3+$A$1", nullptr, nullptr },
+ };
+
+ ScRange aOutRange = insertRangeData(m_pDoc, ScAddress(0,0,0), aData);
+
+ std::vector<std::vector<const char*>> aCheckInitial = {
+ { "10", nullptr, nullptr },
+ { "10", nullptr, nullptr },
+ { "20", nullptr, nullptr },
+ { "30", nullptr, nullptr },
+ };
+
+ bool bGood = checkOutput(m_pDoc, aOutRange, aCheckInitial, "initial data");
+ CPPUNIT_ASSERT(bGood);
+
+ // A3:A4 should be grouped.
+ const ScFormulaCell* pFC = m_pDoc->GetFormulaCell(ScAddress(0,2,0));
+ CPPUNIT_ASSERT(pFC);
+ CPPUNIT_ASSERT_EQUAL(SCROW(2), pFC->GetSharedLength());
+
+ // Drag A2:A4 into C2:C4.
+ ScDocFunc& rFunc = getDocShell().GetDocFunc();
+ bool bMoved = rFunc.MoveBlock(ScRange(0,1,0,0,3,0), ScAddress(2,1,0), true, true, false, true);
+ CPPUNIT_ASSERT(bMoved);
+
+ std::vector<std::vector<const char*>> aCheckAfter = {
+ { "10", nullptr, nullptr},
+ { nullptr, nullptr, "10" },
+ { nullptr, nullptr, "20" },
+ { nullptr, nullptr, "30" },
+ };
+
+ bGood = checkOutput(m_pDoc, aOutRange, aCheckAfter, "A2:A4 moved to C2:C4");
+ CPPUNIT_ASSERT(bGood);
+
+ // C3:C4 should be grouped.
+ pFC = m_pDoc->GetFormulaCell(ScAddress(2,2,0));
+ CPPUNIT_ASSERT(pFC);
+ CPPUNIT_ASSERT_EQUAL(SCROW(2), pFC->GetSharedLength());
+
+ // Undo the move.
+ SfxUndoManager* pUndoMgr = m_pDoc->GetUndoManager();
+ CPPUNIT_ASSERT(pUndoMgr);
+ pUndoMgr->Undo();
+
+ bGood = checkOutput(m_pDoc, aOutRange, aCheckInitial, "after undo");
+ CPPUNIT_ASSERT(bGood);
+
+ // A3:A4 should be grouped.
+ pFC = m_pDoc->GetFormulaCell(ScAddress(0,2,0));
+ CPPUNIT_ASSERT(pFC);
+ CPPUNIT_ASSERT_EQUAL(SCROW(2), pFC->GetSharedLength());
+
+ // Redo and check.
+ pUndoMgr->Redo();
+
+ bGood = checkOutput(m_pDoc, aOutRange, aCheckAfter, "after redo");
+ CPPUNIT_ASSERT(bGood);
+
+ m_pDoc->DeleteTab(0);
+}
+
void Test::testFormulaRefUpdateMoveToSheet()
{
sc::AutoCalcSwitch aACSwitch(*m_pDoc, true); // turn auto calc on.
diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx
index 2f340a7aa602..c0a363c78a5a 100644
--- a/sc/source/core/data/formulacell.cxx
+++ b/sc/source/core/data/formulacell.cxx
@@ -3172,7 +3172,9 @@ bool ScFormulaCell::UpdateReferenceOnMove(
aUndoPos = *pUndoCellPos;
ScAddress aOldPos( aPos );
- if (rCxt.maRange.In(aPos))
+ bool bCellInMoveTarget = rCxt.maRange.In(aPos);
+
+ if ( bCellInMoveTarget )
{
// The cell is being moved or copied to a new position. I guess the
// position has been updated prior to this call? Determine
@@ -3260,7 +3262,7 @@ bool ScFormulaCell::UpdateReferenceOnMove(
(bValChanged && bHasRelName ) || bOnRefMove)
bNeedDirty = true;
- if (pUndoDoc && (bValChanged || bRefModified || bOnRefMove))
+ if (pUndoDoc && !bCellInMoveTarget && (bValChanged || bRefModified || bOnRefMove))
setOldCodeToUndo(pUndoDoc, aUndoPos, pOldCode.get(), eTempGrammar, cMatrixFlag);
bValChanged = false;