sw/qa/extras/ooxmlexport/data/tdf123116_oversizedRowSplit.odt |binary
 sw/qa/extras/ooxmlexport/ooxmlexport14.cxx                    |    7 +++
 sw/source/core/inc/rowfrm.hxx                                 |    3 +
 sw/source/core/layout/tabfrm.cxx                              |   23 +++++++++-
 4 files changed, 31 insertions(+), 2 deletions(-)

New commits:
commit 1cd581c1e6ed31edd2fac83ce2901c91efeb5cd1
Author:     Justin Luth <justin.l...@collabora.com>
AuthorDate: Wed Mar 4 16:31:14 2020 +0300
Commit:     Michael Stahl <michael.st...@allotropia.de>
CommitDate: Fri Jun 20 18:28:29 2025 +0200

    tdf#123116 sw layout: allow rows larger than page to split anyway
    
    Even if the row is set to not allow splitting across pages,
    ignore that setting if the row is too big to fit on a single page.
    Don't worry too much about compatibility, because there is no
    sensible reason why anyone would have hidden content like this
    intentionally.
    
    An oversized row has always moved to start a new page. While that may
    not strictly be necessary anymore, to approximate a bit of backward
    compatibility, continue to do that. MS Word will do the same...
    
    Word, prior to 2013, always tries to keep the whole row on
    one page. In 2013 (compatibleMode == 15), native documents
    will be treated like this patch. So, although this patch
    throws away senseless compatibility with existing documents,
    it is interoperable with anything authored by Word >= 2013.
    Word 2013/2016 also opens .odt files this way.
    
    HOWEVER, LO authored .docx files do not set compatibleMode=15,
    so Word will treat them the old way - hiding all the content
    on a single page.
    
    Change-Id: I306e22230ed6fe21f6b66700ffd7615678859f5d
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/90005
    Tested-by: Jenkins
    Reviewed-by: Justin Luth <justin_l...@sil.org>
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>
    (cherry picked from commit b271cc46851c61ddef20dc869bf339c857f76b18)

diff --git a/sw/qa/extras/ooxmlexport/data/tdf123116_oversizedRowSplit.odt 
b/sw/qa/extras/ooxmlexport/data/tdf123116_oversizedRowSplit.odt
new file mode 100644
index 000000000000..aafc27ae2260
Binary files /dev/null and 
b/sw/qa/extras/ooxmlexport/data/tdf123116_oversizedRowSplit.odt differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport14.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport14.cxx
index d7f9df7eaeb7..f7a1007d3320 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport14.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport14.cxx
@@ -198,6 +198,13 @@ DECLARE_OOXMLEXPORT_TEST(testTdf108350_noFontdefaults, 
"tdf108350_noFontdefaults
     //CPPUNIT_ASSERT_EQUAL_MESSAGE("Font size", 10.f, 
getProperty<float>(xStyleProps, "CharHeight"));
 }
 
