sc/qa/unit/tiledrendering/data/multi-selection.ods |binary
 sc/qa/unit/tiledrendering/tiledrendering.cxx       |   30 +++++++++++++++++++++
 sc/source/ui/view/viewfun3.cxx                     |    8 +++++
 3 files changed, 38 insertions(+)

New commits:
commit 1eda0a81fcf1bf2ce2fd4f29502eaa62879a50d4
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Wed Apr 17 16:25:19 2024 +0200
Commit:     Caolán McNamara <caolan.mcnam...@collabora.com>
CommitDate: Thu Apr 18 09:20:09 2024 +0200

    cool#8789 sc lok: fix copy for multi-selections
    
    Select A1+A3 in Calc, copy, try to paste in B1, nothing happens.
    
    This is because lok::Document::getSelectionTypeAndText() for a Calc
    document ends up in ScViewFunc::CopyToTransferable(), which only handles
    the SC_MARK_SIMPLE* cases.
    
    Fix the problem by implementing support for SC_MARK_MULTI, similar to
    what ScCellShell::ExecuteEdit() does in the SID_COPY case, which also
    calls CopyToClip().
    
    Keep the test highlevel as the Calc shell doesn't seem to have an easy
    function to do the same as the Ctrl-click on a cell without duplicating
    lots of code in the testcase.
    
    Change-Id: I641d9db95ca391a4f39d96aeeb33422129262288
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/166183
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com>
    Reviewed-by: Caolán McNamara <caolan.mcnam...@collabora.com>

diff --git a/sc/qa/unit/tiledrendering/data/multi-selection.ods 
b/sc/qa/unit/tiledrendering/data/multi-selection.ods
new file mode 100644
index 000000000000..9436aaf93c26
Binary files /dev/null and b/sc/qa/unit/tiledrendering/data/multi-selection.ods 
differ
diff --git a/sc/qa/unit/tiledrendering/tiledrendering.cxx 
b/sc/qa/unit/tiledrendering/tiledrendering.cxx
index 6057a1db0b6d..6e47eefd5cd0 100644
--- a/sc/qa/unit/tiledrendering/tiledrendering.cxx
+++ b/sc/qa/unit/tiledrendering/tiledrendering.cxx
@@ -180,6 +180,7 @@ public:
     void testOptimalRowHeight();
     void testExtendedAreasDontOverlap();
     void testEditShapeText();
+    void testCopyMultiSelection();
 
     CPPUNIT_TEST_SUITE(ScTiledRenderingTest);
     CPPUNIT_TEST(testRowColumnHeaders);
@@ -261,6 +262,7 @@ public:
     CPPUNIT_TEST(testOptimalRowHeight);
     CPPUNIT_TEST(testExtendedAreasDontOverlap);
     CPPUNIT_TEST(testEditShapeText);
+    CPPUNIT_TEST(testCopyMultiSelection);
     CPPUNIT_TEST_SUITE_END();
 
 private:
@@ -4126,6 +4128,34 @@ void ScTiledRenderingTest::testEditShapeText()
     CPPUNIT_ASSERT_MESSAGE("Text is not visible", aBitmapBefore != 
aBitmapAfter);
 }
 
+void ScTiledRenderingTest::testCopyMultiSelection()
+{
+    // Given a document with A1 and A3 as selected cells:
+    ScModelObj* pModelObj = createDoc("multi-selection.ods");
+    ViewCallback aView1;
+    // Get the center of A3:
+    uno::Sequence<beans::PropertyValue> aPropertyValues = {
+        comphelper::makePropertyValue("ToPoint", OUString("$A$3")),
+    };
+    dispatchCommand(mxComponent, ".uno:GoToCell", aPropertyValues);
+    Point aPoint = aView1.m_aCellCursorBounds.Center();
+    // Go to A1:
+    aPropertyValues = {
+        comphelper::makePropertyValue("ToPoint", OUString("$A$1")),
+    };
+    dispatchCommand(mxComponent, ".uno:GoToCell", aPropertyValues);
+    // Ctrl-click on A3:
+    int nCtrl = KEY_MOD1;
+    pModelObj->postMouseEvent(LOK_MOUSEEVENT_MOUSEBUTTONDOWN, aPoint.getX(), 
aPoint.getY(), 1,
+                              MOUSE_LEFT, nCtrl);
+
+    // When getting the selection:
+    uno::Reference<datatransfer::XTransferable> xTransferable = 
pModelObj->getSelection();
+
+    // Make sure we get A1+A3 instead of an error:
+    CPPUNIT_ASSERT(xTransferable.is());
+}
+
 }
 
 CPPUNIT_TEST_SUITE_REGISTRATION(ScTiledRenderingTest);
diff --git a/sc/source/ui/view/viewfun3.cxx b/sc/source/ui/view/viewfun3.cxx
index 502340a5bbf0..769805d5d32a 100644
--- a/sc/source/ui/view/viewfun3.cxx
+++ b/sc/source/ui/view/viewfun3.cxx
@@ -460,6 +460,14 @@ rtl::Reference<ScTransferObj> 
ScViewFunc::CopyToTransferable()
             return new ScTransferObj( std::move(pClipDoc), std::move(aObjDesc) 
);
         }
     }
+    else if (eMarkType == SC_MARK_MULTI)
+    {
+        ScDocumentUniquePtr pClipDoc(new ScDocument(SCDOCMODE_CLIP));
+        // This takes care of the input line and calls CopyToClipMultiRange() 
for us.
+        CopyToClip(pClipDoc.get(), /*bCut=*/false, /*bApi=*/true);
+        TransferableObjectDescriptor aObjDesc;
+        return new ScTransferObj(std::move(pClipDoc), std::move(aObjDesc));
+    }
 
     return nullptr;
 }

Reply via email to