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 7fc935ba4cd714eda0666afc9595cdd0690cecf4 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 13:56:11 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. (cherry picked from commit ce8b6f3426e55b6d09a52eb4a7d17614fc1a6c15) Conflicts: writerfilter/qa/cppunittests/dmapper/DomainMapper_Impl.cxx Change-Id: Ifa97213659130b8c279022a6a03f920dca6061bb diff --git a/writerfilter/qa/cppunittests/dmapper/DomainMapper_Impl.cxx b/writerfilter/qa/cppunittests/dmapper/DomainMapper_Impl.cxx index ade216411c54..d78c5bb05fd6 100644 --- a/writerfilter/qa/cppunittests/dmapper/DomainMapper_Impl.cxx +++ b/writerfilter/qa/cppunittests/dmapper/DomainMapper_Impl.cxx @@ -14,6 +14,7 @@ #include <com/sun/star/text/XTextDocument.hpp> #include <com/sun/star/beans/XPropertySet.hpp> #include <com/sun/star/style/BreakType.hpp> +#include <com/sun/star/document/XDocumentInsertable.hpp> using namespace ::com::sun::star; @@ -104,6 +105,33 @@ CPPUNIT_TEST_FIXTURE(Test, testNumberingRestartStyleParent) xPara.set(xParaEnum->nextElement(), uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(OUString("2."), xPara->getPropertyValue(aProp).get<OUString>()); } + +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 a52151a60c0e..8e3a6c1ad9dd 100644 --- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx +++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx @@ -2911,10 +2911,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 );