diff options
author | Miklos Vajna <vmiklos@collabora.com> | 2022-02-07 16:02:51 +0100 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.com> | 2022-02-08 07:35:13 +0100 |
commit | ce8b6f3426e55b6d09a52eb4a7d17614fc1a6c15 (patch) | |
tree | c8e08721bdd07550706d0e2349f38d34ef71d0f7 /writerfilter | |
parent | a7c9980a4a6bb1f547c0c4a7b554ac9afe7b25fc (diff) |
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 <vmiklos@collabora.com>
Tested-by: Jenkins
Diffstat (limited to 'writerfilter')
3 files changed, 68 insertions, 3 deletions
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 ); |