Kaydet (Commit) 2caaf9bf authored tarafından Dennis Francis's avatar Dennis Francis Kaydeden (comit) Eike Rathke

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/39883Tested-by: 's avatarJenkins <ci@libreoffice.org>
Reviewed-by: 's avatarEike Rathke <erack@redhat.com>
üst 3cf9b747
......@@ -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);
......
......@@ -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.
......
......@@ -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;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment