desktop/qa/desktop_lib/test_desktop_lib.cxx | 20 ++++++++++++++++++++ desktop/source/lib/init.cxx | 2 ++ sfx2/sdi/sfx.sdi | 2 +- sw/source/uibase/shells/basesh.cxx | 9 ++++++++- 4 files changed, 31 insertions(+), 2 deletions(-)
New commits: commit 0f371db55f5e22a37ea3b15fe998461c0b1873b1 Author: Miklos Vajna <[email protected]> AuthorDate: Mon Nov 17 09:13:49 2025 +0100 Commit: Caolán McNamara <[email protected]> CommitDate: Mon Nov 17 16:07:36 2025 +0100 cool#13468 sw markdown paste: add UNO command parameter to skip the detection .uno:Paste tries to detect if the plain text content is really just plain text or markdown. There is no way to paste the clipboard content as plain text in a non-interactive way if the input looks like markdown. What happens is that .uno:Paste uses comphelper::IsMarkdownData() to guess if the input is markdown. This is fine in general, but if you want to paste "foo _bar_ baz" as-is, there is no .uno:Paste parameter to do so, you always get "foo <i>bar</i> baz". Fix the problem by adding a new SkipDetection parameter for .uno:Paste, while keeping the current behavior unchanged. The LOK API's doc_paste() function has an explicit mimetype parameter, so skip detection when using that API (a LOK client will use doc_setClipboard() when the user does a Ctrl-V, behavior there is unchanged). Note that an interactive way did exist previously: if you did paste special and selected plain text, that did work. Change-Id: I9888b1bf2322d3e1eeb32ffc8c8d08490b8eaa2c Reviewed-on: https://gerrit.libreoffice.org/c/core/+/194091 Tested-by: Jenkins CollaboraOffice <[email protected]> Tested-by: Caolán McNamara <[email protected]> Reviewed-by: Caolán McNamara <[email protected]> diff --git a/desktop/qa/desktop_lib/test_desktop_lib.cxx b/desktop/qa/desktop_lib/test_desktop_lib.cxx index 0186e9ba9e4e..62d20d72a668 100644 --- a/desktop/qa/desktop_lib/test_desktop_lib.cxx +++ b/desktop/qa/desktop_lib/test_desktop_lib.cxx @@ -761,6 +761,26 @@ void DesktopLOKTest::testPasteWriter() // Without the accompanying fix in place, this test would have failed, as we had a comment // between "foo" and "baz". CPPUNIT_ASSERT(!xTextPortionEnumeration->hasMoreElements()); + + // Overwrite the doc contents with an explicitly plain text paste. + pDocument->pClass->postUnoCommand(pDocument, ".uno:SelectAll", nullptr, false); + Scheduler::ProcessEventsToIdle(); + OString aPlainText("foo _bar_ baz"_ostr); + CPPUNIT_ASSERT(pDocument->pClass->paste(pDocument, "text/plain", aPlainText.getStr(), + aPlainText.getLength())); + + // Check if '_bar_' was pasted as-is. + xParagraphEnumeration = xParagraphEnumerationAccess->createEnumeration(); + xParagraph.set(xParagraphEnumeration->nextElement(), uno::UNO_QUERY); + xTextPortionEnumeration = xParagraph->createEnumeration(); + uno::Reference<text::XTextRange> xTextPortionRange(xTextPortionEnumeration->nextElement(), + uno::UNO_QUERY); + // Without the accompanying fix in place, this test would have failed with: + // - Expected: foo _bar_ baz + // - Actual : foo + // i.e. the text/plain input was parsed as markdown, while that should not happen when + // specifying the text/plain mimetype explicitly (and not text/markdown). + CPPUNIT_ASSERT_EQUAL(u"foo _bar_ baz"_ustr, xTextPortionRange->getString()); } void DesktopLOKTest::testPasteWriterJPEG() diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx index db1a475f24df..1adcb0c40f59 100644 --- a/desktop/source/lib/init.cxx +++ b/desktop/source/lib/init.cxx @@ -6296,6 +6296,8 @@ static bool doc_paste(LibreOfficeKitDocument* pThis, const char* pMimeType, cons { {"AnchorType", uno::Any(static_cast<sal_uInt16>(css::text::TextContentAnchorType_AS_CHARACTER))}, {"IgnoreComments", uno::Any(true)}, + // The MIME type is specified explicitly, don't guess. + {"SkipDetection", uno::Any(true)}, })); if (!comphelper::dispatchCommand(u".uno:Paste"_ustr, aPropertyValues)) { diff --git a/sfx2/sdi/sfx.sdi b/sfx2/sdi/sfx.sdi index 386384759574..a752fa601673 100644 --- a/sfx2/sdi/sfx.sdi +++ b/sfx2/sdi/sfx.sdi @@ -3168,7 +3168,7 @@ SfxTemplateItem ParaStyle SID_STYLE_FAMILY2 SfxVoidItem Paste SID_PASTE -(SfxUInt16Item AnchorType FN_PARAM_1, SfxBoolItem IgnoreComments FN_PARAM_2) +(SfxUInt16Item AnchorType FN_PARAM_1, SfxBoolItem IgnoreComments FN_PARAM_2, SfxBoolItem SkipDetection FN_PARAM_3) [ AutoUpdate = FALSE, FastCall = TRUE, diff --git a/sw/source/uibase/shells/basesh.cxx b/sw/source/uibase/shells/basesh.cxx index 419e9bfa9967..80fbf76879f6 100644 --- a/sw/source/uibase/shells/basesh.cxx +++ b/sw/source/uibase/shells/basesh.cxx @@ -376,7 +376,14 @@ void SwBaseShell::ExecClpbrd(SfxRequest &rReq) const SfxBoolItem* pIgnoreComments = rReq.GetArg<SfxBoolItem>(FN_PARAM_2); if (pIgnoreComments) bIgnoreComments = pIgnoreComments->GetValue(); - SwTransferable::Paste(rSh, aDataHelper, nAnchorType, bIgnoreComments, ePasteTable, true); + + // See if detection should be used. + bool bSkipDetection = false; + const SfxBoolItem* pSkipDetection = rReq.GetArg<SfxBoolItem>(FN_PARAM_3); + if (pSkipDetection) + bSkipDetection = pSkipDetection->GetValue(); + + SwTransferable::Paste(rSh, aDataHelper, nAnchorType, bIgnoreComments, ePasteTable, !bSkipDetection); if( rSh.IsFrameSelected() || rSh.IsObjSelected() ) rSh.EnterSelFrameMode();
