summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Kaganski <mike.kaganski@collabora.com>2019-07-17 12:15:28 +1000
committerChristian Lohmaier <lohmaier+LibreOffice@googlemail.com>2019-07-18 22:16:14 +0200
commit7e803a348a020bc48a039c4f7f098ae17843c534 (patch)
tree1a5a24737b2257716382affc5d02f78660c53432
parent235a74d2e9d0e5e991777ef6d1a1625dab009670 (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> (cherry picked from commit 2d4ccc58e9ef3b98a88407e1a7a3abf3379f0d20) Reviewed-on: https://gerrit.libreoffice.org/75756 Reviewed-by: Christian Lohmaier <lohmaier+LibreOffice@googlemail.com>
-rw-r--r--sc/qa/unit/copy_paste_test.cxx74
-rw-r--r--sc/source/core/data/table2.cxx7
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 967faaadf13a..a31312c6fe6f 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 2aee672f8ad2..5edff4b4889b 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);