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

New commits:
commit 4d3d1e62003522201a0e6662a76f113c7b13d6ec
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Wed Apr 17 16:25:19 2024 +0200
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Thu Apr 18 17:13:14 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.
    
    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>
    (cherry picked from commit 1eda0a81fcf1bf2ce2fd4f29502eaa62879a50d4)
    
    Conflicts:
            sc/qa/unit/tiledrendering/tiledrendering.cxx
    
    Change-Id: I641d9db95ca391a4f39d96aeeb33422129262288
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/166256
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com>
    Reviewed-by: Miklos Vajna <vmik...@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 1e6294801caf..3a9ee97ee49a 100644
--- a/sc/qa/unit/tiledrendering/tiledrendering.cxx
+++ b/sc/qa/unit/tiledrendering/tiledrendering.cxx
@@ -3900,6 +3900,34 @@ CPPUNIT_TEST_FIXTURE(ScTiledRenderingTest, 
testEditShapeText)
     CPPUNIT_ASSERT_MESSAGE("Text is not visible", aBitmapBefore != 
aBitmapAfter);
 }
 
+CPPUNIT_TEST_FIXTURE(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_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/view/viewfun3.cxx b/sc/source/ui/view/viewfun3.cxx
index 30c5e0079ea5..aa8daeb8338f 100644
--- a/sc/source/ui/view/viewfun3.cxx
+++ b/sc/source/ui/view/viewfun3.cxx
@@ -458,6 +458,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