sc/qa/unit/ucalc.cxx           |  490 ----------------------------------------
 sc/qa/unit/ucalc_copypaste.cxx |  498 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 498 insertions(+), 490 deletions(-)

New commits:
commit eb5e2e70ab4eaab9fea555160e61b24bd9941a63
Author:     scito <i...@scito.ch>
AuthorDate: Sat Jun 5 11:42:19 2021 +0200
Commit:     Xisco Fauli <xiscofa...@libreoffice.org>
CommitDate: Mon Jun 7 09:59:58 2021 +0200

    move remaining copy/paste tests from ucalc to ucalc_copypaste
    
    MixData test cases test the special paste with operations such as ADD.
    
    testCopyPasteMatrixFormula belongs also to the copy/paste tests
    
    Change-Id: I2b142b3f95edbc740dd8c8a00de9a00bcf8a22d2
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/116743
    Tested-by: Jenkins
    Reviewed-by: Xisco Fauli <xiscofa...@libreoffice.org>

diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx
index d05656acca9e..9a7a3e34d623 100644
--- a/sc/qa/unit/ucalc.cxx
+++ b/sc/qa/unit/ucalc.cxx
@@ -178,10 +178,6 @@ public:
     void testFormulaPosition();
     void testFormulaWizardSubformula();
 
-    void testMixData();
-    void testMixDataAsLinkTdf116413();
-    void testMixDataWithFormulaTdf116413();
-
     /**
      * Make sure the sheet streams are invalidated properly.
      */
@@ -241,8 +237,6 @@ public:
     void testColumnFindEditCells();
     void testSetStringAndNote();
 
-    // tdf#80137
-    void testCopyPasteMatrixFormula();
     void testUndoDataAnchor();
     void testSetFormula();
     void testMultipleDataCellsInRange();
@@ -305,9 +299,6 @@ public:
     CPPUNIT_TEST(testSearchCells);
     CPPUNIT_TEST(testFormulaPosition);
     CPPUNIT_TEST(testFormulaWizardSubformula);
-    CPPUNIT_TEST(testMixData);
-    CPPUNIT_TEST(testMixDataAsLinkTdf116413);
-    CPPUNIT_TEST(testMixDataWithFormulaTdf116413);
     CPPUNIT_TEST(testJumpToPrecedentsDependents);
     CPPUNIT_TEST(testSetBackgroundColor);
     CPPUNIT_TEST(testRenameTable);
@@ -334,7 +325,6 @@ public:
     CPPUNIT_TEST(testFormulaToValue2);
     CPPUNIT_TEST(testColumnFindEditCells);
     CPPUNIT_TEST(testSetStringAndNote);
-    CPPUNIT_TEST(testCopyPasteMatrixFormula);
     CPPUNIT_TEST(testUndoDataAnchor);
     CPPUNIT_TEST(testSetFormula);
     CPPUNIT_TEST(testMultipleDataCellsInRange);
@@ -5908,419 +5898,6 @@ void Test::testMultipleDataCellsInRange()
     m_pDoc->DeleteTab(0);
 }
 
