sw/qa/filter/ww8/data/floattable-in-inlinetable.doc |binary
 sw/qa/filter/ww8/ww8.cxx                            |   37 ++++++++++++++++++++
 sw/source/filter/ww8/ww8par2.cxx                    |   11 +++--
 3 files changed, 44 insertions(+), 4 deletions(-)

New commits:
commit 89a75cd194371002247d0138e759835bc673f7b0
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Wed Oct 4 08:29:13 2023 +0200
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Wed Oct 4 11:54:54 2023 +0200

    tdf#126449 sw floattable: DOC import: handle inner floating table
    
    One problem with the bugdoc is that the inner floating tables in the DOC
    file stay in a single page.
    
    Seems the usual to-para anchoring + allow-to-split logic is not used
    here, because the toplevel table is handled at
    SwWW8ImplReader::StartApo(), but the inner table is handled in
    SwWW8ImplReader::StartTable(). Additionally, the toplevel table is
    anchored to-para (which seems to be the closest to Word's "position this
    table based on the next paragraph" concept), but the inner table was
    anchored to-char, and such fly frames can't split.
    
    Fix the problem by switching to to-para anchoring even for inner
    floating tables. This improves consistency with toplevel floatint tables
    from DOC and all floating tables from DOCX. It seems to the to-char
    anchor type was added in commit 10f352d2faf6a4d72337b2c098a65377eee5138b
    (INTEGRATION: CWS swqbugfixes18 (1.111.60); FILE MERGED, 2005-03-30),
    but there the motivation was to make sure these are not inline; so that
    use-case keeps working.
    
    This does fix the overlapping text with the original bugdoc, but
    otherwise the DOCX version is still slightly closer to the Word render
    result.
    
    Change-Id: I379a26194da4d3a06241aa3c6f5ae78606f8fc12
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/157550
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>
    Tested-by: Jenkins

diff --git a/sw/qa/filter/ww8/data/floattable-in-inlinetable.doc 
b/sw/qa/filter/ww8/data/floattable-in-inlinetable.doc
new file mode 100644
index 000000000000..a2f06973a53c
Binary files /dev/null and 
b/sw/qa/filter/ww8/data/floattable-in-inlinetable.doc differ
diff --git a/sw/qa/filter/ww8/ww8.cxx b/sw/qa/filter/ww8/ww8.cxx
index 14cde1758588..ebd4e3d38d36 100644
--- a/sw/qa/filter/ww8/ww8.cxx
+++ b/sw/qa/filter/ww8/ww8.cxx
@@ -29,6 +29,7 @@
 #include <sortedobjs.hxx>
 #include <fmtwrapinfluenceonobjpos.hxx>
 #include <ftnidx.hxx>
+#include <tabfrm.hxx>
 
 namespace
 {
@@ -488,6 +489,42 @@ CPPUNIT_TEST_FIXTURE(Test, testFloattableFootnote)
     // - Actual  : 0
     CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), rFootnotes.size());
 }
+
+CPPUNIT_TEST_FIXTURE(Test, testSplitFlyInInlineTableDOC)
+{
+    // Outer inline table on pages 1 -> 2 -> 3, inner floating table on pages 
2 -> 3:
+    // When laying out that document:
+    createSwDoc("floattable-in-inlinetable.doc");
+
+    SwDoc* pDoc = getSwDoc();
+    SwRootFrame* pLayout = pDoc->getIDocumentLayoutAccess().GetCurrentLayout();
+    auto pPage1 = pLayout->Lower()->DynCastPageFrame();
+    CPPUNIT_ASSERT(pPage1);
+    {
+        SwFrame* pBody = pPage1->FindBodyCont();
+        auto pTab = pBody->GetLower()->DynCastTabFrame();
+        CPPUNIT_ASSERT(!pTab->GetPrecede());
+        CPPUNIT_ASSERT(pTab->GetFollow());
+    }
+    auto pPage2 = pPage1->GetNext()->DynCastPageFrame();
+    CPPUNIT_ASSERT(pPage2);
+    {
+        SwFrame* pBody = pPage2->FindBodyCont();
+        auto pTab = pBody->GetLower()->DynCastTabFrame();
+        CPPUNIT_ASSERT(pTab->GetPrecede());
+        // Without the accompanying fix in place, this test would have failed, 
the outer table was
+        // missing on page 3.
+        CPPUNIT_ASSERT(pTab->GetFollow());
+    }
+    auto pPage3 = pPage2->GetNext()->DynCastPageFrame();
+    CPPUNIT_ASSERT(pPage3);
+    {
+        SwFrame* pBody = pPage3->FindBodyCont();
+        auto pTab = pBody->GetLower()->DynCastTabFrame();
+        CPPUNIT_ASSERT(pTab->GetPrecede());
+        CPPUNIT_ASSERT(!pTab->GetFollow());
+    }
+}
 }
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sw/source/filter/ww8/ww8par2.cxx b/sw/source/filter/ww8/ww8par2.cxx
index 6c18f5a9ce08..4cc4f8379b58 100644
--- a/sw/source/filter/ww8/ww8par2.cxx
+++ b/sw/source/filter/ww8/ww8par2.cxx
@@ -3419,8 +3419,8 @@ bool SwWW8ImplReader::StartTable(WW8_CP nStartCp)
                     m_aSectionManager.GetTextAreaWidth(),
                     m_nIniFlyDx, m_nIniFlyDy);
 
-                // #i45301# - anchor nested table Writer fly frame at-character
-                eAnchor = RndStdIds::FLY_AT_CHAR;
+                // #i45301# - anchor nested table Writer fly frame
+                eAnchor = RndStdIds::FLY_AT_PARA;
             }
         }
     }
@@ -3438,7 +3438,7 @@ bool SwWW8ImplReader::StartTable(WW8_CP nStartCp)
     {
         int nNewInTable = m_nInTable + 1;
 
-        if ((eAnchor == RndStdIds::FLY_AT_CHAR)
+        if ((eAnchor == RndStdIds::FLY_AT_PARA)
             && !m_aTableStack.empty() && !InEqualApo(nNewInTable) )
         {
             m_xTableDesc->m_pParentPos = new SwPosition(*m_pPaM->GetPoint());
@@ -3463,9 +3463,12 @@ bool SwWW8ImplReader::StartTable(WW8_CP nStartCp)
             if ( pTableWFlyPara && pTableSFlyPara )
             {
                 WW8FlySet aFlySet( *this, pTableWFlyPara.get(), 
pTableSFlyPara, false );
-                SwFormatAnchor aAnchor( RndStdIds::FLY_AT_CHAR );
+                // At-para, so it can split in the multi-page case.
+                SwFormatAnchor aAnchor(RndStdIds::FLY_AT_PARA);
                 aAnchor.SetAnchor( m_xTableDesc->m_pParentPos );
                 aFlySet.Put( aAnchor );
+                // Map a positioned inner table to a split fly.
+                aFlySet.Put(SwFormatFlySplit(true));
                 m_xTableDesc->m_pFlyFormat->SetFormatAttr( aFlySet );
             }
             else

Reply via email to