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