-void Test::testMixData()
-{
-    m_pDoc->InsertTab(0, "Test");
-
-    m_pDoc->SetValue(ScAddress(1,0,0), 2.0); // B1
-    m_pDoc->SetValue(ScAddress(0,1,0), 3.0); // A2
-
-    // Copy A1:B1 to the clip document.
-    ScDocument aClipDoc(SCDOCMODE_CLIP);
-    copyToClip(m_pDoc, ScRange(0,0,0,1,0,0), &aClipDoc); // A1:B1
-
-    // Copy A2:B2 to the mix document (for arithmetic paste).
-    ScDocument aMixDoc(SCDOCMODE_CLIP);
-    copyToClip(m_pDoc, ScRange(0,1,0,1,1,0), &aMixDoc); // A2:B2
-
-    // Paste A1:B1 to A2:B2 and perform addition.
-    pasteFromClip(m_pDoc, ScRange(0,1,0,1,1,0), &aClipDoc);
-    m_pDoc->MixDocument(ScRange(0,1,0,1,1,0), ScPasteFunc::ADD, false, 
aMixDoc);
-
-    CPPUNIT_ASSERT_EQUAL(3.0, m_pDoc->GetValue(0,1,0)); // A2
-    CPPUNIT_ASSERT_EQUAL(2.0, m_pDoc->GetValue(1,1,0)); // B2
-
-    // Clear everything and start over.
-    clearSheet(m_pDoc, 0);
-    clearSheet(&aClipDoc, 0);
-    clearSheet(&aMixDoc, 0);
-
-    // Set values to A1, A2, and B1.  B2 will remain empty.
-    m_pDoc->SetValue(ScAddress(0,0,0), 15.0);
-    m_pDoc->SetValue(ScAddress(0,1,0), 16.0);
-    m_pDoc->SetValue(ScAddress(1,0,0), 12.0);
-    CPPUNIT_ASSERT_EQUAL_MESSAGE("B2 should be empty.", CELLTYPE_NONE, 
m_pDoc->GetCellType(ScAddress(1,1,0)));
-
-    // Copy A1:A2 and paste it onto B1:B2 with subtraction operation.
-    copyToClip(m_pDoc, ScRange(0,0,0,0,1,0), &aClipDoc);
-    CPPUNIT_ASSERT_EQUAL(m_pDoc->GetValue(ScAddress(0,0,0)), 
aClipDoc.GetValue(ScAddress(0,0,0)));
-    CPPUNIT_ASSERT_EQUAL(m_pDoc->GetValue(ScAddress(0,1,0)), 
aClipDoc.GetValue(ScAddress(0,1,0)));
-
-    copyToClip(m_pDoc, ScRange(1,0,0,1,1,0), &aMixDoc);
-    CPPUNIT_ASSERT_EQUAL(m_pDoc->GetValue(ScAddress(1,0,0)), 
aMixDoc.GetValue(ScAddress(1,0,0)));
-    CPPUNIT_ASSERT_EQUAL(m_pDoc->GetValue(ScAddress(1,1,0)), 
aMixDoc.GetValue(ScAddress(1,1,0)));
-
-    pasteFromClip(m_pDoc, ScRange(1,0,0,1,1,0), &aClipDoc);
-    m_pDoc->MixDocument(ScRange(1,0,0,1,1,0), ScPasteFunc::SUB, false, 
aMixDoc);
-
-    CPPUNIT_ASSERT_EQUAL( -3.0, m_pDoc->GetValue(ScAddress(1,0,0))); // 12 - 15
-    CPPUNIT_ASSERT_EQUAL(-16.0, m_pDoc->GetValue(ScAddress(1,1,0))); //  0 - 16
-
-    m_pDoc->DeleteTab(0);
-}
-
-void Test::testMixDataAsLinkTdf116413()
-{
-    sc::AutoCalcSwitch aACSwitch(*m_pDoc, true); // turn on auto calculation.
-
-    const SCTAB nTab = 0;
-    m_pDoc->InsertTab(nTab, "Test");
-
-    // Scenario 1: Past "As Link" and "Add" operation (as described in 
tdf#116413)
-    m_pDoc->SetValue(0, 0, nTab, 1.0); // A1
-    m_pDoc->SetValue(0, 1, nTab, 1000.0); // A2
-
-    // Copy A1 to the clip document.
-    ScDocument aClipDoc(SCDOCMODE_CLIP);
-    copyToClip(m_pDoc, ScRange(0, 0, nTab, 0, 0, nTab), &aClipDoc); // A1
-
-    ScRange aDestRange(0, 1, nTab, 0, 1, nTab);
-    // Copy A2 to the mix document (for arithmetic paste).
-    ScDocument aMixDoc(SCDOCMODE_CLIP);
-    copyToClip(m_pDoc, aDestRange, &aMixDoc); // A2
-
-    // Paste A1 to A2 "As Link" and perform addition.
-    ScMarkData aMark(m_pDoc->GetSheetLimits());
-    aMark.SetMarkArea(aDestRange);
-    m_pDoc->CopyFromClip(aDestRange, aMark, InsertDeleteFlags::ALL, nullptr, 
&aClipDoc, true, true);
-
-    m_pDoc->MixDocument(aDestRange, ScPasteFunc::ADD, false, aMixDoc);
-
-    OUString aFormula;
-
-    // Test precondition
-    CPPUNIT_ASSERT_EQUAL(1001.0, m_pDoc->GetValue(0, 1, nTab)); // A2
-    m_pDoc->GetFormula(0, 1, nTab, aFormula);
-    CPPUNIT_ASSERT_EQUAL(OUString("=1000+($Test.$A$1)"), aFormula);
-
-    // Change A1 from 1.0 to 2.0 (auto calculation is triggered)
-    m_pDoc->SetValue(0, 0, nTab, 2.0); // A1
-
-    // Without the fix in place, this would have failed with
-    // - Expected: =1002
-    // - Actual  : =1001
-    CPPUNIT_ASSERT_EQUAL(1002.0, m_pDoc->GetValue(0, 1, nTab)); // A2
-    m_pDoc->GetFormula(0, 1, nTab, aFormula);
-    CPPUNIT_ASSERT_EQUAL(OUString("=1000+($Test.$A$1)"), aFormula);
-
-    // Clear everything and start over.
-    clearSheet(m_pDoc, nTab);
-    clearSheet(&aClipDoc, nTab);
-    clearSheet(&aMixDoc, nTab);
-
-    // Scenario 2: Like Scenario 1, but with a range (3 columns)
-    m_pDoc->InsertTab(nTab, "Test");
-
-    m_pDoc->SetValue(0, 0, nTab, 1.0); // A1
-    m_pDoc->SetValue(0, 1, nTab, 1000.0); // A2
-    m_pDoc->SetValue(1, 0, nTab, 1.0); // B1
-    m_pDoc->SetValue(1, 1, nTab, 1000.0); // B2
-    m_pDoc->SetValue(2, 0, nTab, 1.0); // C1
-    m_pDoc->SetValue(2, 1, nTab, 1000.0); // C2
-
-    // Copy A1:C1 to the clip document.
-    copyToClip(m_pDoc, ScRange(0, 0, nTab, 2, 0, nTab), &aClipDoc); // A1:C1
-
-    aDestRange = ScRange(0, 1, nTab, 2, 1, nTab);
-    // Copy A2:C2 to the mix document (for arithmetic paste).
-    copyToClip(m_pDoc, aDestRange, &aMixDoc); // A2:C2
-
-    // Paste A1:C1 to A2:C2 "As Link" and perform addition.
-    aMark = ScMarkData(m_pDoc->GetSheetLimits());
-    aMark.SetMarkArea(aDestRange);
-    m_pDoc->CopyFromClip(aDestRange, aMark, InsertDeleteFlags::ALL, nullptr, 
&aClipDoc, true, true);
-
-    m_pDoc->MixDocument(aDestRange, ScPasteFunc::ADD, false, aMixDoc);
-
-    // Test precondition
-    CPPUNIT_ASSERT_EQUAL(1001.0, m_pDoc->GetValue(0, 1, nTab)); // A2
-    m_pDoc->GetFormula(0, 1, nTab, aFormula);
-    CPPUNIT_ASSERT_EQUAL(OUString("=1000+($Test.$A$1)"), aFormula);
-
-    CPPUNIT_ASSERT_EQUAL(1001.0, m_pDoc->GetValue(1, 1, nTab)); // B2
-    m_pDoc->GetFormula(1, 1, nTab, aFormula);
-    CPPUNIT_ASSERT_EQUAL(OUString("=1000+($Test.$B$1)"), aFormula);
-
-    CPPUNIT_ASSERT_EQUAL(1001.0, m_pDoc->GetValue(2, 1, nTab)); // C2
-    m_pDoc->GetFormula(2, 1, nTab, aFormula);
-    CPPUNIT_ASSERT_EQUAL(OUString("=1000+($Test.$C$1)"), aFormula);
-
-    // Change A1:C1 from 1.0 to 2.0 (auto calculation is triggered)
-    m_pDoc->SetValue(0, 0, nTab, 2.0); // A1
-    m_pDoc->SetValue(1, 0, nTab, 2.0); // B1
-    m_pDoc->SetValue(2, 0, nTab, 2.0); // C1
-
-    // Without the fix in place, this would have failed with
-    // - Expected: =1002
-    // - Actual  : =1001
-    CPPUNIT_ASSERT_EQUAL(1002.0, m_pDoc->GetValue(0, 1, nTab)); // A2
-    m_pDoc->GetFormula(0, 1, nTab, aFormula);
-    CPPUNIT_ASSERT_EQUAL(OUString("=1000+($Test.$A$1)"), aFormula);
-
-    CPPUNIT_ASSERT_EQUAL(1002.0, m_pDoc->GetValue(1, 1, nTab)); // B2
-    m_pDoc->GetFormula(1, 1, nTab, aFormula);
-    CPPUNIT_ASSERT_EQUAL(OUString("=1000+($Test.$B$1)"), aFormula);
-
-    CPPUNIT_ASSERT_EQUAL(1002.0, m_pDoc->GetValue(2, 1, nTab)); // C2
-    m_pDoc->GetFormula(2, 1, nTab, aFormula);
-    CPPUNIT_ASSERT_EQUAL(OUString("=1000+($Test.$C$1)"), aFormula);
-
-    // Scenario 3: Like Scenario 2, but transposed
-    m_pDoc->InsertTab(nTab, "Test");
-
-    m_pDoc->SetValue(0, 0, nTab, 1.0); // A1
-    m_pDoc->SetValue(1, 0, nTab, 1000.0); // B1
-    m_pDoc->SetValue(0, 1, nTab, 1.0); // A2
-    m_pDoc->SetValue(1, 1, nTab, 1000.0); // B2
-    m_pDoc->SetValue(0, 2, nTab, 1.0); // A3
-    m_pDoc->SetValue(1, 2, nTab, 1000.0); // B3
-
-    // Copy A1:A3 to the clip document.
-    copyToClip(m_pDoc, ScRange(0, 0, nTab, 0, 2, nTab), &aClipDoc); // A1:A3
-
-    aDestRange = ScRange(1, 0, nTab, 1, 2, nTab);
-    // Copy B1:B3 to the mix document (for arithmetic paste).
-    copyToClip(m_pDoc, aDestRange, &aMixDoc); // B1:B3
-
-    // Paste A1:A3 to B1:B3 "As Link" and perform addition.
-    aMark = ScMarkData(m_pDoc->GetSheetLimits());
-    aMark.SetMarkArea(aDestRange);
-    m_pDoc->CopyFromClip(aDestRange, aMark, InsertDeleteFlags::ALL, nullptr, 
&aClipDoc, true, true);
-
-    m_pDoc->MixDocument(aDestRange, ScPasteFunc::ADD, false, aMixDoc);
-
-    // Test precondition
-    CPPUNIT_ASSERT_EQUAL(1001.0, m_pDoc->GetValue(1, 0, nTab)); // B1
-    m_pDoc->GetFormula(1, 0, nTab, aFormula);
-    CPPUNIT_ASSERT_EQUAL(OUString("=1000+($Test.$A$1)"), aFormula);
-
-    CPPUNIT_ASSERT_EQUAL(1001.0, m_pDoc->GetValue(1, 1, nTab)); // B2
-    m_pDoc->GetFormula(1, 1, nTab, aFormula);
-    CPPUNIT_ASSERT_EQUAL(OUString("=1000+($Test.$A$2)"), aFormula);
-
-    CPPUNIT_ASSERT_EQUAL(1001.0, m_pDoc->GetValue(1, 2, nTab)); // B3
-    m_pDoc->GetFormula(1, 2, nTab, aFormula);
-    CPPUNIT_ASSERT_EQUAL(OUString("=1000+($Test.$A$3)"), aFormula);
-
-    // Change A1:C1 from 1.0 to 2.0 (auto calculation is triggered)
-    m_pDoc->SetValue(0, 0, nTab, 2.0); // A1
-    m_pDoc->SetValue(0, 1, nTab, 2.0); // A2
-    m_pDoc->SetValue(0, 2, nTab, 2.0); // A3
-
-    // Without the fix in place, this would have failed with
-    // - Expected: =1002
-    // - Actual  : =1001
-    CPPUNIT_ASSERT_EQUAL(1002.0, m_pDoc->GetValue(1, 0, nTab)); // B1
-    m_pDoc->GetFormula(1, 0, nTab, aFormula);
-    CPPUNIT_ASSERT_EQUAL(OUString("=1000+($Test.$A$1)"), aFormula);
-
-    CPPUNIT_ASSERT_EQUAL(1002.0, m_pDoc->GetValue(1, 1, nTab)); // B2
-    m_pDoc->GetFormula(1, 1, nTab, aFormula);
-    CPPUNIT_ASSERT_EQUAL(OUString("=1000+($Test.$A$2)"), aFormula);
-
-    CPPUNIT_ASSERT_EQUAL(1002.0, m_pDoc->GetValue(1, 2, nTab)); // B3
-    m_pDoc->GetFormula(1, 2, nTab, aFormula);
-    CPPUNIT_ASSERT_EQUAL(OUString("=1000+($Test.$A$3)"), aFormula);
-
-    m_pDoc->DeleteTab(nTab);
-}
-
-void Test::testMixDataWithFormulaTdf116413()
-{
-    sc::AutoCalcSwitch aACSwitch(*m_pDoc, true); // turn on auto calculation.
-
-    const SCTAB nTab = 0;
-    m_pDoc->InsertTab(nTab, "Test");
-
-    // Scenario 1: There is already a reference in destination cell
-    m_pDoc->InsertTab(nTab, "Test");
-
-    m_pDoc->SetValue(0, 0, nTab, 100.0); // A1
-    m_pDoc->SetValue(0, 1, nTab, 1.0); // A2
-    m_pDoc->SetString(0, 2, nTab, "=A2"); // A3
-
-    // Copy A1 to the clip document.
-    ScDocument aClipDoc(SCDOCMODE_CLIP);
-    copyToClip(m_pDoc, ScRange(0, 0, nTab, 0, 0, nTab), &aClipDoc); // A1
-
-    ScRange aDestRange(0, 2, nTab, 0, 2, nTab);
-    ScDocument aMixDoc(SCDOCMODE_CLIP);
-    // Copy A3 to the mix document (for arithmetic paste).
-    copyToClip(m_pDoc, aDestRange, &aMixDoc); // A3
-
-    // Paste A1 to A3 and perform addition.
-    pasteFromClip(m_pDoc, aDestRange, &aClipDoc);
-    m_pDoc->MixDocument(aDestRange, ScPasteFunc::ADD, false, aMixDoc);
-
-    OUString aFormula;
-
-    // Test precondition
-    CPPUNIT_ASSERT_EQUAL(101.0, m_pDoc->GetValue(0, 2, nTab)); // A3
-    m_pDoc->GetFormula(0, 2, nTab, aFormula);
-    CPPUNIT_ASSERT_EQUAL(OUString("=(A2)+100"), aFormula);
-
-    // Change A2 from 1.0 to 2.0 (auto calculation is triggered)
-    m_pDoc->SetValue(0, 1, nTab, 2.0); // A2
-
-    // Without the fix in place, this would have failed with
-    // - Expected: =102
-    // - Actual  : =101
-    CPPUNIT_ASSERT_EQUAL(102.0, m_pDoc->GetValue(0, 2, nTab)); // A3
-    m_pDoc->GetFormula(0, 2, nTab, aFormula);
-    CPPUNIT_ASSERT_EQUAL(OUString("=(A2)+100"), aFormula);
-
-    // Clear everything and start over.
-    clearSheet(m_pDoc, nTab);
-    clearSheet(&aClipDoc, nTab);
-    clearSheet(&aMixDoc, nTab);
-
-    // Scenario 2: Similar to scenario 1, but a range of 4 cells and 2 of them 
have references
-    m_pDoc->InsertTab(nTab, "Test");
-
-    m_pDoc->SetValue(0, 0, nTab, 100.0); // A1
-    m_pDoc->SetValue(0, 1, nTab, 1.0); // A2
-    m_pDoc->SetValue(0, 2, nTab, 1000.0); // A3
-
-    m_pDoc->SetValue(1, 0, nTab, 100.0); // B1
-    m_pDoc->SetValue(1, 1, nTab, 1.0); // B2
-    m_pDoc->SetString(1, 2, nTab, "=B2"); // B3
-
-    m_pDoc->SetValue(2, 0, nTab, 100.0); // C1
-    m_pDoc->SetValue(2, 1, nTab, 1.0); // C2
-    m_pDoc->SetString(2, 2, nTab, "=C2"); // C3
-
-    m_pDoc->SetValue(3, 0, nTab, 100.0); // D1
-    m_pDoc->SetValue(3, 1, nTab, 1.0); // D2
-    m_pDoc->SetValue(3, 2, nTab, 1000.0); // D3
-
-    // Copy A1:D1 to the clip document.
-    copyToClip(m_pDoc, ScRange(0, 0, nTab, 3, 0, nTab), &aClipDoc); // A1:D1
-
-    aDestRange = ScRange(0, 2, nTab, 3, 2, nTab);
-    // Copy A3:D3 to the mix document (for arithmetic paste).
-    copyToClip(m_pDoc, aDestRange, &aMixDoc); // A3:D3
-
-    // Paste A1:D1 to A3:D3 and perform addition.
-    pasteFromClip(m_pDoc, aDestRange, &aClipDoc);
-    m_pDoc->MixDocument(aDestRange, ScPasteFunc::ADD, false, aMixDoc);
-
-    // Test precondition
-    CPPUNIT_ASSERT_EQUAL(1100.0, m_pDoc->GetValue(0, 2, nTab)); // A3
-    m_pDoc->GetFormula(0, 2, nTab, aFormula);
-    CPPUNIT_ASSERT_EQUAL(EMPTY_OUSTRING, aFormula);
-
-    CPPUNIT_ASSERT_EQUAL(101.0, m_pDoc->GetValue(1, 2, nTab)); // B3
-    m_pDoc->GetFormula(1, 2, nTab, aFormula);
-    CPPUNIT_ASSERT_EQUAL(OUString("=(B2)+100"), aFormula);
-
-    CPPUNIT_ASSERT_EQUAL(101.0, m_pDoc->GetValue(2, 2, nTab)); // C3
-    m_pDoc->GetFormula(2, 2, nTab, aFormula);
-    CPPUNIT_ASSERT_EQUAL(OUString("=(C2)+100"), aFormula);
-
-    CPPUNIT_ASSERT_EQUAL(1100.0, m_pDoc->GetValue(3, 2, nTab)); // D3
-    m_pDoc->GetFormula(3, 2, nTab, aFormula);
-    CPPUNIT_ASSERT_EQUAL(EMPTY_OUSTRING, aFormula);
-
-    // Change A2:D2 from 1.0 to 2.0 (auto calculation is triggered)
-    m_pDoc->SetValue(0, 1, nTab, 2.0); // A2
-    m_pDoc->SetValue(1, 1, nTab, 2.0); // B2
-    m_pDoc->SetValue(2, 1, nTab, 2.0); // C2
-    m_pDoc->SetValue(3, 1, nTab, 2.0); // D2
-
-    CPPUNIT_ASSERT_EQUAL(1100.0, m_pDoc->GetValue(0, 2, nTab)); // A3
-    m_pDoc->GetFormula(0, 2, nTab, aFormula);
-    CPPUNIT_ASSERT_EQUAL(EMPTY_OUSTRING, aFormula);
-
-    // Without the fix in place, this would have failed with
-    // - Expected: =102
-    // - Actual  : =101
-    CPPUNIT_ASSERT_EQUAL(102.0, m_pDoc->GetValue(1, 2, nTab)); // B3
-    m_pDoc->GetFormula(1, 2, nTab, aFormula);
-    CPPUNIT_ASSERT_EQUAL(OUString("=(B2)+100"), aFormula);
-
-    CPPUNIT_ASSERT_EQUAL(102.0, m_pDoc->GetValue(2, 2, nTab)); // C3
-    m_pDoc->GetFormula(2, 2, nTab, aFormula);
-    CPPUNIT_ASSERT_EQUAL(OUString("=(C2)+100"), aFormula);
-
-    CPPUNIT_ASSERT_EQUAL(1100.0, m_pDoc->GetValue(3, 2, nTab)); // D3
-    m_pDoc->GetFormula(3, 2, nTab, aFormula);
-    CPPUNIT_ASSERT_EQUAL(EMPTY_OUSTRING, aFormula);
-
-    // Scenario 3: Similar to scenario 2, but transposed
-    m_pDoc->InsertTab(nTab, "Test");
-
-    m_pDoc->SetValue(0, 0, nTab, 100.0); // A1
-    m_pDoc->SetValue(1, 0, nTab, 1.0); // B1
-    m_pDoc->SetValue(2, 0, nTab, 1000.0); // C1
-
-    m_pDoc->SetValue( 0, 1, nTab, 100.0); // A2
-    m_pDoc->SetValue( 1, 1, nTab, 1.0); // B2
-    m_pDoc->SetString(2, 1, nTab, "=B2"); // C2
-
-    m_pDoc->SetValue( 0, 2, nTab, 100.0); // A3
-    m_pDoc->SetValue( 1, 2, nTab, 1.0); // B3
-    m_pDoc->SetString(2, 2, nTab, "=B3"); // C3
-
-    m_pDoc->SetValue(0, 3, nTab, 100.0); // A4
-    m_pDoc->SetValue(1, 3, nTab, 1.0); // B4
-    m_pDoc->SetValue(2, 3, nTab, 1000.0); // C4
-
-    // Copy A1:A4 to the clip document.
-    copyToClip(m_pDoc, ScRange(0, 0, nTab, 0, 3, nTab), &aClipDoc); // A1:A4
-
-    aDestRange = ScRange(2, 0, nTab, 2, 3, nTab);
-    // Copy C1:C4 to the mix document (for arithmetic paste).
-    copyToClip(m_pDoc, aDestRange, &aMixDoc); // C1:C4
-
-    // Paste A1:A4 to C1:C4 and perform addition.
-    pasteFromClip(m_pDoc, aDestRange, &aClipDoc);
-    m_pDoc->MixDocument(aDestRange, ScPasteFunc::ADD, false, aMixDoc);
-
-    // Test precondition
-    CPPUNIT_ASSERT_EQUAL(1100.0, m_pDoc->GetValue(2, 0, nTab)); // C1
-    m_pDoc->GetFormula(2, 0, nTab, aFormula);
-    CPPUNIT_ASSERT_EQUAL(EMPTY_OUSTRING, aFormula);
-
-    CPPUNIT_ASSERT_EQUAL(101.0, m_pDoc->GetValue(2, 1, nTab)); // C2
-    m_pDoc->GetFormula(2, 1, nTab, aFormula);
-    CPPUNIT_ASSERT_EQUAL(OUString("=(B2)+100"), aFormula);
-
-    CPPUNIT_ASSERT_EQUAL(101.0, m_pDoc->GetValue(2, 2, nTab)); // C3
-    m_pDoc->GetFormula(2, 2, nTab, aFormula);
-    CPPUNIT_ASSERT_EQUAL(OUString("=(B3)+100"), aFormula);
-
-    CPPUNIT_ASSERT_EQUAL(1100.0, m_pDoc->GetValue(2, 3, nTab)); // C4
-    m_pDoc->GetFormula(2, 3, nTab, aFormula);
-    CPPUNIT_ASSERT_EQUAL(EMPTY_OUSTRING, aFormula);
-
-    // Change B1:B4 from 1.0 to 2.0 (auto calculation is triggered)
-    m_pDoc->SetValue(1, 0, nTab, 2.0); // B1
-    m_pDoc->SetValue(1, 1, nTab, 2.0); // B2
-    m_pDoc->SetValue(1, 2, nTab, 2.0); // B3
-    m_pDoc->SetValue(1, 3, nTab, 2.0); // B4
-
-    CPPUNIT_ASSERT_EQUAL(1100.0, m_pDoc->GetValue(2, 0, nTab)); // C1
-    m_pDoc->GetFormula(2, 0, nTab, aFormula);
-    CPPUNIT_ASSERT_EQUAL(EMPTY_OUSTRING, aFormula);
-
-    // Without the fix in place, this would have failed with
-    // - Expected: =102
-    // - Actual  : =101
-    CPPUNIT_ASSERT_EQUAL(102.0, m_pDoc->GetValue(2, 1, nTab)); // C2
-    m_pDoc->GetFormula(2, 1, nTab, aFormula);
-    CPPUNIT_ASSERT_EQUAL(OUString("=(B2)+100"), aFormula);
-
-    CPPUNIT_ASSERT_EQUAL(102.0, m_pDoc->GetValue(2, 2, nTab)); // C3
-    m_pDoc->GetFormula(2, 2, nTab, aFormula);
-    CPPUNIT_ASSERT_EQUAL(OUString("=(B3)+100"), aFormula);
-
-    CPPUNIT_ASSERT_EQUAL(1100.0, m_pDoc->GetValue(2, 3, nTab)); // C4
-    m_pDoc->GetFormula(2, 3, nTab, aFormula);
-    CPPUNIT_ASSERT_EQUAL(EMPTY_OUSTRING, aFormula);
-
-    m_pDoc->DeleteTab(nTab);
-}
-
 void Test::testFormulaWizardSubformula()
 {
     m_pDoc->InsertTab(0, "Test");
@@ -6365,73 +5942,6 @@ void Test::testSetStringAndNote()
     m_pDoc->DeleteTab(0);
 }
 
