diff options
author | Miklos Vajna <vmiklos@collabora.com> | 2023-10-04 08:29:13 +0200 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.com> | 2023-10-04 11:54:54 +0200 |
commit | 89a75cd194371002247d0138e759835bc673f7b0 (patch) | |
tree | 206f553c1c0bc13e3b200709711b2a08856c7dab | |
parent | 1ea27b7e35faf6619112bf3f1d69e4ec41c0bf23 (diff) |
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 <vmiklos@collabora.com>
Tested-by: Jenkins
-rw-r--r-- | sw/qa/filter/ww8/data/floattable-in-inlinetable.doc | bin | 0 -> 33792 bytes | |||
-rw-r--r-- | sw/qa/filter/ww8/ww8.cxx | 37 | ||||
-rw-r--r-- | sw/source/filter/ww8/ww8par2.cxx | 11 |
3 files changed, 44 insertions, 4 deletions
diff --git a/sw/qa/filter/ww8/data/floattable-in-inlinetable.doc b/sw/qa/filter/ww8/data/floattable-in-inlinetable.doc Binary files differnew file mode 100644 index 000000000000..a2f06973a53c --- /dev/null +++ b/sw/qa/filter/ww8/data/floattable-in-inlinetable.doc 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 |