writerfilter/qa/cppunittests/dmapper/DomainMapper_Impl.cxx | 28 ++++++++++++ writerfilter/qa/cppunittests/dmapper/data/paste-ole.rtf | 30 +++++++++++++ writerfilter/source/dmapper/DomainMapper_Impl.cxx | 13 ++++- 3 files changed, 68 insertions(+), 3 deletions(-)
New commits: commit ce8b6f3426e55b6d09a52eb4a7d17614fc1a6c15 Author: Miklos Vajna <vmik...@collabora.com> AuthorDate: Mon Feb 7 16:02:51 2022 +0100 Commit: Miklos Vajna <vmik...@collabora.com> CommitDate: Tue Feb 8 07:35:13 2022 +0100 RTF paste: fix cursor creation on shapes This went wrong in commit 232ad2f2588beff50cb5c1f3b689c581ba317583 (API CHANGE: add a "position" parameter to XParagraph/TextPortionAppend methods, 2012-11-28), the problem is that the text range is part of the shape text's node range, so we have to call createTextCursorByRange() on the shape's XText, not on the body text. Change-Id: Ifa97213659130b8c279022a6a03f920dca6061bb Reviewed-on: https://gerrit.libreoffice.org/c/core/+/129603 Reviewed-by: Miklos Vajna <vmik...@collabora.com> Tested-by: Jenkins diff --git a/writerfilter/qa/cppunittests/dmapper/DomainMapper_Impl.cxx b/writerfilter/qa/cppunittests/dmapper/DomainMapper_Impl.cxx index c0468d9d55cc..962aa63f9ebc 100644 --- a/writerfilter/qa/cppunittests/dmapper/DomainMapper_Impl.cxx +++ b/writerfilter/qa/cppunittests/dmapper/DomainMapper_Impl.cxx @@ -20,6 +20,7 @@ #include <com/sun/star/text/XTextTable.hpp> #include <com/sun/star/lang/XServiceInfo.hpp> #include <com/sun/star/style/XStyleFamiliesSupplier.hpp> +#include <com/sun/star/document/XDocumentInsertable.hpp> #include <vcl/scheduler.hxx> @@ -256,6 +257,33 @@ CPPUNIT_TEST_FIXTURE(Test, testPTab) // visually inside the background shape. CPPUNIT_ASSERT_EQUAL(OUString(" \n1" SAL_NEWLINE_STRING), xFooter->getString()); } + +CPPUNIT_TEST_FIXTURE(Test, testPasteOle) +{ + // Given an empty document: + getComponent() = loadFromDesktop("private:factory/swriter", "com.sun.star.text.TextDocument"); + + // When pasting RTF into that document: + uno::Reference<text::XTextDocument> xTextDocument(getComponent(), uno::UNO_QUERY); + uno::Reference<text::XText> xText = xTextDocument->getText(); + uno::Reference<document::XDocumentInsertable> xCursor( + xText->createTextCursorByRange(xText->getStart()), uno::UNO_QUERY); + OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "paste-ole.rtf"; + xCursor->insertDocumentFromURL(aURL, {}); + + // Then make sure that all the 3 paragraphs of the paste data (empty para, OLE obj, text) are + // inserted to the document: + uno::Reference<container::XEnumerationAccess> xParaEnumAccess(xText, uno::UNO_QUERY); + uno::Reference<container::XEnumeration> xParaEnum = xParaEnumAccess->createEnumeration(); + xParaEnum->nextElement(); + // Without the accompanying fix in place, this test would have failed, as the paste result was a + // single paragaph, containing the OLE object, and the content after the OLE object was lost. + CPPUNIT_ASSERT(xParaEnum->hasMoreElements()); + xParaEnum->nextElement(); + CPPUNIT_ASSERT(xParaEnum->hasMoreElements()); + uno::Reference<text::XTextRange> xPara(xParaEnum->nextElement(), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(OUString("hello"), xPara->getString()); +} } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/qa/cppunittests/dmapper/data/paste-ole.rtf b/writerfilter/qa/cppunittests/dmapper/data/paste-ole.rtf new file mode 100644 index 000000000000..27ce59baa50b --- /dev/null +++ b/writerfilter/qa/cppunittests/dmapper/data/paste-ole.rtf @@ -0,0 +1,30 @@ +{\rtf1 +\pard\plain\par +\pard\plain +{\object\objemb\objw1287\objh832\objscalex100\objscaley99 +{\*\objclass Package} +{\*\objdata 0105000002000000080000005061636b616765000000000000000000eb010000 +020030322e73766700443a5c446e445c54657374646174656e5c416c6c654461746569547970656e5c30322e737667000000030036000000443a5c54454d505c7b42433241443335362d363732422d344345302d394136342d3033373544464134324334377d5c30322e73766700ab0000003c7376672076657273696f6e +3d22312e31222076696577426f783d223020302034342032362220786d6c6e733d22687474703a2f2f7777772e77332e6f72672f323030302f737667223e0a203c7265637420783d222e352220793d222e35222077696474683d22343322206865696768743d223235222072783d2232222072793d2232222066696c6c3d +222366666622207374726f6b653d2223303037616666222f3e0a3c2f7376673e0a3500000044003a005c00540045004d0050005c007b00420043003200410044003300350036002d0036003700320042002d0034004300450030002d0039004100360034002d003000330037003500440046004100340032004300340037 +007d005c00300032002e0073007600670006000000300032002e007300760067002600000044003a005c0044006e0044005c00540065007300740064006100740065006e005c0041006c006c0065004400610074006500690054007900700065006e005c00300032002e007300760067000105000000000000} +{\result +{\*\shppict +{\pict +\picscalex100\picscaley99\picw2270\pich1468\picwgoal1287\pichgoal832\emfblip +010000006c00000000000000000000009500000095000000000000000000 +0000670f0000630f000020454d4600000100280100000700000002000000 +00000000000000000000000038070000bd030000e9010000fd0000000000 +00000000000000000000f675070016dd0300210000000800000062000000 +0c0000000100000027000000180000000100000000000000ff0000000000 +000047000000700000000000000000000000950000009500000050000000 +010000002000000001000000030000003000000000000000000000009600 +000096000000320000000000000064000000320000000000000032000000 +960000006400000032000000640000006400000096000000220000000c00 +0000ffffffff0e00000014000000000000001000000014000000} +} +} +} +\pard\plain\par +\pard\plain hello\par +} diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx b/writerfilter/source/dmapper/DomainMapper_Impl.cxx index 87c954bbe9ca..99aefa3b1b09 100644 --- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx +++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx @@ -3566,10 +3566,17 @@ void DomainMapper_Impl::PushShapeContext( const uno::Reference< drawing::XShape } else { - uno::Reference< text::XTextRange > xShapeText( xShape, uno::UNO_QUERY_THROW); + uno::Reference<text::XTextRange> xShapeTextRange(xShape, uno::UNO_QUERY_THROW); // Add the shape to the text append stack - m_aTextAppendStack.push( TextAppendContext(uno::Reference< text::XTextAppend >( xShape, uno::UNO_QUERY_THROW ), - m_bIsNewDoc ? uno::Reference<text::XTextCursor>() : m_xBodyText->createTextCursorByRange(xShapeText->getStart() ))); + uno::Reference<text::XTextAppend> xShapeTextAppend(xShape, uno::UNO_QUERY_THROW); + uno::Reference<text::XTextCursor> xTextCursor; + if (!m_bIsNewDoc) + { + xTextCursor = xShapeTextRange->getText()->createTextCursorByRange( + xShapeTextRange->getStart()); + } + TextAppendContext aContext(xShapeTextAppend, xTextCursor); + m_aTextAppendStack.push(aContext); // Add the shape to the anchored objects stack uno::Reference< text::XTextContent > xTxtContent( xShape, uno::UNO_QUERY_THROW );