-void Test::testCopyPasteMatrixFormula()
-{
-    m_pDoc->InsertTab(0, "hcv");
-
-    // Set Values to B1, C1, D1
-    m_pDoc->SetValue(ScAddress(1,0,0), 2.0);    // B1
-    m_pDoc->SetValue(ScAddress(2,0,0), 5.0);    // C1
-    m_pDoc->SetValue(ScAddress(3,0,0), 3.0);    // D1
-
-    // Set Values to B2, C2
-    m_pDoc->SetString(ScAddress(1,1,0), "B2");  // B2
-    //m_pDoc->SetString(ScAddress(2,1,0), "C2");  // C2
-    m_pDoc->SetString(ScAddress(3,1,0), "D2");  // D2
-
-    // Set Values to D3
-    //m_pDoc->SetValue(ScAddress(1,2,0), 9.0);    // B3
-    //m_pDoc->SetString(ScAddress(2,2,0), "C3");  // C3
-    m_pDoc->SetValue(ScAddress(3,2,0), 11.0);   // D3
-
-    // Insert matrix formula to A1
-    ScMarkData aMark(m_pDoc->GetSheetLimits());
-    aMark.SelectOneTable(0);
-    m_pDoc->InsertMatrixFormula(0, 0, 0, 0, aMark, 
"=COUNTIF(ISBLANK(B1:D1);TRUE())");
-    m_pDoc->CalcAll();
-    // A1 should contain 0
-    CPPUNIT_ASSERT_EQUAL( 0.0, m_pDoc->GetValue(ScAddress(0,0,0)) ); // A1
-
-    // Copy cell A1 to clipboard.
-    ScAddress aPos(0,0,0);  // A1
-    ScDocument aClipDoc(SCDOCMODE_CLIP);
-    ScClipParam aParam(aPos, false);
-    m_pDoc->CopyToClip(aParam, &aClipDoc, &aMark, false, false);
-    // Formula string should be equal.
-    CPPUNIT_ASSERT_EQUAL(m_pDoc->GetString(aPos), aClipDoc.GetString(aPos));
-
-    // First try single range.
-    // Paste matrix formula to A2
-    pasteFromClip(m_pDoc, ScRange(0,1,0,0,1,0), &aClipDoc); // A2
-    // A2 Cell value should contain 1.0
-    CPPUNIT_ASSERT_EQUAL( 1.0, m_pDoc->GetValue(ScAddress(0,1,0)));
-
-    // Paste matrix formula to A3
-    pasteFromClip(m_pDoc, ScRange(0,2,0,0,2,0), &aClipDoc); // A3
-    // A3 Cell value should contain 2.0
-    CPPUNIT_ASSERT_EQUAL( 2.0, m_pDoc->GetValue(ScAddress(0,2,0)));
-
-    // Paste matrix formula to A4
-    pasteFromClip(m_pDoc, ScRange(0,3,0,0,3,0), &aClipDoc); // A4
-    // A4 Cell value should contain 3.0
-    CPPUNIT_ASSERT_EQUAL( 3.0, m_pDoc->GetValue(ScAddress(0,3,0)));
-
-    // Clear cell A2:A4
-    clearRange(m_pDoc, ScRange(0,1,0,0,3,0));
-
-    // Paste matrix formula to range A2:A4
-    pasteFromClip(m_pDoc, ScRange(0,1,0,0,3,0), &aClipDoc); // A2:A4
-
-    // A2 Cell value should contain 1.0
-    CPPUNIT_ASSERT_EQUAL( 1.0, m_pDoc->GetValue(ScAddress(0,1,0)));
-    // A3 Cell value should contain 2.0
-    CPPUNIT_ASSERT_EQUAL( 2.0, m_pDoc->GetValue(ScAddress(0,2,0)));
-    // A4 Cell value should contain 3.0
-    CPPUNIT_ASSERT_EQUAL( 3.0, m_pDoc->GetValue(ScAddress(0,3,0)));
-
-    m_pDoc->DeleteTab(0);
-}
-
 void Test::testUndoDataAnchor()
 {
     m_pDoc->InsertTab(0, "Tab1");
diff --git a/sc/qa/unit/ucalc_copypaste.cxx b/sc/qa/unit/ucalc_copypaste.cxx
index b9ec61590a01..6e2d37759511 100644
--- a/sc/qa/unit/ucalc_copypaste.cxx
+++ b/sc/qa/unit/ucalc_copypaste.cxx
@@ -138,6 +138,13 @@ public:
     void testReferencedCutTransposedRangesColTab1To3();
     void testReferencedCutTransposedRangesColTab3To1();
 
+    void testMixData();
+    void testMixDataAsLinkTdf116413();
+    void testMixDataWithFormulaTdf116413();
+
+    // tdf#80137
+    void testCopyPasteMatrixFormula();
+
     CPPUNIT_TEST_SUITE(TestCopyPaste);
 
     CPPUNIT_TEST(testCopyPaste);
@@ -235,6 +242,12 @@ public:
     CPPUNIT_TEST(testReferencedCutTransposedRangesColTab1To3);
     CPPUNIT_TEST(testReferencedCutTransposedRangesColTab3To1);
 
+    CPPUNIT_TEST(testMixData);
+    CPPUNIT_TEST(testMixDataAsLinkTdf116413);
+    CPPUNIT_TEST(testMixDataWithFormulaTdf116413);
+
+    CPPUNIT_TEST(testCopyPasteMatrixFormula);
+
     CPPUNIT_TEST_SUITE_END();
 
 private:
@@ -11169,6 +11182,491 @@ void TestCopyPaste::testTdf71058()
     CPPUNIT_ASSERT_EQUAL(2.0, m_pDoc->GetValue(3, 2, nTab));
 }
 
