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 78b1631e9649402e29c906c7023f55ed2cbe84f9
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Thu Mar 9 08:00:44 2023 +0100
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Thu Mar 9 08:21:29 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.
    
    Change-Id: Ie37be61443a274f408e1124983d1d495de5636c8
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/148521
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>
    Tested-by: Jenkins

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:

Reply via email to