sw/qa/extras/ooxmlexport/data/tdf164500_framePrBeforeTable.docx |binary
 sw/qa/extras/ooxmlexport/ooxmlexport18.cxx                      |   12 ++++
 sw/source/writerfilter/dmapper/DomainMapper_Impl.cxx            |   29 
++++++++++
 3 files changed, 41 insertions(+)

New commits:
commit 575094675e7f6fb643e8cac61f06c14d2f79bcd5
Author:     Justin Luth <justin.l...@collabora.com>
AuthorDate: Tue Jan 14 18:25:48 2025 -0500
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Thu Jan 16 09:17:51 2025 +0100

    tdf#164500 docx import framePr: add blank para as anchor before table
    
    In my unit test there is a "problem"
    because the added paragraph wraps below the frame
    and thus pushes the content down an extra line (compared to MS Word).
    But if the frame was not autosized (full width),
    then the added paragraph would wrap around behind it perfectly.
    This is emulation (since we can't anchor to a table start node),
    so it will have to be good enough.
    
    make CppunitTest_sw_ooxmlexport18 \
        CPPUNIT_TEST_NAME=testTdf164500_framePrBeforeTable
    
    Change-Id: I1318dbacf853fb7d08c988e48dda7ac20c9498ab
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/179492
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>
    Reviewed-by: Justin Luth <jl...@mail.com>
    Tested-by: Jenkins

diff --git a/sw/qa/extras/ooxmlexport/data/tdf164500_framePrBeforeTable.docx 
b/sw/qa/extras/ooxmlexport/data/tdf164500_framePrBeforeTable.docx
new file mode 100644
index 000000000000..d9c7fbb2544a
Binary files /dev/null and 
b/sw/qa/extras/ooxmlexport/data/tdf164500_framePrBeforeTable.docx differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport18.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport18.cxx
index 65f78c7779d4..9b21067e9dc0 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport18.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport18.cxx
@@ -192,6 +192,18 @@ DECLARE_OOXMLEXPORT_TEST(testTdf104394_lostTextbox, 
"tdf104394_lostTextbox.docx"
     CPPUNIT_ASSERT_EQUAL(2, getPages());
 }
 
+DECLARE_OOXMLEXPORT_TEST(testTdf164500_framePrBeforeTable, 
"tdf164500_framePrBeforeTable.docx")
+{
+    // Should be only one page (but was two because the frame was anchored 
inside cell A1,
+    // and thus the width was limited by the cell width. It must be anchored 
before the table.
+    CPPUNIT_ASSERT_EQUAL(1, getPages());
+    CPPUNIT_ASSERT_EQUAL(1, getShapes()); // one text frame
+
+    uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, 
uno::UNO_QUERY_THROW);
+    uno::Reference<container::XIndexAccess> 
xTables(xTablesSupplier->getTextTables(), uno::UNO_QUERY_THROW);
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(3), xTables->getCount());
+}
+
 DECLARE_OOXMLEXPORT_TEST(testTdf146984_anchorInShape, 
"tdf146984_anchorInShape.docx")
 {
     // This was only one page b/c the page break was missing.
diff --git a/sw/source/writerfilter/dmapper/DomainMapper_Impl.cxx 
b/sw/source/writerfilter/dmapper/DomainMapper_Impl.cxx
index 0458e8a1c83e..b7e6c0828b94 100644
--- a/sw/source/writerfilter/dmapper/DomainMapper_Impl.cxx
+++ b/sw/source/writerfilter/dmapper/DomainMapper_Impl.cxx
@@ -2565,6 +2565,35 @@ void DomainMapper_Impl::finishParagraph( const 
PropertyMapPtr& pPropertyMap, con
 
                         CheckUnregisteredFrameConversion(bPreventOverlap);
 
+                        // If a table is starting and the table itself is not 
framed (!bIsFrameMode)
+                        // but the paragraph before the table needs to be 
(m_xFrameEndRange.is())
+                        // then an empty paragraph is needed after the 
to-be-converted-to-frame
+                        // paragraphs in order for the new frame to be 
anchored before the table.
+                        // That is because convertToTextFrame just points the 
anchor to the node
+                        // where the moved-to-frame paragraphs were,
+                        // and these paragraphs-that-will-become-table-cells
+                        // are going to end up at that node.
+                        // Thus a blank node needs to be inserted after the 
to-be-deleted nodes,
+                        // since LO cannot anchor a frame to a table node 
itself (which Word does).
+                        if (!bIsFrameMode && m_xFrameEndRange.is()
+                            && m_StreamStateStack.top().nTableCellDepth > 0
+                            && hasTableManager() && 
!getTableManager().isInTable())
+                        {
+                            uno::Reference<text::XTextCursor> xCursor
+                                = 
xTextAppend->createTextCursorByRange(m_xFrameEndRange);
+                            xTextAppend->insertControlCharacter(
+                                xCursor, 
text::ControlCharacter::APPEND_PARAGRAPH,
+                                /*bAbsorb*/false);
+
+                            // remove any inherited properties from the 
placeholder anchor-paragraph
+                            uno::Reference<beans::XMultiPropertyStates> 
xMPS(xCursor,
+                                                                             
uno::UNO_QUERY);
+                            xMPS->setAllPropertiesToDefault();
+                            uno::Reference<beans::XPropertySet> xPS(xCursor, 
uno::UNO_QUERY);
+                            xPS->setPropertyValue(u"ParaStyleName"_ustr,
+                                                  uno::Any(u"Standard"_ustr));
+                        }
+
                         // If different frame properties are set on this 
paragraph, keep them.
                         if (!bIsDropCap && bIsFrameMode)
                         {

Reply via email to