[Libreoffice-commits] core.git: Branch 'libreoffice-5-4-0' - sc/qa sc/source

Dennis Francis dennis.francis at collabora.co.uk
Fri Jul 21 09:24:52 UTC 2017


 sc/qa/unit/ucalc.hxx                |    4 +
 sc/qa/unit/ucalc_formula.cxx        |  126 ++++++++++++++++++++++++++++++++++++
 sc/source/core/data/formulacell.cxx |    6 +
 3 files changed, 134 insertions(+), 2 deletions(-)

New commits:
commit beb7e49e6906c5f2bbe18c87a70a47b57dd4cb2f
Author: Dennis Francis <dennis.francis at collabora.co.uk>
Date:   Thu Jul 13 11:35:41 2017 +0530

    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 at libreoffice.org>
    Reviewed-by: Eike Rathke <erack at redhat.com>
    (cherry picked from commit 2caaf9bfe8d3f81517467daf36de0bd8ddd6b543)
    Reviewed-on: https://gerrit.libreoffice.org/39923
    Reviewed-by: Markus Mohrhard <markus.mohrhard at googlemail.com>
    Reviewed-by: Michael Meeks <michael.meeks at collabora.com>
    Tested-by: Michael Meeks <michael.meeks at collabora.com>

diff --git a/sc/qa/unit/ucalc.hxx b/sc/qa/unit/ucalc.hxx
index 5d1def66c7c7..bddf2eda1ff8 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();
@@ -562,6 +564,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 223b88dd1f2f..3f04ff0a0c45 100644
--- a/sc/qa/unit/ucalc_formula.cxx
+++ b/sc/qa/unit/ucalc_formula.cxx
@@ -2316,6 +2316,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 b23814f77047..630ba6208869 100644
--- a/sc/source/core/data/formulacell.cxx
+++ b/sc/source/core/data/formulacell.cxx
@@ -3191,7 +3191,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
@@ -3280,7 +3282,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;


More information about the Libreoffice-commits mailing list