summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.com>2024-04-19 08:51:34 +0200
committerMiklos Vajna <vmiklos@collabora.com>2024-04-19 17:14:37 +0200
commit4ffe06a81866a2c9f8598d194e04c114cc083119 (patch)
treece9335c961fff582c2dfd9e0439c8359267ba3e7
parent78bd5e2523d077a67468b752d4788a2c3b43fb5f (diff)
cool#8789 sc lok: fix copy for multi-selections HEADmaster
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 <vmiklos@collabora.com> Tested-by: Jenkins
-rw-r--r--sc/qa/unit/tiledrendering2/data/multi-selection.odsbin0 -> 8400 bytes
-rw-r--r--sc/qa/unit/tiledrendering2/tiledrendering2.cxx45
-rw-r--r--sc/source/ui/view/viewfun3.cxx8
3 files changed, 53 insertions, 0 deletions
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
--- /dev/null
+++ b/sc/qa/unit/tiledrendering2/data/multi-selection.ods
Binary files 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;
}