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 );

Reply via email to