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 589af9366078036c2f33e3254a628e267628352c
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Wed Oct 4 08:29:13 2023 +0200
Commit:     Caolán McNamara <caolan.mcnam...@collabora.com>
CommitDate: Thu Oct 5 20:53:45 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.
    
    (cherry picked from commit 89a75cd194371002247d0138e759835bc673f7b0)
    
    Change-Id: I379a26194da4d3a06241aa3c6f5ae78606f8fc12
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/157598
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com>
    Reviewed-by: Caolán McNamara <caolan.mcnam...@collabora.com>

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 6914ea8677b6..2a5fd2c08416 100644
--- a/sw/qa/filter/ww8/ww8.cxx
+++ b/sw/qa/filter/ww8/ww8.cxx
@@ -28,6 +28,7 @@
 #include <sortedobjs.hxx>
 #include <fmtwrapinfluenceonobjpos.hxx>
 #include <ftnidx.hxx>
+#include <tabfrm.hxx>
 
 namespace
 {
@@ -463,6 +464,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 0f8ab1f8ebc6..503437c8231b 100644
--- a/sw/source/filter/ww8/ww8par2.cxx
+++ b/sw/source/filter/ww8/ww8par2.cxx
@@ -3455,8 +3455,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;
             }
         }
     }
@@ -3474,7 +3474,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());
@@ -3499,9 +3499,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