diff options
author | Mike Kaganski <mike.kaganski@collabora.com> | 2019-07-17 12:15:28 +1000 |
---|---|---|
committer | Mike Kaganski <mike.kaganski@collabora.com> | 2019-07-17 09:53:50 +0200 |
commit | 2d4ccc58e9ef3b98a88407e1a7a3abf3379f0d20 (patch) | |
tree | 9518f96f00a8a3ca3a0ac7a0c9f38db229d30509 | |
parent | 0e82806ed6841c0a6919f97660ed4622c89d2338 (diff) |
tdf#126421: don't limit pasted data to allocated columns in destination
Change-Id: Ic30360795c5dac1dc232f95bd25f5a11946c7dee
Reviewed-on: https://gerrit.libreoffice.org/75738
Tested-by: Jenkins
Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
-rw-r--r-- | sc/qa/unit/copy_paste_test.cxx | 74 | ||||
-rw-r--r-- | sc/source/core/data/table2.cxx | 7 |
2 files changed, 79 insertions, 2 deletions
diff --git a/sc/qa/unit/copy_paste_test.cxx b/sc/qa/unit/copy_paste_test.cxx index 8a65609b51b1..6d4e0fb3f6bf 100644 --- a/sc/qa/unit/copy_paste_test.cxx +++ b/sc/qa/unit/copy_paste_test.cxx @@ -33,11 +33,13 @@ public: void testCopyPasteXLS(); void testTdf84411(); void testTdf124565(); + void testTdf126421(); CPPUNIT_TEST_SUITE(ScCopyPasteTest); CPPUNIT_TEST(testCopyPasteXLS); CPPUNIT_TEST(testTdf84411); CPPUNIT_TEST(testTdf124565); + CPPUNIT_TEST(testTdf126421); CPPUNIT_TEST_SUITE_END(); private: @@ -126,6 +128,14 @@ void ScCopyPasteTest::testCopyPasteXLS() 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); @@ -135,6 +145,7 @@ void lcl_copy( const OUString& rSrcRange, const OUString& rDstRange, ScDocument& 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 @@ -142,6 +153,7 @@ void lcl_copy( const OUString& rSrcRange, const OUString& rDstRange, ScDocument& 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); } @@ -289,6 +301,68 @@ void ScCopyPasteTest::testTdf124565() xDocSh->DoClose(); } +void ScCopyPasteTest::testTdf126421() +{ + uno::Reference<frame::XDesktop2> xDesktop + = frame::Desktop::create(::comphelper::getProcessComponentContext()); + CPPUNIT_ASSERT(xDesktop.is()); + + // create a frame + Reference<frame::XFrame> xTargetFrame = xDesktop->findFrame("_blank", 0); + CPPUNIT_ASSERT(xTargetFrame.is()); + + // 1. Create spreadsheet + uno::Sequence<beans::PropertyValue> aEmptyArgList; + uno::Reference<lang::XComponent> xComponent + = xDesktop->loadComponentFromURL("private:factory/scalc", "_blank", 0, aEmptyArgList); + CPPUNIT_ASSERT(xComponent.is()); + + // Get the document model + SfxObjectShell* pFoundShell = SfxObjectShell::GetShellFromComponent(xComponent); + CPPUNIT_ASSERT_MESSAGE("Failed to access document shell", pFoundShell); + + ScDocShellRef xDocSh = dynamic_cast<ScDocShell*>(pFoundShell); + CPPUNIT_ASSERT(xDocSh); + + uno::Reference<frame::XModel2> xModel2(xDocSh->GetModel(), UNO_QUERY); + CPPUNIT_ASSERT(xModel2.is()); + + Reference<frame::XController2> xController(xModel2->createDefaultViewController(xTargetFrame), + UNO_QUERY); + CPPUNIT_ASSERT(xController.is()); + + // introduce model/view/controller to each other + xController->attachModel(xModel2.get()); + xModel2->connectController(xController.get()); + xTargetFrame->setComponent(xController->getComponentWindow(), xController.get()); + xController->attachFrame(xTargetFrame); + xModel2->setCurrentController(xController.get()); + + 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(); +} + ScCopyPasteTest::ScCopyPasteTest() : ScBootstrapFixture( "sc/qa/unit/data" ) { diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx index 388e0bb1be61..5b182c897b4b 100644 --- a/sc/source/core/data/table2.cxx +++ b/sc/source/core/data/table2.cxx @@ -670,17 +670,20 @@ bool ScTable::InitColumnBlockPosition( sc::ColumnBlockPosition& rBlockPos, SCCOL return true; } +// pTable is source + void ScTable::CopyFromClip( sc::CopyFromClipContext& rCxt, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, SCCOL nDx, SCROW nDy, ScTable* pTable ) { - if (nCol2 > aCol.size() - 1) - nCol2 = aCol.size() - 1; + if (nCol2 > MAXCOL) + nCol2 = MAXCOL; if (nRow2 > MAXROW) nRow2 = MAXROW; if (ValidColRow(nCol1, nRow1) && ValidColRow(nCol2, nRow2)) { + CreateColumnIfNotExists(nCol2); for ( SCCOL i = nCol1; i <= nCol2; i++) { pTable->CreateColumnIfNotExists(i - nDx); |