sw/qa/core/layout/data/floattable-widow.docx |binary sw/qa/core/layout/flycnt.cxx | 50 +++++++++++++++++++++++++++ sw/source/core/text/widorp.cxx | 13 ++++++- 3 files changed, 62 insertions(+), 1 deletion(-)
New commits: commit 84cf61a9d44edcc9574417e2eb74ea9916fef772 Author: Miklos Vajna <vmik...@collabora.com> AuthorDate: Thu Mar 9 08:00:44 2023 +0100 Commit: Miklos Vajna <vmik...@collabora.com> CommitDate: Fri Mar 10 09:36:41 2023 +0000 sw floattable: enable widow / orphan control in split rows The bugdoc has a single table cell, and widow control is meant to move the last 2 lines to the second page, but only one page was moved there. The problem is that widow / orphan control was completely disabled inside split table rows, but Word does this. We know when a table comes from a Word document, so in that case enable widow / orphan control inside split rows as well. Do this only for in-fly tables for now, doing this in general would need more work, as pointed out by CppunitTest_sw_layoutwriter's testForcepoint76. It is an RTF file that doesn't open in Word, but we would layout-loop on it if this would be enabled in general right now. (cherry picked from commit 78b1631e9649402e29c906c7023f55ed2cbe84f9) Change-Id: Ie37be61443a274f408e1124983d1d495de5636c8 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/148596 Tested-by: Miklos Vajna <vmik...@collabora.com> Reviewed-by: Miklos Vajna <vmik...@collabora.com> diff --git a/sw/qa/core/layout/data/floattable-widow.docx b/sw/qa/core/layout/data/floattable-widow.docx new file mode 100644 index 000000000000..4a70c942c976 Binary files /dev/null and b/sw/qa/core/layout/data/floattable-widow.docx differ diff --git a/sw/qa/core/layout/flycnt.cxx b/sw/qa/core/layout/flycnt.cxx index 254a316886c7..ee3f38537aca 100644 --- a/sw/qa/core/layout/flycnt.cxx +++ b/sw/qa/core/layout/flycnt.cxx @@ -420,6 +420,56 @@ CPPUNIT_TEST_FIXTURE(Test, testSplitFly2Cols) // 2nd half of the split row and the very last row went to a 3rd page. CPPUNIT_ASSERT(!pPage2->GetNext()); } + +CPPUNIT_TEST_FIXTURE(Test, testSplitFlyWidow) +{ + // Given a document with a 2nd page that contains 2 lines, due to widow control: + std::shared_ptr<comphelper::ConfigurationChanges> pChanges( + comphelper::ConfigurationChanges::create()); + officecfg::Office::Writer::Filter::Import::DOCX::ImportFloatingTableAsSplitFly::set(true, + pChanges); + pChanges->commit(); + comphelper::ScopeGuard g([pChanges] { + officecfg::Office::Writer::Filter::Import::DOCX::ImportFloatingTableAsSplitFly::set( + false, pChanges); + pChanges->commit(); + }); + createSwDoc("floattable-widow.docx"); + + // When laying out that document: + calcLayout(); + + // Then make sure that widow control works: + SwDoc* pDoc = getSwDoc(); + SwRootFrame* pLayout = pDoc->getIDocumentLayoutAccess().GetCurrentLayout(); + auto pPage1 = dynamic_cast<SwPageFrame*>(pLayout->Lower()); + CPPUNIT_ASSERT(pPage1); + const SwSortedObjs& rPage1Objs = *pPage1->GetSortedObjs(); + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), rPage1Objs.size()); + auto pPage1Fly = dynamic_cast<SwFlyAtContentFrame*>(rPage1Objs[0]); + CPPUNIT_ASSERT(pPage1Fly); + SwFrame* pTab1 = pPage1Fly->GetLower(); + SwFrame* pRow1 = pTab1->GetLower(); + SwFrame* pCell1 = pRow1->GetLower(); + auto pText1 = dynamic_cast<SwTextFrame*>(pCell1->GetLower()); + // Without the accompanying fix in place, this test would have failed with: + // - Expected: 6 + // - Actual : 7 + // i.e. widow control was disabled, layout didn't match Word. + CPPUNIT_ASSERT_EQUAL(static_cast<sal_uLong>(6), pText1->GetThisLines()); + auto pPage2 = dynamic_cast<SwPageFrame*>(pPage1->GetNext()); + CPPUNIT_ASSERT(pPage2); + const SwSortedObjs& rPage2Objs = *pPage2->GetSortedObjs(); + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), rPage2Objs.size()); + auto pPage2Fly = dynamic_cast<SwFlyAtContentFrame*>(rPage2Objs[0]); + CPPUNIT_ASSERT(pPage2Fly); + SwFrame* pTab2 = pPage2Fly->GetLower(); + SwFrame* pRow2 = pTab2->GetLower(); + SwFrame* pCell2 = pRow2->GetLower(); + auto pText2 = dynamic_cast<SwTextFrame*>(pCell2->GetLower()); + // And then similarly this was 1, not 2. + CPPUNIT_ASSERT_EQUAL(static_cast<sal_uLong>(2), pText2->GetThisLines()); +} } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/core/text/widorp.cxx b/sw/source/core/text/widorp.cxx index a89751f736da..596307e61384 100644 --- a/sw/source/core/text/widorp.cxx +++ b/sw/source/core/text/widorp.cxx @@ -36,6 +36,7 @@ #include <sectfrm.hxx> #include <ftnfrm.hxx> #include <pagefrm.hxx> +#include <IDocumentSettingAccess.hxx> #undef WIDOWTWIPS @@ -309,7 +310,17 @@ WidowsAndOrphans::WidowsAndOrphans( SwTextFrame *pNewFrame, const SwTwips nRst, bool bResetFlags = false; - if ( m_pFrame->IsInTab() ) + bool bWordTableCell = false; + if (m_pFrame->IsInFly()) + { + // Enable widow / orphan control in Word-style table cells in split rows, at least inside + // flys. + const SwDoc& rDoc = m_pFrame->GetTextNodeForParaProps()->GetDoc(); + const IDocumentSettingAccess& rIDSA = rDoc.getIDocumentSettingAccess(); + bWordTableCell = rIDSA.get(DocumentSettingId::TABLE_ROW_KEEP); + } + + if ( m_pFrame->IsInTab() && !bWordTableCell ) { // For compatibility reasons, we disable Keep/Widows/Orphans // inside splittable row frames: