sc/qa/unit/tiledrendering2/data/multi-selection.ods |binary sc/qa/unit/tiledrendering2/tiledrendering2.cxx | 45 ++++++++++++++++++++ sc/source/ui/view/viewfun3.cxx | 8 +++ 3 files changed, 53 insertions(+)
New commits: commit 4ffe06a81866a2c9f8598d194e04c114cc083119 Author: Miklos Vajna <vmik...@collabora.com> AuthorDate: Fri Apr 19 08:51:34 2024 +0200 Commit: Miklos Vajna <vmik...@collabora.com> CommitDate: Fri Apr 19 17:14:37 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/+/166279 Reviewed-by: Miklos Vajna <vmik...@collabora.com> Tested-by: Jenkins diff --git a/sc/qa/unit/tiledrendering2/data/multi-selection.ods b/sc/qa/unit/tiledrendering2/data/multi-selection.ods new file mode 100644 index 000000000000..9436aaf93c26 Binary files /dev/null and b/sc/qa/unit/tiledrendering2/data/multi-selection.ods differ diff --git a/sc/qa/unit/tiledrendering2/tiledrendering2.cxx b/sc/qa/unit/tiledrendering2/tiledrendering2.cxx index 058e7deb0883..65a85c685b33 100644 --- a/sc/qa/unit/tiledrendering2/tiledrendering2.cxx +++ b/sc/qa/unit/tiledrendering2/tiledrendering2.cxx @@ -17,6 +17,8 @@ #include <sfx2/lokhelper.hxx> #include <test/lokcallback.hxx> #include <vcl/scheduler.hxx> +#include <comphelper/propertyvalue.hxx> +#include <comphelper/string.hxx> #include <docuno.hxx> @@ -79,6 +81,7 @@ class ViewCallback final public: std::map<std::string, boost::property_tree::ptree> m_aStateChanges; + tools::Rectangle m_aCellCursorBounds; TestLokCallbackWrapper m_callbackWrapper; ViewCallback() @@ -108,6 +111,20 @@ public: { switch (nType) { + case LOK_CALLBACK_CELL_CURSOR: + { + uno::Sequence<OUString> aSeq = comphelper::string::convertCommaSeparated( + OUString::createFromAscii(pPayload)); + m_aCellCursorBounds = tools::Rectangle(); + if (aSeq.getLength() >= 4) + { + m_aCellCursorBounds.SetLeft(aSeq[0].toInt32()); + m_aCellCursorBounds.SetTop(aSeq[1].toInt32()); + m_aCellCursorBounds.setWidth(aSeq[2].toInt32()); + m_aCellCursorBounds.setHeight(aSeq[3].toInt32()); + } + } + break; case LOK_CALLBACK_STATE_CHANGED: { std::stringstream aStream(pPayload); @@ -159,6 +176,34 @@ CPPUNIT_TEST_FIXTURE(Test, testSidebarLocale) std::string aLocale = it->second.get<std::string>("locale"); CPPUNIT_ASSERT_EQUAL(std::string("de-DE"), aLocale); } + +CPPUNIT_TEST_FIXTURE(Test, 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(); diff --git a/sc/source/ui/view/viewfun3.cxx b/sc/source/ui/view/viewfun3.cxx index ee2cccf72f35..1c918ff1c04d 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; }