+void TestCopyPaste::testMixData()
+{
+    m_pDoc->InsertTab(0, "Test");
+
+    m_pDoc->SetValue(ScAddress(1, 0, 0), 2.0); // B1
+    m_pDoc->SetValue(ScAddress(0, 1, 0), 3.0); // A2
+
+    // Copy A1:B1 to the clip document.
+    ScDocument aClipDoc(SCDOCMODE_CLIP);
+    copyToClip(m_pDoc, ScRange(0, 0, 0, 1, 0, 0), &aClipDoc); // A1:B1
+
+    // Copy A2:B2 to the mix document (for arithmetic paste).
+    ScDocument aMixDoc(SCDOCMODE_CLIP);
+    copyToClip(m_pDoc, ScRange(0, 1, 0, 1, 1, 0), &aMixDoc); // A2:B2
+
+    // Paste A1:B1 to A2:B2 and perform addition.
+    pasteFromClip(m_pDoc, ScRange(0, 1, 0, 1, 1, 0), &aClipDoc);
+    m_pDoc->MixDocument(ScRange(0, 1, 0, 1, 1, 0), ScPasteFunc::ADD, false, 
aMixDoc);
+
+    CPPUNIT_ASSERT_EQUAL(3.0, m_pDoc->GetValue(0, 1, 0)); // A2
+    CPPUNIT_ASSERT_EQUAL(2.0, m_pDoc->GetValue(1, 1, 0)); // B2
+
+    // Clear everything and start over.
+    clearSheet(m_pDoc, 0);
+    clearSheet(&aClipDoc, 0);
+    clearSheet(&aMixDoc, 0);
+
+    // Set values to A1, A2, and B1.  B2 will remain empty.
+    m_pDoc->SetValue(ScAddress(0, 0, 0), 15.0);
+    m_pDoc->SetValue(ScAddress(0, 1, 0), 16.0);
+    m_pDoc->SetValue(ScAddress(1, 0, 0), 12.0);
+    CPPUNIT_ASSERT_EQUAL_MESSAGE("B2 should be empty.", CELLTYPE_NONE,
+                                 m_pDoc->GetCellType(ScAddress(1, 1, 0)));
+
+    // Copy A1:A2 and paste it onto B1:B2 with subtraction operation.
+    copyToClip(m_pDoc, ScRange(0, 0, 0, 0, 1, 0), &aClipDoc);
+    CPPUNIT_ASSERT_EQUAL(m_pDoc->GetValue(ScAddress(0, 0, 0)),
+                         aClipDoc.GetValue(ScAddress(0, 0, 0)));
+    CPPUNIT_ASSERT_EQUAL(m_pDoc->GetValue(ScAddress(0, 1, 0)),
+                         aClipDoc.GetValue(ScAddress(0, 1, 0)));
+
+    copyToClip(m_pDoc, ScRange(1, 0, 0, 1, 1, 0), &aMixDoc);
+    CPPUNIT_ASSERT_EQUAL(m_pDoc->GetValue(ScAddress(1, 0, 0)),
+                         aMixDoc.GetValue(ScAddress(1, 0, 0)));
+    CPPUNIT_ASSERT_EQUAL(m_pDoc->GetValue(ScAddress(1, 1, 0)),
+                         aMixDoc.GetValue(ScAddress(1, 1, 0)));
+
+    pasteFromClip(m_pDoc, ScRange(1, 0, 0, 1, 1, 0), &aClipDoc);
+    m_pDoc->MixDocument(ScRange(1, 0, 0, 1, 1, 0), ScPasteFunc::SUB, false, 
aMixDoc);
+
+    CPPUNIT_ASSERT_EQUAL(-3.0, m_pDoc->GetValue(ScAddress(1, 0, 0))); // 12 - 
15
+    CPPUNIT_ASSERT_EQUAL(-16.0, m_pDoc->GetValue(ScAddress(1, 1, 0))); //  0 - 
16
+
+    m_pDoc->DeleteTab(0);
+}
+
+void TestCopyPaste::testMixDataAsLinkTdf116413()
+{
+    sc::AutoCalcSwitch aACSwitch(*m_pDoc, true); // turn on auto calculation.
+
+    const SCTAB nTab = 0;
+    m_pDoc->InsertTab(nTab, "Test");
+
+    // Scenario 1: Past "As Link" and "Add" operation (as described in 
tdf#116413)
+    m_pDoc->SetValue(0, 0, nTab, 1.0); // A1
+    m_pDoc->SetValue(0, 1, nTab, 1000.0); // A2
+
+    // Copy A1 to the clip document.
+    ScDocument aClipDoc(SCDOCMODE_CLIP);
+    copyToClip(m_pDoc, ScRange(0, 0, nTab, 0, 0, nTab), &aClipDoc); // A1
+
+    ScRange aDestRange(0, 1, nTab, 0, 1, nTab);
+    // Copy A2 to the mix document (for arithmetic paste).
+    ScDocument aMixDoc(SCDOCMODE_CLIP);
+    copyToClip(m_pDoc, aDestRange, &aMixDoc); // A2
+
+    // Paste A1 to A2 "As Link" and perform addition.
+    ScMarkData aMark(m_pDoc->GetSheetLimits());
+    aMark.SetMarkArea(aDestRange);
+    m_pDoc->CopyFromClip(aDestRange, aMark, InsertDeleteFlags::ALL, nullptr, 
&aClipDoc, true, true);
+
+    m_pDoc->MixDocument(aDestRange, ScPasteFunc::ADD, false, aMixDoc);
+
+    OUString aFormula;
+
+    // Test precondition
+    CPPUNIT_ASSERT_EQUAL(1001.0, m_pDoc->GetValue(0, 1, nTab)); // A2
+    m_pDoc->GetFormula(0, 1, nTab, aFormula);
+    CPPUNIT_ASSERT_EQUAL(OUString("=1000+($Test.$A$1)"), aFormula);
+
+    // Change A1 from 1.0 to 2.0 (auto calculation is triggered)
+    m_pDoc->SetValue(0, 0, nTab, 2.0); // A1
+
+    // Without the fix in place, this would have failed with
+    // - Expected: =1002
+    // - Actual  : =1001
+    CPPUNIT_ASSERT_EQUAL(1002.0, m_pDoc->GetValue(0, 1, nTab)); // A2
+    m_pDoc->GetFormula(0, 1, nTab, aFormula);
+    CPPUNIT_ASSERT_EQUAL(OUString("=1000+($Test.$A$1)"), aFormula);
+
+    // Clear everything and start over.
+    clearSheet(m_pDoc, nTab);
+    clearSheet(&aClipDoc, nTab);
+    clearSheet(&aMixDoc, nTab);
+
+    // Scenario 2: Like Scenario 1, but with a range (3 columns)
+    m_pDoc->InsertTab(nTab, "Test");
+
+    m_pDoc->SetValue(0, 0, nTab, 1.0); // A1
+    m_pDoc->SetValue(0, 1, nTab, 1000.0); // A2
+    m_pDoc->SetValue(1, 0, nTab, 1.0); // B1
+    m_pDoc->SetValue(1, 1, nTab, 1000.0); // B2
+    m_pDoc->SetValue(2, 0, nTab, 1.0); // C1
+    m_pDoc->SetValue(2, 1, nTab, 1000.0); // C2
+
+    // Copy A1:C1 to the clip document.
+    copyToClip(m_pDoc, ScRange(0, 0, nTab, 2, 0, nTab), &aClipDoc); // A1:C1
+
+    aDestRange = ScRange(0, 1, nTab, 2, 1, nTab);
+    // Copy A2:C2 to the mix document (for arithmetic paste).
+    copyToClip(m_pDoc, aDestRange, &aMixDoc); // A2:C2
+
+    // Paste A1:C1 to A2:C2 "As Link" and perform addition.
+    aMark = ScMarkData(m_pDoc->GetSheetLimits());
+    aMark.SetMarkArea(aDestRange);
+    m_pDoc->CopyFromClip(aDestRange, aMark, InsertDeleteFlags::ALL, nullptr, 
&aClipDoc, true, true);
+
+    m_pDoc->MixDocument(aDestRange, ScPasteFunc::ADD, false, aMixDoc);
+
+    // Test precondition
+    CPPUNIT_ASSERT_EQUAL(1001.0, m_pDoc->GetValue(0, 1, nTab)); // A2
+    m_pDoc->GetFormula(0, 1, nTab, aFormula);
+    CPPUNIT_ASSERT_EQUAL(OUString("=1000+($Test.$A$1)"), aFormula);
+
+    CPPUNIT_ASSERT_EQUAL(1001.0, m_pDoc->GetValue(1, 1, nTab)); // B2
+    m_pDoc->GetFormula(1, 1, nTab, aFormula);
+    CPPUNIT_ASSERT_EQUAL(OUString("=1000+($Test.$B$1)"), aFormula);
+
+    CPPUNIT_ASSERT_EQUAL(1001.0, m_pDoc->GetValue(2, 1, nTab)); // C2
+    m_pDoc->GetFormula(2, 1, nTab, aFormula);
+    CPPUNIT_ASSERT_EQUAL(OUString("=1000+($Test.$C$1)"), aFormula);
+
+    // Change A1:C1 from 1.0 to 2.0 (auto calculation is triggered)
+    m_pDoc->SetValue(0, 0, nTab, 2.0); // A1
+    m_pDoc->SetValue(1, 0, nTab, 2.0); // B1
+    m_pDoc->SetValue(2, 0, nTab, 2.0); // C1
+
+    // Without the fix in place, this would have failed with
+    // - Expected: =1002
+    // - Actual  : =1001
+    CPPUNIT_ASSERT_EQUAL(1002.0, m_pDoc->GetValue(0, 1, nTab)); // A2
+    m_pDoc->GetFormula(0, 1, nTab, aFormula);
+    CPPUNIT_ASSERT_EQUAL(OUString("=1000+($Test.$A$1)"), aFormula);
+
+    CPPUNIT_ASSERT_EQUAL(1002.0, m_pDoc->GetValue(1, 1, nTab)); // B2
+    m_pDoc->GetFormula(1, 1, nTab, aFormula);
+    CPPUNIT_ASSERT_EQUAL(OUString("=1000+($Test.$B$1)"), aFormula);
+
+    CPPUNIT_ASSERT_EQUAL(1002.0, m_pDoc->GetValue(2, 1, nTab)); // C2
+    m_pDoc->GetFormula(2, 1, nTab, aFormula);
+    CPPUNIT_ASSERT_EQUAL(OUString("=1000+($Test.$C$1)"), aFormula);
+
+    // Scenario 3: Like Scenario 2, but transposed
+    m_pDoc->InsertTab(nTab, "Test");
+
+    m_pDoc->SetValue(0, 0, nTab, 1.0); // A1
+    m_pDoc->SetValue(1, 0, nTab, 1000.0); // B1
+    m_pDoc->SetValue(0, 1, nTab, 1.0); // A2
+    m_pDoc->SetValue(1, 1, nTab, 1000.0); // B2
+    m_pDoc->SetValue(0, 2, nTab, 1.0); // A3
+    m_pDoc->SetValue(1, 2, nTab, 1000.0); // B3
+
+    // Copy A1:A3 to the clip document.
+    copyToClip(m_pDoc, ScRange(0, 0, nTab, 0, 2, nTab), &aClipDoc); // A1:A3
+
+    aDestRange = ScRange(1, 0, nTab, 1, 2, nTab);
+    // Copy B1:B3 to the mix document (for arithmetic paste).
+    copyToClip(m_pDoc, aDestRange, &aMixDoc); // B1:B3
+
+    // Paste A1:A3 to B1:B3 "As Link" and perform addition.
+    aMark = ScMarkData(m_pDoc->GetSheetLimits());
+    aMark.SetMarkArea(aDestRange);
+    m_pDoc->CopyFromClip(aDestRange, aMark, InsertDeleteFlags::ALL, nullptr, 
&aClipDoc, true, true);
+
+    m_pDoc->MixDocument(aDestRange, ScPasteFunc::ADD, false, aMixDoc);
+
+    // Test precondition
+    CPPUNIT_ASSERT_EQUAL(1001.0, m_pDoc->GetValue(1, 0, nTab)); // B1
+    m_pDoc->GetFormula(1, 0, nTab, aFormula);
+    CPPUNIT_ASSERT_EQUAL(OUString("=1000+($Test.$A$1)"), aFormula);
+
+    CPPUNIT_ASSERT_EQUAL(1001.0, m_pDoc->GetValue(1, 1, nTab)); // B2
+    m_pDoc->GetFormula(1, 1, nTab, aFormula);
+    CPPUNIT_ASSERT_EQUAL(OUString("=1000+($Test.$A$2)"), aFormula);
+
+    CPPUNIT_ASSERT_EQUAL(1001.0, m_pDoc->GetValue(1, 2, nTab)); // B3
+    m_pDoc->GetFormula(1, 2, nTab, aFormula);
+    CPPUNIT_ASSERT_EQUAL(OUString("=1000+($Test.$A$3)"), aFormula);
+
+    // Change A1:C1 from 1.0 to 2.0 (auto calculation is triggered)
+    m_pDoc->SetValue(0, 0, nTab, 2.0); // A1
+    m_pDoc->SetValue(0, 1, nTab, 2.0); // A2
+    m_pDoc->SetValue(0, 2, nTab, 2.0); // A3
+
+    // Without the fix in place, this would have failed with
+    // - Expected: =1002
+    // - Actual  : =1001
+    CPPUNIT_ASSERT_EQUAL(1002.0, m_pDoc->GetValue(1, 0, nTab)); // B1
+    m_pDoc->GetFormula(1, 0, nTab, aFormula);
+    CPPUNIT_ASSERT_EQUAL(OUString("=1000+($Test.$A$1)"), aFormula);
+
+    CPPUNIT_ASSERT_EQUAL(1002.0, m_pDoc->GetValue(1, 1, nTab)); // B2
+    m_pDoc->GetFormula(1, 1, nTab, aFormula);
+    CPPUNIT_ASSERT_EQUAL(OUString("=1000+($Test.$A$2)"), aFormula);
+
+    CPPUNIT_ASSERT_EQUAL(1002.0, m_pDoc->GetValue(1, 2, nTab)); // B3
+    m_pDoc->GetFormula(1, 2, nTab, aFormula);
+    CPPUNIT_ASSERT_EQUAL(OUString("=1000+($Test.$A$3)"), aFormula);
+
+    m_pDoc->DeleteTab(nTab);
+}
+
+void TestCopyPaste::testMixDataWithFormulaTdf116413()
+{
+    sc::AutoCalcSwitch aACSwitch(*m_pDoc, true); // turn on auto calculation.
+
+    const SCTAB nTab = 0;
+    m_pDoc->InsertTab(nTab, "Test");
+
+    // Scenario 1: There is already a reference in destination cell
+    m_pDoc->InsertTab(nTab, "Test");
+
+    m_pDoc->SetValue(0, 0, nTab, 100.0); // A1
+    m_pDoc->SetValue(0, 1, nTab, 1.0); // A2
+    m_pDoc->SetString(0, 2, nTab, "=A2"); // A3
+
+    // Copy A1 to the clip document.
+    ScDocument aClipDoc(SCDOCMODE_CLIP);
+    copyToClip(m_pDoc, ScRange(0, 0, nTab, 0, 0, nTab), &aClipDoc); // A1
+
+    ScRange aDestRange(0, 2, nTab, 0, 2, nTab);
+    ScDocument aMixDoc(SCDOCMODE_CLIP);
+    // Copy A3 to the mix document (for arithmetic paste).
+    copyToClip(m_pDoc, aDestRange, &aMixDoc); // A3
+
+    // Paste A1 to A3 and perform addition.
+    pasteFromClip(m_pDoc, aDestRange, &aClipDoc);
+    m_pDoc->MixDocument(aDestRange, ScPasteFunc::ADD, false, aMixDoc);
+
+    OUString aFormula;
+
+    // Test precondition
+    CPPUNIT_ASSERT_EQUAL(101.0, m_pDoc->GetValue(0, 2, nTab)); // A3
+    m_pDoc->GetFormula(0, 2, nTab, aFormula);
+    CPPUNIT_ASSERT_EQUAL(OUString("=(A2)+100"), aFormula);
+
+    // Change A2 from 1.0 to 2.0 (auto calculation is triggered)
+    m_pDoc->SetValue(0, 1, nTab, 2.0); // A2
+
+    // Without the fix in place, this would have failed with
+    // - Expected: =102
+    // - Actual  : =101
+    CPPUNIT_ASSERT_EQUAL(102.0, m_pDoc->GetValue(0, 2, nTab)); // A3
+    m_pDoc->GetFormula(0, 2, nTab, aFormula);
+    CPPUNIT_ASSERT_EQUAL(OUString("=(A2)+100"), aFormula);
+
+    // Clear everything and start over.
+    clearSheet(m_pDoc, nTab);
+    clearSheet(&aClipDoc, nTab);
+    clearSheet(&aMixDoc, nTab);
+
+    // Scenario 2: Similar to scenario 1, but a range of 4 cells and 2 of them 
have references
+    m_pDoc->InsertTab(nTab, "Test");
+
+    m_pDoc->SetValue(0, 0, nTab, 100.0); // A1
+    m_pDoc->SetValue(0, 1, nTab, 1.0); // A2
+    m_pDoc->SetValue(0, 2, nTab, 1000.0); // A3
+
+    m_pDoc->SetValue(1, 0, nTab, 100.0); // B1
+    m_pDoc->SetValue(1, 1, nTab, 1.0); // B2
+    m_pDoc->SetString(1, 2, nTab, "=B2"); // B3
+
+    m_pDoc->SetValue(2, 0, nTab, 100.0); // C1
+    m_pDoc->SetValue(2, 1, nTab, 1.0); // C2
+    m_pDoc->SetString(2, 2, nTab, "=C2"); // C3
+
+    m_pDoc->SetValue(3, 0, nTab, 100.0); // D1
+    m_pDoc->SetValue(3, 1, nTab, 1.0); // D2
+    m_pDoc->SetValue(3, 2, nTab, 1000.0); // D3
+
+    // Copy A1:D1 to the clip document.
+    copyToClip(m_pDoc, ScRange(0, 0, nTab, 3, 0, nTab), &aClipDoc); // A1:D1
+
+    aDestRange = ScRange(0, 2, nTab, 3, 2, nTab);
+    // Copy A3:D3 to the mix document (for arithmetic paste).
+    copyToClip(m_pDoc, aDestRange, &aMixDoc); // A3:D3
+
+    // Paste A1:D1 to A3:D3 and perform addition.
+    pasteFromClip(m_pDoc, aDestRange, &aClipDoc);
+    m_pDoc->MixDocument(aDestRange, ScPasteFunc::ADD, false, aMixDoc);
+
+    // Test precondition
+    CPPUNIT_ASSERT_EQUAL(1100.0, m_pDoc->GetValue(0, 2, nTab)); // A3
+    m_pDoc->GetFormula(0, 2, nTab, aFormula);
+    CPPUNIT_ASSERT_EQUAL(EMPTY_OUSTRING, aFormula);
+
+    CPPUNIT_ASSERT_EQUAL(101.0, m_pDoc->GetValue(1, 2, nTab)); // B3
+    m_pDoc->GetFormula(1, 2, nTab, aFormula);
+    CPPUNIT_ASSERT_EQUAL(OUString("=(B2)+100"), aFormula);
+
+    CPPUNIT_ASSERT_EQUAL(101.0, m_pDoc->GetValue(2, 2, nTab)); // C3
+    m_pDoc->GetFormula(2, 2, nTab, aFormula);
+    CPPUNIT_ASSERT_EQUAL(OUString("=(C2)+100"), aFormula);
+
+    CPPUNIT_ASSERT_EQUAL(1100.0, m_pDoc->GetValue(3, 2, nTab)); // D3
+    m_pDoc->GetFormula(3, 2, nTab, aFormula);
+    CPPUNIT_ASSERT_EQUAL(EMPTY_OUSTRING, aFormula);
+
+    // Change A2:D2 from 1.0 to 2.0 (auto calculation is triggered)
+    m_pDoc->SetValue(0, 1, nTab, 2.0); // A2
+    m_pDoc->SetValue(1, 1, nTab, 2.0); // B2
+    m_pDoc->SetValue(2, 1, nTab, 2.0); // C2
+    m_pDoc->SetValue(3, 1, nTab, 2.0); // D2
+
+    CPPUNIT_ASSERT_EQUAL(1100.0, m_pDoc->GetValue(0, 2, nTab)); // A3
+    m_pDoc->GetFormula(0, 2, nTab, aFormula);
+    CPPUNIT_ASSERT_EQUAL(EMPTY_OUSTRING, aFormula);
+
+    // Without the fix in place, this would have failed with
+    // - Expected: =102
+    // - Actual  : =101
+    CPPUNIT_ASSERT_EQUAL(102.0, m_pDoc->GetValue(1, 2, nTab)); // B3
+    m_pDoc->GetFormula(1, 2, nTab, aFormula);
+    CPPUNIT_ASSERT_EQUAL(OUString("=(B2)+100"), aFormula);
+
+    CPPUNIT_ASSERT_EQUAL(102.0, m_pDoc->GetValue(2, 2, nTab)); // C3
+    m_pDoc->GetFormula(2, 2, nTab, aFormula);
+    CPPUNIT_ASSERT_EQUAL(OUString("=(C2)+100"), aFormula);
+
+    CPPUNIT_ASSERT_EQUAL(1100.0, m_pDoc->GetValue(3, 2, nTab)); // D3
+    m_pDoc->GetFormula(3, 2, nTab, aFormula);
+    CPPUNIT_ASSERT_EQUAL(EMPTY_OUSTRING, aFormula);
+
+    // Scenario 3: Similar to scenario 2, but transposed
+    m_pDoc->InsertTab(nTab, "Test");
+
+    m_pDoc->SetValue(0, 0, nTab, 100.0); // A1
+    m_pDoc->SetValue(1, 0, nTab, 1.0); // B1
+    m_pDoc->SetValue(2, 0, nTab, 1000.0); // C1
+
+    m_pDoc->SetValue(0, 1, nTab, 100.0); // A2
+    m_pDoc->SetValue(1, 1, nTab, 1.0); // B2
+    m_pDoc->SetString(2, 1, nTab, "=B2"); // C2
+
+    m_pDoc->SetValue(0, 2, nTab, 100.0); // A3
+    m_pDoc->SetValue(1, 2, nTab, 1.0); // B3
+    m_pDoc->SetString(2, 2, nTab, "=B3"); // C3
+
+    m_pDoc->SetValue(0, 3, nTab, 100.0); // A4
+    m_pDoc->SetValue(1, 3, nTab, 1.0); // B4
+    m_pDoc->SetValue(2, 3, nTab, 1000.0); // C4
+
+    // Copy A1:A4 to the clip document.
+    copyToClip(m_pDoc, ScRange(0, 0, nTab, 0, 3, nTab), &aClipDoc); // A1:A4
+
+    aDestRange = ScRange(2, 0, nTab, 2, 3, nTab);
+    // Copy C1:C4 to the mix document (for arithmetic paste).
+    copyToClip(m_pDoc, aDestRange, &aMixDoc); // C1:C4
+
+    // Paste A1:A4 to C1:C4 and perform addition.
+    pasteFromClip(m_pDoc, aDestRange, &aClipDoc);
+    m_pDoc->MixDocument(aDestRange, ScPasteFunc::ADD, false, aMixDoc);
+
+    // Test precondition
+    CPPUNIT_ASSERT_EQUAL(1100.0, m_pDoc->GetValue(2, 0, nTab)); // C1
+    m_pDoc->GetFormula(2, 0, nTab, aFormula);
+    CPPUNIT_ASSERT_EQUAL(EMPTY_OUSTRING, aFormula);
+
+    CPPUNIT_ASSERT_EQUAL(101.0, m_pDoc->GetValue(2, 1, nTab)); // C2
+    m_pDoc->GetFormula(2, 1, nTab, aFormula);
+    CPPUNIT_ASSERT_EQUAL(OUString("=(B2)+100"), aFormula);
+
+    CPPUNIT_ASSERT_EQUAL(101.0, m_pDoc->GetValue(2, 2, nTab)); // C3
+    m_pDoc->GetFormula(2, 2, nTab, aFormula);
+    CPPUNIT_ASSERT_EQUAL(OUString("=(B3)+100"), aFormula);
+
+    CPPUNIT_ASSERT_EQUAL(1100.0, m_pDoc->GetValue(2, 3, nTab)); // C4
+    m_pDoc->GetFormula(2, 3, nTab, aFormula);
+    CPPUNIT_ASSERT_EQUAL(EMPTY_OUSTRING, aFormula);
+
+    // Change B1:B4 from 1.0 to 2.0 (auto calculation is triggered)
+    m_pDoc->SetValue(1, 0, nTab, 2.0); // B1
+    m_pDoc->SetValue(1, 1, nTab, 2.0); // B2
+    m_pDoc->SetValue(1, 2, nTab, 2.0); // B3
+    m_pDoc->SetValue(1, 3, nTab, 2.0); // B4
+
+    CPPUNIT_ASSERT_EQUAL(1100.0, m_pDoc->GetValue(2, 0, nTab)); // C1
+    m_pDoc->GetFormula(2, 0, nTab, aFormula);
+    CPPUNIT_ASSERT_EQUAL(EMPTY_OUSTRING, aFormula);
+
+    // Without the fix in place, this would have failed with
+    // - Expected: =102
+    // - Actual  : =101
+    CPPUNIT_ASSERT_EQUAL(102.0, m_pDoc->GetValue(2, 1, nTab)); // C2
+    m_pDoc->GetFormula(2, 1, nTab, aFormula);
+    CPPUNIT_ASSERT_EQUAL(OUString("=(B2)+100"), aFormula);
+
+    CPPUNIT_ASSERT_EQUAL(102.0, m_pDoc->GetValue(2, 2, nTab)); // C3
+    m_pDoc->GetFormula(2, 2, nTab, aFormula);
+    CPPUNIT_ASSERT_EQUAL(OUString("=(B3)+100"), aFormula);
+
+    CPPUNIT_ASSERT_EQUAL(1100.0, m_pDoc->GetValue(2, 3, nTab)); // C4
+    m_pDoc->GetFormula(2, 3, nTab, aFormula);
+    CPPUNIT_ASSERT_EQUAL(EMPTY_OUSTRING, aFormula);
+
+    m_pDoc->DeleteTab(nTab);
+}
+
+void TestCopyPaste::testCopyPasteMatrixFormula()
+{
+    m_pDoc->InsertTab(0, "hcv");
+
+    // Set Values to B1, C1, D1
+    m_pDoc->SetValue(ScAddress(1, 0, 0), 2.0); // B1
+    m_pDoc->SetValue(ScAddress(2, 0, 0), 5.0); // C1
+    m_pDoc->SetValue(ScAddress(3, 0, 0), 3.0); // D1
+
+    // Set Values to B2, C2
+    m_pDoc->SetString(ScAddress(1, 1, 0), "B2"); // B2
+    //m_pDoc->SetString(ScAddress(2,1,0), "C2");  // C2
+    m_pDoc->SetString(ScAddress(3, 1, 0), "D2"); // D2
+
+    // Set Values to D3
+    //m_pDoc->SetValue(ScAddress(1,2,0), 9.0);    // B3
+    //m_pDoc->SetString(ScAddress(2,2,0), "C3");  // C3
+    m_pDoc->SetValue(ScAddress(3, 2, 0), 11.0); // D3
+
+    // Insert matrix formula to A1
+    ScMarkData aMark(m_pDoc->GetSheetLimits());
+    aMark.SelectOneTable(0);
+    m_pDoc->InsertMatrixFormula(0, 0, 0, 0, aMark, 
"=COUNTIF(ISBLANK(B1:D1);TRUE())");
+    m_pDoc->CalcAll();
+    // A1 should contain 0
+    CPPUNIT_ASSERT_EQUAL(0.0, m_pDoc->GetValue(ScAddress(0, 0, 0))); // A1
+
+    // Copy cell A1 to clipboard.
+    ScAddress aPos(0, 0, 0); // A1
+    ScDocument aClipDoc(SCDOCMODE_CLIP);
+    ScClipParam aParam(aPos, false);
+    m_pDoc->CopyToClip(aParam, &aClipDoc, &aMark, false, false);
+    // Formula string should be equal.
+    CPPUNIT_ASSERT_EQUAL(m_pDoc->GetString(aPos), aClipDoc.GetString(aPos));
+
+    // First try single range.
+    // Paste matrix formula to A2
+    pasteFromClip(m_pDoc, ScRange(0, 1, 0, 0, 1, 0), &aClipDoc); // A2
+    // A2 Cell value should contain 1.0
+    CPPUNIT_ASSERT_EQUAL(1.0, m_pDoc->GetValue(ScAddress(0, 1, 0)));
+
+    // Paste matrix formula to A3
+    pasteFromClip(m_pDoc, ScRange(0, 2, 0, 0, 2, 0), &aClipDoc); // A3
+    // A3 Cell value should contain 2.0
+    CPPUNIT_ASSERT_EQUAL(2.0, m_pDoc->GetValue(ScAddress(0, 2, 0)));
+
+    // Paste matrix formula to A4
+    pasteFromClip(m_pDoc, ScRange(0, 3, 0, 0, 3, 0), &aClipDoc); // A4
+    // A4 Cell value should contain 3.0
+    CPPUNIT_ASSERT_EQUAL(3.0, m_pDoc->GetValue(ScAddress(0, 3, 0)));
+
+    // Clear cell A2:A4
+    clearRange(m_pDoc, ScRange(0, 1, 0, 0, 3, 0));
+
+    // Paste matrix formula to range A2:A4
+    pasteFromClip(m_pDoc, ScRange(0, 1, 0, 0, 3, 0), &aClipDoc); // A2:A4
+
+    // A2 Cell value should contain 1.0
+    CPPUNIT_ASSERT_EQUAL(1.0, m_pDoc->GetValue(ScAddress(0, 1, 0)));
+    // A3 Cell value should contain 2.0
+    CPPUNIT_ASSERT_EQUAL(2.0, m_pDoc->GetValue(ScAddress(0, 2, 0)));
+    // A4 Cell value should contain 3.0
+    CPPUNIT_ASSERT_EQUAL(3.0, m_pDoc->GetValue(ScAddress(0, 3, 0)));
+
+    m_pDoc->DeleteTab(0);
+}
+
 CPPUNIT_TEST_SUITE_REGISTRATION(TestCopyPaste);
 
 CPPUNIT_PLUGIN_IMPLEMENT();
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to