summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.com>2023-10-04 08:29:13 +0200
committerMiklos Vajna <vmiklos@collabora.com>2023-10-04 11:54:54 +0200
commit89a75cd194371002247d0138e759835bc673f7b0 (patch)
tree206f553c1c0bc13e3b200709711b2a08856c7dab
parent1ea27b7e35faf6619112bf3f1d69e4ec41c0bf23 (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.docbin0 -> 33792 bytes
-rw-r--r--sw/qa/filter/ww8/ww8.cxx37
-rw-r--r--sw/source/filter/ww8/ww8par2.cxx11
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
new file mode 100644
index 000000000000..a2f06973a53c
--- /dev/null
+++ b/sw/qa/filter/ww8/data/floattable-in-inlinetable.doc
Binary files 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