+DECLARE_OOXMLEXPORT_TEST(testTdf123116_oversizedRowSplit, 
"tdf123116_oversizedRowSplit.odt")
+{
+    // For highest backward compatibility and interoperability, the 
now-splitable-row
+    // should start on a new page.
+    CPPUNIT_ASSERT_EQUAL_MESSAGE("Row splits over 5 pages", 5, getPages());
+}
+
 DECLARE_OOXMLIMPORT_TEST(testTdf125038, "tdf125038.docx")
 {
     OUString aActual = getParagraph(1)->getString();
diff --git a/sw/source/core/inc/rowfrm.hxx b/sw/source/core/inc/rowfrm.hxx
index 3786d00f8347..e131730c20e6 100644
--- a/sw/source/core/inc/rowfrm.hxx
+++ b/sw/source/core/inc/rowfrm.hxx
@@ -43,6 +43,7 @@ class SwRowFrame: public SwLayoutFrame
     bool m_bIsRepeatedHeadline;
     bool m_bIsRowSpanLine;
 
+    bool m_bForceRowSplitAllowed;
     bool m_bIsInSplit;
 
     virtual void DestroyImpl() override;
@@ -90,6 +91,8 @@ public:
 
     // --> split table rows
     bool IsRowSplitAllowed() const;
+    bool IsForceRowSplitAllowed() const { return m_bForceRowSplitAllowed; }
+    void SetForceRowSplitAllowed( bool bNew) { m_bForceRowSplitAllowed = bNew; 
};
     bool IsFollowFlowRow() const { return m_bIsFollowFlowRow; }
     void SetFollowFlowRow( bool bNew ) { m_bIsFollowFlowRow = bNew; }
     // <-- split table rows
diff --git a/sw/source/core/layout/tabfrm.cxx b/sw/source/core/layout/tabfrm.cxx
index c9f9674e8593..6edc4e84a198 100644
--- a/sw/source/core/layout/tabfrm.cxx
+++ b/sw/source/core/layout/tabfrm.cxx
@@ -1055,7 +1055,16 @@ bool SwTabFrame::Split( const SwTwips nCutPos, bool 
bTryToSplit, bool bTableRowK
     //                   table, or it will be set to false under certain
     //                   conditions that are not suitable for splitting
     //                   the row.
-    bool bSplitRowAllowed = pRow->IsRowSplitAllowed() && !IsSplitRowDisabled();
+    bool bSplitRowAllowed = !IsSplitRowDisabled();
+    if ( bSplitRowAllowed && !pRow->IsRowSplitAllowed() )
+    {
+        // A row larger than the entire page ought to be allowed to split 
regardless of setting,
+        // otherwise it has hidden content and that makes no sense
+        if ( !pRow->GetPrev() && pRow->getFrameArea().Height() > 
FindPageFrame()->getFramePrintArea().Height() )
+            pRow->SetForceRowSplitAllowed( true );
+        else
+            bSplitRowAllowed = false;
+    }
 
     // #i29438#
     // #i26945# - Floating screen objects no longer forbid
@@ -3695,6 +3704,13 @@ bool SwTabFrame::ShouldBwdMoved( SwLayoutFrame 
*pNewUpper, bool &rReformat )
             rReformat = true;
             return true;
         }
+
+        // Unsplitable rows have always started on a new page, so don't 
movebwd, even though we now allow splitting in some cases.
+        // This also matches Word - so good for interoperability (tdf#123116)
+        const SwRowFrame* pFirstRow = GetFirstNonHeadlineRow();
+        if ( pFirstRow && pFirstRow->IsForceRowSplitAllowed() )
+            return false;
+
         bool bFits = nSpace > 0;
         if (!bFits && aRectFnSet.GetHeight(getFrameArea()) == 0)
             // This frame fits into pNewUpper in case it has no space, but this
@@ -3705,7 +3721,6 @@ bool SwTabFrame::ShouldBwdMoved( SwLayoutFrame 
*pNewUpper, bool &rReformat )
             // #i26945# - check, if follow flow line
             // contains frame, which are moved forward due to its object
             // positioning.
-            SwRowFrame* pFirstRow = GetFirstNonHeadlineRow();
             if ( pFirstRow && pFirstRow->IsInFollowFlowRow() &&
                  SwLayouter::DoesRowContainMovedFwdFrame(
                                             
*(pFirstRow->GetFormat()->GetDoc()),
@@ -3909,6 +3924,7 @@ SwRowFrame::SwRowFrame(const SwTableLine &rLine, SwFrame* 
pSib, bool bInsertCont
     // <-- split table rows
     , m_bIsRepeatedHeadline( false )
     , m_bIsRowSpanLine( false )
+    , m_bForceRowSplitAllowed( false )
     , m_bIsInSplit( false )
 {
     mnFrameType = SwFrameType::Row;
@@ -4857,6 +4873,9 @@ bool SwRowFrame::IsRowSplitAllowed() const
          pTabFrame->IsInHeadline( *this ) )
         return false;
 
+    if ( IsForceRowSplitAllowed() )
+        return true;
+
     const SwTableLineFormat* pFrameFormat = 
static_cast<SwTableLineFormat*>(GetTabLine()->GetFrameFormat());
     const SwFormatRowSplit& rLP = pFrameFormat->GetRowSplit();
     return rLP.GetValue();

Reply via email to