diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:06:44 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:06:44 +0000 |
commit | ed5640d8b587fbcfed7dd7967f3de04b37a76f26 (patch) | |
tree | 7a5f7c6c9d02226d7471cb3cc8fbbf631b415303 /sc/qa/unit/copy_paste_test.cxx | |
parent | Initial commit. (diff) | |
download | libreoffice-ed5640d8b587fbcfed7dd7967f3de04b37a76f26.tar.xz libreoffice-ed5640d8b587fbcfed7dd7967f3de04b37a76f26.zip |
Adding upstream version 4:7.4.7.upstream/4%7.4.7upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'sc/qa/unit/copy_paste_test.cxx')
-rw-r--r-- | sc/qa/unit/copy_paste_test.cxx | 854 |
1 files changed, 854 insertions, 0 deletions
diff --git a/sc/qa/unit/copy_paste_test.cxx b/sc/qa/unit/copy_paste_test.cxx new file mode 100644 index 000000000..bcdce8eaa --- /dev/null +++ b/sc/qa/unit/copy_paste_test.cxx @@ -0,0 +1,854 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include <sal/config.h> + +#include <string_view> + +#include <test/bootstrapfixture.hxx> +#include <comphelper/processfactory.hxx> +#include <comphelper/propertyvalue.hxx> + +#include <docsh.hxx> +#include <docfunc.hxx> +#include <cellmergeoption.hxx> +#include <tabvwsh.hxx> +#include <impex.hxx> +#include <scitems.hxx> +#include <attrib.hxx> +#include <userlist.hxx> + +#include <com/sun/star/frame/Desktop.hpp> + +#include "helper/qahelper.hxx" + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; + +class ScCopyPasteTest : public ScBootstrapFixture +{ +public: + ScCopyPasteTest(); + + virtual void setUp() override; + virtual void tearDown() override; + + void testCopyPasteXLS(); + void testTdf84411(); + void testTdf124565(); + void testTdf126421(); + void testTdf107394(); + void testTdf53431_fillOnAutofilter(); + void testTdf40993_fillMergedCells(); + void testTdf43958_clickSelectOnMergedCells(); + void testTdf88782_autofillLinearNumbersInMergedCells(); + void tdf137621_autofillMergedBool(); + void tdf137205_autofillDatesInMergedCells(); + void tdf137653_137654_autofillUserlist(); + void tdf113500_autofillMixed(); + void tdf137625_autofillMergedUserlist(); + void tdf137624_autofillMergedMixed(); + + CPPUNIT_TEST_SUITE(ScCopyPasteTest); + CPPUNIT_TEST(testCopyPasteXLS); + CPPUNIT_TEST(testTdf84411); + CPPUNIT_TEST(testTdf124565); + CPPUNIT_TEST(testTdf126421); + CPPUNIT_TEST(testTdf107394); + CPPUNIT_TEST(testTdf53431_fillOnAutofilter); + CPPUNIT_TEST(testTdf40993_fillMergedCells); + CPPUNIT_TEST(testTdf43958_clickSelectOnMergedCells); + CPPUNIT_TEST(testTdf88782_autofillLinearNumbersInMergedCells); + CPPUNIT_TEST(tdf137621_autofillMergedBool); + CPPUNIT_TEST(tdf137205_autofillDatesInMergedCells); + CPPUNIT_TEST(tdf137653_137654_autofillUserlist); + CPPUNIT_TEST(tdf113500_autofillMixed); + CPPUNIT_TEST(tdf137625_autofillMergedUserlist); + CPPUNIT_TEST(tdf137624_autofillMergedMixed); + CPPUNIT_TEST_SUITE_END(); + +private: + void addToUserList(const OUString& rStr); + uno::Reference<uno::XInterface> m_xCalcComponent; +}; + +// tdf#83366 +void ScCopyPasteTest::testCopyPasteXLS() +{ + ScDocShellRef xDocSh = loadDocAndSetupModelViewController(u"chartx2.", FORMAT_XLS); + + ScDocument& rDoc = xDocSh->GetDocument(); + + // Get the document controller + ScTabViewShell* pViewShell = xDocSh->GetBestViewShell(false); + CPPUNIT_ASSERT(pViewShell != nullptr); + + // 2. Highlight B2:C5 + ScRange aSrcRange; + ScRefFlags nRes = aSrcRange.Parse("B2:C5", rDoc, rDoc.GetAddressConvention()); + CPPUNIT_ASSERT_MESSAGE("Failed to parse.", (nRes & ScRefFlags::VALID)); + + ScMarkData aMark(rDoc.GetSheetLimits()); + aMark.SetMarkArea(aSrcRange); + + pViewShell->GetViewData().GetMarkData().SetMarkArea(aSrcRange); + + // 3. Copy + ScDocument aClipDoc(SCDOCMODE_CLIP); + pViewShell->GetViewData().GetView()->CopyToClip(&aClipDoc, false, false, false, false); + + // 4. Close the document (Ctrl-W) + xDocSh->DoClose(); + + xDocSh = loadEmptyDocument(); + CPPUNIT_ASSERT(xDocSh); + + // Get the document controller + pViewShell = xDocSh->GetBestViewShell(false); + CPPUNIT_ASSERT(pViewShell != nullptr); + + // 6. Paste + pViewShell->GetViewData().GetView()->PasteFromClip(InsertDeleteFlags::ALL, &aClipDoc); + + xDocSh->DoClose(); +} + +namespace { + +ScMarkData::MarkedTabsType TabsInRange(const ScRange& r) +{ + ScMarkData::MarkedTabsType aResult; + for (SCTAB i = r.aStart.Tab(); i <= r.aEnd.Tab(); ++i) + aResult.insert(i); + return aResult; +} + +void lcl_copy( const OUString& rSrcRange, const OUString& rDstRange, ScDocument& rDoc, ScTabViewShell* pViewShell ) +{ + ScDocument aClipDoc(SCDOCMODE_CLIP); + + // 1. Copy + ScRange aSrcRange; + ScRefFlags nRes = aSrcRange.Parse(rSrcRange, rDoc, rDoc.GetAddressConvention()); + CPPUNIT_ASSERT_MESSAGE("Failed to parse.", (nRes & ScRefFlags::VALID)); + pViewShell->GetViewData().GetMarkData().SetMarkArea(aSrcRange); + pViewShell->GetViewData().GetMarkData().SetSelectedTabs(TabsInRange(aSrcRange)); + pViewShell->GetViewData().GetView()->CopyToClip(&aClipDoc, false, false, false, false); + + // 2. Paste + ScRange aDstRange; + nRes = aDstRange.Parse(rDstRange, rDoc, rDoc.GetAddressConvention()); + CPPUNIT_ASSERT_MESSAGE("Failed to parse.", (nRes & ScRefFlags::VALID)); + pViewShell->GetViewData().GetMarkData().SetMarkArea(aDstRange); + pViewShell->GetViewData().GetMarkData().SetSelectedTabs(TabsInRange(aDstRange)); + pViewShell->GetViewData().GetView()->PasteFromClip(InsertDeleteFlags::ALL, &aClipDoc); +} + +} // anonymous namespace + +void ScCopyPasteTest::testTdf84411() +{ + ScDocShellRef xDocSh = loadEmptyDocument(); + CPPUNIT_ASSERT(xDocSh); + + ScDocument& rDoc = xDocSh->GetDocument(); + + // Get the document controller + ScTabViewShell* pViewShell = xDocSh->GetBestViewShell(false); + CPPUNIT_ASSERT(pViewShell != nullptr); + + + // 2. Setup data and formulas + for (unsigned int r = 0; r <= 4991; ++r) + for (unsigned int c = 0; c <= 14; ++c) + rDoc.SetValue( ScAddress(c,r,0), (r+1)*(c+1) ); + + rDoc.SetString(ScAddress(15,10000,0), "=AVERAGE(A10001:O10001)"); + rDoc.SetString(ScAddress(16,10000,0), "=MIN(A10001:O10001)"); + rDoc.SetString(ScAddress(17,10000,0), "=MAX(A10001:O10001)"); + + lcl_copy("P10001:R10001", "P10002:R12500", rDoc, pViewShell); + + + // 3. Disable OpenCL + uno::Reference<lang::XComponent> xComponent = xDocSh->GetModel(); + ScModelObj* pModel = dynamic_cast<ScModelObj*>(xComponent.get()); + CPPUNIT_ASSERT(pModel != nullptr); + bool bOpenCLState = ScCalcConfig::isOpenCLEnabled(); + pModel->enableOpenCL(false); + CPPUNIT_ASSERT(!ScCalcConfig::isOpenCLEnabled() || ScCalcConfig::getForceCalculationType() == ForceCalculationOpenCL); + pModel->enableAutomaticCalculation(true); + + + // 4. Copy and Paste + lcl_copy("A1:O2500", "A10001:O12500", rDoc, pViewShell); + + lcl_copy("A2501:O5000", "A12501:O15000", rDoc, pViewShell); + + lcl_copy("P10001:R10001", "P12501:R15000", rDoc, pViewShell); + + + // 5. Close the document (Ctrl-W) + pModel->enableOpenCL(bOpenCLState); + + xDocSh->DoClose(); +} + +void ScCopyPasteTest::testTdf124565() +{ + ScDocShellRef xDocSh = loadEmptyDocument(); + CPPUNIT_ASSERT(xDocSh); + + ScDocument& rDoc = xDocSh->GetDocument(); + ScTabViewShell* pViewShell = xDocSh->GetBestViewShell(false); + CPPUNIT_ASSERT(pViewShell != nullptr); + + // Set content and height of first row + rDoc.SetString(ScAddress(0, 0, 0), "Test"); + rDoc.SetRowHeight(0, 0, 500); + rDoc.SetManualHeight(0, 0, 0, true); + + // Copy first row + ScDocument aClipDoc(SCDOCMODE_CLIP); + ScRange aCopyRange(0, 0, 0, aClipDoc.MaxCol(), 0, 0); + pViewShell->GetViewData().GetMarkData().SetMarkArea(aCopyRange); + pViewShell->GetViewData().GetView()->CopyToClip(&aClipDoc, false, false, false, false); + + // Paste to second row + SCTAB nTab = 0; + SCCOL nCol = 0; + SCROW nRow = 1; + + ScRange aPasteRange(nCol, nRow, nTab, aClipDoc.MaxCol(), nRow, nTab); + pViewShell->GetViewData().GetMarkData().SetMarkArea(aPasteRange); + pViewShell->GetViewData().GetView()->PasteFromClip(InsertDeleteFlags::ALL, &aClipDoc); + + // Copy-pasted? + CPPUNIT_ASSERT_EQUAL_MESSAGE("String was not pasted!", OUString("Test"), rDoc.GetString(nCol, nRow, nTab)); + + // And height same as in source? + CPPUNIT_ASSERT_EQUAL_MESSAGE("Row#2 height is invalid!", sal_uInt16(500), rDoc.GetRowHeight(nRow, nTab)); + + CPPUNIT_ASSERT_MESSAGE("Row#2 must be manual height!", rDoc.IsManualRowHeight(nRow, nTab)); + + xDocSh->DoClose(); +} + +void ScCopyPasteTest::testTdf126421() +{ + ScDocShellRef xDocSh = loadEmptyDocument(); + CPPUNIT_ASSERT(xDocSh); + + ScDocument& rDoc = xDocSh->GetDocument(); + + // Get the document controller + ScTabViewShell* pViewShell = xDocSh->GetBestViewShell(false); + CPPUNIT_ASSERT(pViewShell != nullptr); + + // 2. Setup data + for (int r = 0; r < 2; ++r) + for (int c = 0; c < 1024; ++c) + rDoc.SetValue(c, r, 0, (c + 1) * 100 + (r + 1)); + + const SCTAB n2ndTab = rDoc.GetMaxTableNumber() + 1; + rDoc.MakeTable(n2ndTab); + const auto aTabNames = rDoc.GetAllTableNames(); + + lcl_copy(aTabNames[0] + ".A1:AMJ2", aTabNames[n2ndTab] + ".A1:AMJ2", rDoc, pViewShell); + + // 3. Check all cells in destination table + for (int r = 0; r < 2; ++r) + for (int c = 0; c < 1024; ++c) + CPPUNIT_ASSERT_EQUAL(double((c + 1) * 100 + (r + 1)), rDoc.GetValue(c, r, n2ndTab)); + + xDocSh->DoClose(); +} + +void ScCopyPasteTest::testTdf107394() +{ + ScDocShellRef xDocSh = loadEmptyDocument(); + CPPUNIT_ASSERT(xDocSh); + + ScDocument& rDoc = xDocSh->GetDocument(); + + sal_uInt16 nFirstRowHeight = rDoc.GetRowHeight(0, 0); + sal_uInt16 nSecondRowHeight = rDoc.GetRowHeight(1, 0); + CPPUNIT_ASSERT_EQUAL(nFirstRowHeight, nSecondRowHeight); + + // Import values to A1:A2. + ScImportExport aObj(rDoc, ScAddress(0,0,0)); + aObj.SetImportBroadcast(true); + + SvMemoryStream aStream; + aStream.WriteOString("<pre>First\nVery long sentence.</pre>"); + aStream.Seek(0); + CPPUNIT_ASSERT(aObj.ImportStream(aStream, OUString(), SotClipboardFormatId::HTML)); + + CPPUNIT_ASSERT_EQUAL(OUString("First"), rDoc.GetString(ScAddress(0,0,0))); + CPPUNIT_ASSERT_EQUAL(OUString("Very long sentence."), rDoc.GetString(ScAddress(0,1,0))); + + nFirstRowHeight = rDoc.GetRowHeight(0, 0); + nSecondRowHeight = rDoc.GetRowHeight(1, 0); + CPPUNIT_ASSERT_GREATER(nFirstRowHeight, nSecondRowHeight); + + // Undo, and check the result. + SfxUndoManager* pUndoMgr = rDoc.GetUndoManager(); + CPPUNIT_ASSERT_MESSAGE("Failed to get the undo manager.", pUndoMgr); + pUndoMgr->Undo(); + + CPPUNIT_ASSERT(rDoc.GetString(ScAddress(0,0,0)).isEmpty()); + CPPUNIT_ASSERT(rDoc.GetString(ScAddress(0,1,0)).isEmpty()); + + nFirstRowHeight = rDoc.GetRowHeight(0, 0); + nSecondRowHeight = rDoc.GetRowHeight(1, 0); + // Without the accompanying fix in place, this test would have failed: + // - Expected: 256 + // - Actual : 477 + // i.e. the increased height of the second row remained after undo. + CPPUNIT_ASSERT_EQUAL(nFirstRowHeight, nSecondRowHeight); + + xDocSh->DoClose(); +} + +static ScMF lcl_getMergeFlagOfCell(const ScDocument& rDoc, SCCOL nCol, SCROW nRow, SCTAB nTab) +{ + const SfxPoolItem& rPoolItem = rDoc.GetPattern(nCol, nRow, nTab)->GetItem(ATTR_MERGE_FLAG); + const ScMergeFlagAttr& rMergeFlag = static_cast<const ScMergeFlagAttr&>(rPoolItem); + return rMergeFlag.GetValue(); +} + +static ScAddress lcl_getMergeSizeOfCell(const ScDocument& rDoc, SCCOL nCol, SCROW nRow, SCTAB nTab) +{ + const SfxPoolItem& rPoolItem = rDoc.GetPattern(nCol, nRow, nTab)->GetItem(ATTR_MERGE); + const ScMergeAttr& rMerge = static_cast<const ScMergeAttr&>(rPoolItem); + return ScAddress(rMerge.GetColMerge(), rMerge.GetRowMerge(), nTab); +} + +void ScCopyPasteTest::testTdf53431_fillOnAutofilter() +{ + ScDocShellRef xDocSh = loadDocAndSetupModelViewController(u"tdf53431_autofilterFilldown.", FORMAT_ODS); + ScDocument& rDoc = xDocSh->GetDocument(); + + // Get the document controller + ScTabViewShell* pView = xDocSh->GetBestViewShell(false); + CPPUNIT_ASSERT(pView != nullptr); + + //Fill should not clone Autofilter button + ScDocShell::GetViewData()->GetMarkData().SetMarkArea(ScRange(1, 1, 0, 2, 4, 0)); + pView->FillSimple(FILL_TO_BOTTOM); + CPPUNIT_ASSERT((lcl_getMergeFlagOfCell(rDoc, 1, 1, 0) & ScMF::Auto)); + CPPUNIT_ASSERT((lcl_getMergeFlagOfCell(rDoc, 2, 1, 0) & ScMF::Auto)); + CPPUNIT_ASSERT(!(lcl_getMergeFlagOfCell(rDoc, 1, 4, 0) & ScMF::Auto)); + + ScDocShell::GetViewData()->GetMarkData().SetMarkArea(ScRange(1, 1, 0, 4, 4, 0)); + pView->FillSimple(FILL_TO_RIGHT); + CPPUNIT_ASSERT((lcl_getMergeFlagOfCell(rDoc, 1, 1, 0) & ScMF::Auto)); + CPPUNIT_ASSERT((lcl_getMergeFlagOfCell(rDoc, 2, 1, 0) & ScMF::Auto)); + CPPUNIT_ASSERT(!(lcl_getMergeFlagOfCell(rDoc, 4, 1, 0) & ScMF::Auto)); + CPPUNIT_ASSERT(!(lcl_getMergeFlagOfCell(rDoc, 1, 4, 0) & ScMF::Auto)); + CPPUNIT_ASSERT(!(lcl_getMergeFlagOfCell(rDoc, 4, 4, 0) & ScMF::Auto)); + + //Fill should not delete Autofilter buttons + ScDocShell::GetViewData()->GetMarkData().SetMarkArea(ScRange(0, 0, 0, 2, 4, 0)); + pView->FillSimple(FILL_TO_TOP); + CPPUNIT_ASSERT((lcl_getMergeFlagOfCell(rDoc, 1, 1, 0) & ScMF::Auto)); + CPPUNIT_ASSERT((lcl_getMergeFlagOfCell(rDoc, 2, 1, 0) & ScMF::Auto)); + CPPUNIT_ASSERT(!(lcl_getMergeFlagOfCell(rDoc, 1, 0, 0) & ScMF::Auto)); + + ScDocShell::GetViewData()->GetMarkData().SetMarkArea(ScRange(0, 0, 0, 4, 4, 0)); + pView->FillSimple(FILL_TO_LEFT); + CPPUNIT_ASSERT((lcl_getMergeFlagOfCell(rDoc, 1, 1, 0) & ScMF::Auto)); + CPPUNIT_ASSERT((lcl_getMergeFlagOfCell(rDoc, 2, 1, 0) & ScMF::Auto)); + CPPUNIT_ASSERT(!(lcl_getMergeFlagOfCell(rDoc, 0, 1, 0) & ScMF::Auto)); +} + +void ScCopyPasteTest::testTdf40993_fillMergedCells() +{ + ScDocShellRef xDocSh = loadDocAndSetupModelViewController(u"tdf40993_fillMergedCells.", FORMAT_ODS); + ScDocument& rDoc = xDocSh->GetDocument(); + + // Get the document controller + ScTabViewShell* pView = xDocSh->GetBestViewShell(false); + CPPUNIT_ASSERT(pView != nullptr); + + // check content of the merged cell H11:I11 + CPPUNIT_ASSERT_EQUAL(OUString("1.5"), rDoc.GetString(ScAddress(7, 10, 0))); + + // fill operation on the merged cell should clone ATTR_MERGE and ATTR_MERGE_FLAG + // (as long as ATTR_MERGE_FLAG has only ScMF::Hor or ScMF::Ver) + // + // select merged cell + ScDocShell::GetViewData()->GetMarkData().SetMarkArea(ScRange(7, 10, 0, 8, 10, 0)); + // copy its content in the next ten rows + pView->FillAuto(FILL_TO_BOTTOM, 7, 10, 8, 10, 10); + for (int i = 7; i < 9; i++) + { + ScMF nOriginFlag = lcl_getMergeFlagOfCell(rDoc, i, 10, 0); + ScAddress aOriginMerge = lcl_getMergeSizeOfCell(rDoc, i, 10, 0); + + // ATTR_MERGE_FLAG: top left cell is NONE, the other cell shows horizontal overlapping + CPPUNIT_ASSERT_EQUAL(i == 7 ? ScMF::NONE : ScMF::Hor, nOriginFlag); + + // ATTR_MERGE: top left cell contains the size of the + // merged area (2:1), the other cell doesn't + CPPUNIT_ASSERT_EQUAL(i == 7 ? ScAddress(2, 1, 0): ScAddress(0, 0, 0), aOriginMerge); + + for (int j = 11; j < 21; j++) + { + // check copying of ATTR_MERGE and ATTR_MERGE_FLAG + CPPUNIT_ASSERT_EQUAL(lcl_getMergeFlagOfCell(rDoc, i, j, 0), nOriginFlag); + CPPUNIT_ASSERT_EQUAL(lcl_getMergeSizeOfCell(rDoc, i, j, 0), aOriginMerge); + } + } + + CPPUNIT_ASSERT_EQUAL(lcl_getMergeFlagOfCell(rDoc, 7, 21, 0), + lcl_getMergeFlagOfCell(rDoc, 7, 10, 0)); + CPPUNIT_ASSERT(lcl_getMergeSizeOfCell(rDoc, 7, 21, 0) != + lcl_getMergeSizeOfCell(rDoc, 7, 10, 0)); + CPPUNIT_ASSERT(lcl_getMergeFlagOfCell(rDoc, 8, 21, 0) != + lcl_getMergeFlagOfCell(rDoc, 8, 10, 0)); + CPPUNIT_ASSERT_EQUAL(lcl_getMergeSizeOfCell(rDoc, 8, 21, 0), + lcl_getMergeSizeOfCell(rDoc, 8, 10, 0)); + + // area A6:E9 with various merged cells copied vertically and horizontally + ScDocShell::GetViewData()->GetMarkData().SetMarkArea(ScRange(0, 5, 0, 4, 8, 0)); + pView->FillAuto(FILL_TO_BOTTOM, 0, 5, 4, 8, 12); + ScDocShell::GetViewData()->GetMarkData().SetMarkArea(ScRange(0, 5, 0, 4, 8, 0)); + pView->FillAuto(FILL_TO_RIGHT, 0, 5, 4, 8, 10); + for (int i = 0; i < 5; i++) + { + for (int j = 5; j < 9; j++) + { + ScMF nOriginFlag = lcl_getMergeFlagOfCell(rDoc, i, j, 0); + ScAddress aOriginMerge = lcl_getMergeSizeOfCell(rDoc, i, j, 0); + // copies contain the same ATTR_MERGE and ATTR_MERGE_FLAG + for (int k = 0; k < 12; k += 4) + { + CPPUNIT_ASSERT_EQUAL(lcl_getMergeFlagOfCell(rDoc, i, j + k, 0), nOriginFlag); + CPPUNIT_ASSERT_EQUAL(lcl_getMergeSizeOfCell(rDoc, i, j + k, 0), aOriginMerge); + } + for (int k = 0; k < 10; k += 5) + { + CPPUNIT_ASSERT_EQUAL(lcl_getMergeFlagOfCell(rDoc, i + k, j, 0), nOriginFlag); + CPPUNIT_ASSERT_EQUAL(lcl_getMergeSizeOfCell(rDoc, i + k, j, 0), aOriginMerge); + } + } + } + CPPUNIT_ASSERT_EQUAL(lcl_getMergeSizeOfCell(rDoc, 1, 5, 0), ScAddress(2, 4, 0)); + CPPUNIT_ASSERT_EQUAL(lcl_getMergeSizeOfCell(rDoc, 0, 5, 0), ScAddress(1, 2, 0)); + CPPUNIT_ASSERT_EQUAL(lcl_getMergeSizeOfCell(rDoc, 4, 6, 0), ScAddress(1, 2, 0)); + CPPUNIT_ASSERT_EQUAL(lcl_getMergeSizeOfCell(rDoc, 3, 5, 0), ScAddress(2, 1, 0)); +} + +static void lcl_clickAndCheckCurrentArea(SCCOL nCol, SCROW nRow, SCCOL nCol2, SCROW nRow2) +{ + ScRange aRange; + ScDocShell::GetViewData()->SetCurX(nCol); + ScDocShell::GetViewData()->SetCurY(nRow); + ScDocShell::GetViewData()->GetSimpleArea(aRange); + CPPUNIT_ASSERT_EQUAL(aRange, ScRange(nCol, nRow, 0, nCol2, nRow2, 0)); +} + +void ScCopyPasteTest::testTdf43958_clickSelectOnMergedCells() +{ + loadDocAndSetupModelViewController(u"tdf40993_fillMergedCells.", FORMAT_ODS); + + // select cell (e.g. by clicking on it) and check what is selected [but not marked]: + // if it is the top left cell of a merged area, the selection is enlarged to the area + lcl_clickAndCheckCurrentArea(1, 5, 2, 8); // B6 -> B6:C9 + lcl_clickAndCheckCurrentArea(0, 5, 0, 6); // A6 -> A6:A7 + lcl_clickAndCheckCurrentArea(3, 5, 4, 5); // D6 -> D6:E6 + lcl_clickAndCheckCurrentArea(4, 6, 4, 7); // D7 -> D6:D7 + lcl_clickAndCheckCurrentArea(7, 10, 8, 10); // H11 -> H11:I11 + lcl_clickAndCheckCurrentArea(7, 13, 8, 13); // H14 -> H14:I14 + + // otherwise it remains the same + lcl_clickAndCheckCurrentArea(0, 7, 0, 7); // A8 + lcl_clickAndCheckCurrentArea(0, 8, 0, 8); // A9 + lcl_clickAndCheckCurrentArea(2, 6, 2, 6); // C7 + lcl_clickAndCheckCurrentArea(2, 7, 2, 7); // C8 + lcl_clickAndCheckCurrentArea(2, 8, 2, 8); // C9 +} + +void ScCopyPasteTest::testTdf88782_autofillLinearNumbersInMergedCells() +{ + ScDocShellRef xDocSh = loadDocAndSetupModelViewController(u"tdf88782_AutofillLinearNumbersInMergedCells.", FORMAT_ODS); + ScDocument& rDoc = xDocSh->GetDocument(); + + // Get the document controller + ScTabViewShell* pView = xDocSh->GetBestViewShell(false); + CPPUNIT_ASSERT(pView != nullptr); + + // merge the yellow cells + ScCellMergeOption aMergeOptions(9, 11, 10, 13); //J12:K14 + aMergeOptions.maTabs.insert(0); + xDocSh->GetDocFunc().MergeCells(aMergeOptions, false, true, true, false); + + // fillauto numbers, these areas contain mostly merged cells + pView->FillAuto(FILL_TO_BOTTOM, 1, 8, 3, 14, 7); // B9:D15 -> B9:D22 + pView->FillAuto(FILL_TO_BOTTOM, 5, 8, 7, 17, 10); // F9:H18 -> F9:H28 + pView->FillAuto(FILL_TO_BOTTOM, 9, 8, 10, 13, 6); // J9:K14 -> J9:K20 + pView->FillAuto(FILL_TO_RIGHT, 9, 30, 16, 35, 8); //J31:Q36 -> J31:Y36 + pView->FillAuto(FILL_TO_LEFT, 9, 30, 16, 35, 8); //J31:Q36 -> B31:Q36 + + // compare the results of fill-down with the reference stored in the test file + // this compares the whole area blindly, for specific test cases, check the test file + // the test file have instructions / explanations, so that is easy to understand + for (int nCol = 1; nCol <= 10; nCol++) + { + for (int nRow = 8; nRow <= 27; nRow++) + { + CellType nType1 = rDoc.GetCellType(ScAddress(nCol, nRow, 0)); + CellType nType2 = rDoc.GetCellType(ScAddress(nCol + 22, nRow, 0)); + double* pValue1 = rDoc.GetValueCell(ScAddress(nCol, nRow, 0)); + double* pValue2 = rDoc.GetValueCell(ScAddress(nCol + 22, nRow, 0)); + + CPPUNIT_ASSERT_EQUAL(nType1, nType2); + if (pValue2 != nullptr) + CPPUNIT_ASSERT_EQUAL(*pValue1, *pValue2); //cells with number value + else + CPPUNIT_ASSERT_EQUAL(pValue1, pValue2); //empty cells + } + } + + // compare the results of fill-right and left with the reference stored in the test file + for (int nCol = 1; nCol <= 24; nCol++) + { + for (int nRow = 30; nRow <= 35; nRow++) + { + CellType nType1 = rDoc.GetCellType(ScAddress(nCol, nRow, 0)); + CellType nType2 = rDoc.GetCellType(ScAddress(nCol, nRow + 16, 0)); + double* pValue1 = rDoc.GetValueCell(ScAddress(nCol, nRow, 0)); + double* pValue2 = rDoc.GetValueCell(ScAddress(nCol, nRow + 16, 0)); + + CPPUNIT_ASSERT_EQUAL(nType1, nType2); + if (pValue2 != nullptr) + CPPUNIT_ASSERT_EQUAL(*pValue1, *pValue2); + else + CPPUNIT_ASSERT_EQUAL(pValue1, pValue2); + } + } +} + +void ScCopyPasteTest::tdf137621_autofillMergedBool() +{ + ScDocShellRef xDocSh = loadDocAndSetupModelViewController(u"tdf137621_autofillMergedBool.", FORMAT_ODS); + ScDocument& rDoc = xDocSh->GetDocument(); + + // Get the document controller + ScTabViewShell* pView = xDocSh->GetBestViewShell(false); + CPPUNIT_ASSERT(pView != nullptr); + + // fillauto booleans, these areas contain only merged cells + pView->FillAuto(FILL_TO_RIGHT, 0, 4, 3, 5, 8); //A5:D6 + + // compare the results of fill-right with the reference stored in the test file + // this compares the whole area blindly, for specific test cases, check the test file + for (int nCol = 4; nCol <= 11; nCol++) + { + for (int nRow = 4; nRow <= 5; nRow++) + { + CellType nType1 = rDoc.GetCellType(ScAddress(nCol, nRow, 0)); + CellType nType2 = rDoc.GetCellType(ScAddress(nCol, nRow + 3, 0)); + double* pValue1 = rDoc.GetValueCell(ScAddress(nCol, nRow, 0)); + double* pValue2 = rDoc.GetValueCell(ScAddress(nCol, nRow + 3, 0)); + + CPPUNIT_ASSERT_EQUAL(nType1, nType2); + if (pValue2 != nullptr) + CPPUNIT_ASSERT_EQUAL(*pValue1, *pValue2); //cells with boolean value + else + CPPUNIT_ASSERT_EQUAL(pValue1, pValue2); //empty cells + } + } +} + +void ScCopyPasteTest::tdf137205_autofillDatesInMergedCells() +{ + ScDocShellRef xDocSh = loadDocAndSetupModelViewController(u"tdf137205_AutofillDatesInMergedCells.", FORMAT_ODS); + ScDocument& rDoc = xDocSh->GetDocument(); + + // Get the document controller + ScTabViewShell* pView = xDocSh->GetBestViewShell(false); + CPPUNIT_ASSERT(pView != nullptr); + + // fillauto dates, this areas contain only merged cells + pView->FillAuto(FILL_TO_RIGHT, 1, 5, 4, 7, 8); //B6:E8 + + // compare the results of fill-right with the reference stored in the test file + // this compares the whole area blindly, for specific test cases, check the test file + for (int nCol = 5; nCol <= 12; nCol++) + { + for (int nRow = 5; nRow <= 7; nRow++) + { + CellType nType1 = rDoc.GetCellType(ScAddress(nCol, nRow, 0)); + CellType nType2 = rDoc.GetCellType(ScAddress(nCol, nRow + 5, 0)); + double* pValue1 = rDoc.GetValueCell(ScAddress(nCol, nRow, 0)); + double* pValue2 = rDoc.GetValueCell(ScAddress(nCol, nRow + 5, 0)); + + CPPUNIT_ASSERT_EQUAL(nType1, nType2); + if (pValue2 != nullptr) + CPPUNIT_ASSERT_EQUAL(*pValue1, *pValue2); //cells with number value + else + CPPUNIT_ASSERT_EQUAL(pValue1, pValue2); //empty cells + } + } +} + +void ScCopyPasteTest::addToUserList(const OUString& rStr) +{ + ScUserListData* aListData = new ScUserListData(rStr); + ScGlobal::GetUserList()->push_back(aListData); +} + +void ScCopyPasteTest::tdf137653_137654_autofillUserlist() +{ + ScDocShellRef xDocSh = loadDocAndSetupModelViewController(u"tdf137653_137654_autofillUserlist.", FORMAT_ODS); + ScDocument& rDoc = xDocSh->GetDocument(); + + // Get the document controller + ScTabViewShell* pView = xDocSh->GetBestViewShell(false); + CPPUNIT_ASSERT(pView != nullptr); + + // delete every userlist to make sure there won't be any string that is in 2 different userlist + ScGlobal::GetUserList()->clear(); + addToUserList({ "January,February,March,April,May,June,July,August,September,October,November,December" }); + const ScUserListData* pListData = ScGlobal::GetUserList()->GetData("January"); + sal_uInt16 nIdx1 = 0, nIdx2 = 0; + bool bHasIdx1, bHasIdx2; + bool bMatchCase = false; + + // fillauto userlist, these areas contain only merged cells + pView->FillAuto(FILL_TO_RIGHT, 4, 5, 6, 7, 3); //E6:G8 + pView->FillAuto(FILL_TO_LEFT, 4, 5, 6, 7, 3); //E6:G8 + pView->FillAuto(FILL_TO_BOTTOM, 1, 18, 3, 19, 2); //B19:D20 + pView->FillAuto(FILL_TO_TOP, 1, 18, 3, 19, 2); //B19:D20 + + // compare the results of fill-right / -left with the reference stored in the test file + // this compares the whole area blindly, for specific test cases, check the test file + for (int nCol = 1; nCol <= 9; nCol++) + { + for (int nRow = 5; nRow <= 7; nRow++) + { + CellType nType1 = rDoc.GetCellType(ScAddress(nCol, nRow, 0)); + CellType nType2 = rDoc.GetCellType(ScAddress(nCol, nRow + 4, 0)); + bHasIdx1 = pListData->GetSubIndex(rDoc.GetString(nCol, nRow, 0), nIdx1, bMatchCase); + bHasIdx2 = pListData->GetSubIndex(rDoc.GetString(nCol, nRow + 4, 0), nIdx2, bMatchCase); + + CPPUNIT_ASSERT_EQUAL(nType1, nType2); + CPPUNIT_ASSERT(bHasIdx1); + CPPUNIT_ASSERT(bHasIdx2); + CPPUNIT_ASSERT_EQUAL(nIdx1, nIdx2); // userlist index value of cells + } + } + + // compare the results of fill-up / -down + for (int nCol = 1; nCol <= 3; nCol++) + { + for (int nRow = 16; nRow <= 21; nRow++) + { + CellType nType1 = rDoc.GetCellType(ScAddress(nCol, nRow, 0)); + CellType nType2 = rDoc.GetCellType(ScAddress(nCol + 4, nRow, 0)); + bHasIdx1 = pListData->GetSubIndex(rDoc.GetString(nCol, nRow, 0), nIdx1, bMatchCase); + bHasIdx2 = pListData->GetSubIndex(rDoc.GetString(nCol + 4, nRow, 0), nIdx2, bMatchCase); + + CPPUNIT_ASSERT_EQUAL(nType1, nType2); + CPPUNIT_ASSERT(bHasIdx1); + CPPUNIT_ASSERT(bHasIdx2); + CPPUNIT_ASSERT_EQUAL(nIdx1, nIdx2); // userlist index value of cells + } + } +} + +void ScCopyPasteTest::tdf113500_autofillMixed() +{ + ScDocShellRef xDocSh = loadDocAndSetupModelViewController(u"tdf113500_autofillMixed.", FORMAT_ODS); + ScDocument& rDoc = xDocSh->GetDocument(); + + // Get the document controller + ScTabViewShell* pView = xDocSh->GetBestViewShell(false); + CPPUNIT_ASSERT(pView != nullptr); + + // fillauto userlist, these areas contain only merged cells + pView->FillAuto(FILL_TO_RIGHT, 4, 5, 6, 7, 3); //E6:G8 + pView->FillAuto(FILL_TO_LEFT, 4, 5, 6, 7, 3); //E6:G8 + pView->FillAuto(FILL_TO_BOTTOM, 1, 18, 3, 19, 2); //B19:D20 + pView->FillAuto(FILL_TO_TOP, 1, 18, 3, 19, 2); //B19:D20 + + // compare the results of fill-right / -left with the reference stored in the test file + // this compares the whole area blindly, for specific test cases, check the test file + // do not check the 3. row: a1,b2,a3. It is another bug to fix + for (int nCol = 1; nCol <= 9; nCol++) + { + for (int nRow = 5; nRow <= 6; nRow++) + { + CellType nType1 = rDoc.GetCellType(ScAddress(nCol, nRow, 0)); + CellType nType2 = rDoc.GetCellType(ScAddress(nCol, nRow + 4, 0)); + OUString aStr1 = rDoc.GetString(nCol, nRow, 0); + OUString aStr2 = rDoc.GetString(nCol, nRow + 4, 0); + + CPPUNIT_ASSERT_EQUAL(nType1, nType2); + CPPUNIT_ASSERT_EQUAL(aStr1, aStr2); + } + } + + // compare the results of fill-up / -down + // do not check the 2. column: 1st,3st. It is another bug to fix + for (int nCol = 1; nCol <= 3; nCol+=2) + { + for (int nRow = 16; nRow <= 21; nRow++) + { + CellType nType1 = rDoc.GetCellType(ScAddress(nCol, nRow, 0)); + CellType nType2 = rDoc.GetCellType(ScAddress(nCol + 4, nRow, 0)); + OUString aStr1 = rDoc.GetString(nCol, nRow, 0); + OUString aStr2 = rDoc.GetString(nCol + 4, nRow, 0); + + CPPUNIT_ASSERT_EQUAL(nType1, nType2); + CPPUNIT_ASSERT_EQUAL(aStr1, aStr2); + } + } +} + +void ScCopyPasteTest::tdf137625_autofillMergedUserlist() +{ + ScDocShellRef xDocSh = loadDocAndSetupModelViewController(u"tdf137625_autofillMergedUserlist.", FORMAT_ODS); + ScDocument& rDoc = xDocSh->GetDocument(); + + // Get the document controller + ScTabViewShell* pView = xDocSh->GetBestViewShell(false); + CPPUNIT_ASSERT(pView != nullptr); + + // delete every userlist to make sure there won't be any string that is in 2 different userlist + ScGlobal::GetUserList()->clear(); + addToUserList({ "January,February,March,April,May,June,July,August,September,October,November,December" }); + const ScUserListData* pListData = ScGlobal::GetUserList()->GetData("January"); + sal_uInt16 nIdx1 = 0, nIdx2 = 0; + bool bHasIdx1, bHasIdx2; + bool bMatchCase = false; + + // fillauto userlist, these areas contain only merged cells + pView->FillAuto(FILL_TO_RIGHT, 7, 5, 12, 7, 6); //H6:M8 + pView->FillAuto(FILL_TO_LEFT, 7, 5, 12, 7, 6); //H6:M8 + pView->FillAuto(FILL_TO_BOTTOM, 1, 20, 3, 23, 4); //B21:D24 + pView->FillAuto(FILL_TO_TOP, 1, 20, 3, 23, 4); //B21:D24 + + // compare the results of fill-right / -left with the reference stored in the test file + // this compares the whole area blindly, for specific test cases, check the test file + for (int nCol = 1; nCol <= 18; nCol++) + { + for (int nRow = 5; nRow <= 7; nRow++) + { + CellType nType1 = rDoc.GetCellType(ScAddress(nCol, nRow, 0)); + CellType nType2 = rDoc.GetCellType(ScAddress(nCol, nRow + 4, 0)); + bHasIdx1 = pListData->GetSubIndex(rDoc.GetString(nCol, nRow, 0), nIdx1, bMatchCase); + bHasIdx2 = pListData->GetSubIndex(rDoc.GetString(nCol, nRow + 4, 0), nIdx2, bMatchCase); + + CPPUNIT_ASSERT_EQUAL(nType1, nType2); + CPPUNIT_ASSERT_EQUAL(bHasIdx1, bHasIdx2); + if (bHasIdx1) + CPPUNIT_ASSERT_EQUAL(nIdx1, nIdx2); //cells with userlist value + } + } + + // compare the results of fill-up / -down + for (int nCol = 1; nCol <= 3; nCol++) + { + for (int nRow = 16; nRow <= 27; nRow++) + { + CellType nType1 = rDoc.GetCellType(ScAddress(nCol, nRow, 0)); + CellType nType2 = rDoc.GetCellType(ScAddress(nCol + 4, nRow, 0)); + bHasIdx1 = pListData->GetSubIndex(rDoc.GetString(nCol, nRow, 0), nIdx1, bMatchCase); + bHasIdx2 = pListData->GetSubIndex(rDoc.GetString(nCol + 4, nRow, 0), nIdx2, bMatchCase); + + CPPUNIT_ASSERT_EQUAL(nType1, nType2); + CPPUNIT_ASSERT_EQUAL(bHasIdx1, bHasIdx2); + if (bHasIdx1) + CPPUNIT_ASSERT_EQUAL(nIdx1, nIdx2); //cells with userlist value + } + } +} + +void ScCopyPasteTest::tdf137624_autofillMergedMixed() +{ + ScDocShellRef xDocSh = loadDocAndSetupModelViewController(u"tdf137624_autofillMergedMixed.", FORMAT_ODS); + ScDocument& rDoc = xDocSh->GetDocument(); + + // Get the document controller + ScTabViewShell* pView = xDocSh->GetBestViewShell(false); + CPPUNIT_ASSERT(pView != nullptr); + + // add 1aa,2bb,3cc,4dd,5ee,6ff to userlist, to test that autofill won't confuse it with 1aa,3aa + // delete every userlist to make sure there won't be any string that is in 2 different userlist + ScGlobal::GetUserList()->clear(); + addToUserList({ "1aa,2bb,3cc,4dd,5ee,6ff" }); + + // fillauto mixed (string + number), these areas contain only merged cells + pView->FillAuto(FILL_TO_RIGHT, 7, 5, 12, 7, 6); //H6:M8 + pView->FillAuto(FILL_TO_LEFT, 7, 5, 12, 7, 6); //H6:M8 + pView->FillAuto(FILL_TO_BOTTOM, 1, 20, 3, 23, 4); //B21:D24 + pView->FillAuto(FILL_TO_TOP, 1, 20, 3, 23, 4); //B21:D24 + + // compare the results of fill-right / -left with the reference stored in the test file + // this compares the whole area blindly, for specific test cases, check the test file + for (int nCol = 1; nCol <= 18; nCol++) + { + for (int nRow = 5; nRow <= 7; nRow++) + { + CellType nType1 = rDoc.GetCellType(ScAddress(nCol, nRow, 0)); + CellType nType2 = rDoc.GetCellType(ScAddress(nCol, nRow + 4, 0)); + OUString aStr1 = rDoc.GetString(nCol, nRow, 0); + OUString aStr2 = rDoc.GetString(nCol, nRow + 4, 0); + + CPPUNIT_ASSERT_EQUAL(nType1, nType2); + CPPUNIT_ASSERT_EQUAL(aStr1, aStr2); + } + } + + // compare the results of fill-up / -down + for (int nCol = 1; nCol <= 3; nCol++) + { + for (int nRow = 16; nRow <= 27; nRow++) + { + CellType nType1 = rDoc.GetCellType(ScAddress(nCol, nRow, 0)); + CellType nType2 = rDoc.GetCellType(ScAddress(nCol + 4, nRow, 0)); + OUString aStr1 = rDoc.GetString(nCol, nRow, 0); + OUString aStr2 = rDoc.GetString(nCol + 4, nRow, 0); + + CPPUNIT_ASSERT_EQUAL(nType1, nType2); + CPPUNIT_ASSERT_EQUAL(aStr1, aStr2); + } + } +} + +ScCopyPasteTest::ScCopyPasteTest() + : ScBootstrapFixture( "sc/qa/unit/data" ) +{ +} + +void ScCopyPasteTest::setUp() +{ + test::BootstrapFixture::setUp(); + + // This is a bit of a fudge, we do this to ensure that ScGlobals::ensure, + // which is a private symbol to us, gets called + m_xCalcComponent = + getMultiServiceFactory()->createInstance("com.sun.star.comp.Calc.SpreadsheetDocument"); + CPPUNIT_ASSERT_MESSAGE("no calc component!", m_xCalcComponent.is()); +} + +void ScCopyPasteTest::tearDown() +{ + uno::Reference< lang::XComponent >( m_xCalcComponent, UNO_QUERY_THROW )->dispose(); + test::BootstrapFixture::tearDown(); +} + +CPPUNIT_TEST_SUITE_REGISTRATION(ScCopyPasteTest); + +CPPUNIT_PLUGIN_IMPLEMENT(); + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |