diff options
author | scito <info@scito.ch> | 2021-06-05 11:42:19 +0200 |
---|---|---|
committer | Xisco Fauli <xiscofauli@libreoffice.org> | 2021-06-07 09:59:58 +0200 |
commit | eb5e2e70ab4eaab9fea555160e61b24bd9941a63 (patch) | |
tree | 666033d9642eea79c5eb5df1fe9a1648f3a36156 /sc | |
parent | ec629c5ee22d02f99d66a5cf975ce239876b7f4d (diff) |
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 <xiscofauli@libreoffice.org>
Diffstat (limited to 'sc')
-rw-r--r-- | sc/qa/unit/ucalc.cxx | 490 | ||||
-rw-r--r-- | sc/qa/unit/ucalc_copypaste.cxx | 498 |
2 files changed, 498 insertions, 490 deletions
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(); |