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