[Libreoffice-commits] core.git: sw/qa sw/source

Miklos Vajna vmiklos at collabora.co.uk
Mon Jul 3 14:33:47 UTC 2017


 sw/qa/extras/uiwriter/uiwriter.cxx |    6 ----
 sw/source/core/layout/sectfrm.cxx  |   45 +++++++++++++++++++++++++++++++++----
 2 files changed, 41 insertions(+), 10 deletions(-)

New commits:
commit b5e0a143308e976b4165ff6181f4dccc3db0bd31
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Mon Jul 3 13:53:28 2017 +0200

    tdf#108524 sw: attempt to split section frames inside table cells, take two
    
    Tables-in-sections were already split across multiple pages, but not
    secions-in-tables. To be safe still don't allow
    sections-in-tables-in-sections, so you can combine these in both orders
    now, but not recursively.
    
    To achieve this, relax two "not in table" conditions to just require
    "not in a table that is already in a section", and define that in case a
    section-in-table is to be split, the follow section frame should be
    inserted under the follow of its cell.
    
    With this, finally the section frame in the bugdoc is split into two,
    and the second section frame is moved to the second page as expected.
    
    This restores commit f991b842addddeada6dc45c4054deeca5aa7f17b, but this second
    take makes sure that we do not crash while laying out ooo61225-1.sxw.
    GetNextSctLeaf() used to assume that SwTableFrame::Split() created the
    follow cell frames; and when that wasn't the case, it crashed. Still
    don't attempt to create the cell frame in GetNextSctLeaf(), but handle
    when the cell follow frame is missing, and return early, as it used to
    be the case before this commit.
    
    Change-Id: I9dcc76b4c61b39b9d23b140b84420e89cf274cf3
    Reviewed-on: https://gerrit.libreoffice.org/39471
    Reviewed-by: Miklos Vajna <vmiklos at collabora.co.uk>
    Tested-by: Jenkins <ci at libreoffice.org>

diff --git a/sw/qa/extras/uiwriter/uiwriter.cxx b/sw/qa/extras/uiwriter/uiwriter.cxx
index becae3b83617..c9b4efda6fad 100644
--- a/sw/qa/extras/uiwriter/uiwriter.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter.cxx
@@ -254,9 +254,7 @@ public:
     void testMsWordCompTrailingBlanks();
     void testCreateDocxAnnotation();
     void testTdf107976();
-#if 0
     void testTdf108524();
-#endif
     void testTableInSection();
 
     CPPUNIT_TEST_SUITE(SwUiWriterTest);
@@ -399,9 +397,7 @@ public:
     CPPUNIT_TEST(testMsWordCompTrailingBlanks);
     CPPUNIT_TEST(testCreateDocxAnnotation);
     CPPUNIT_TEST(testTdf107976);
-#if 0
     CPPUNIT_TEST(testTdf108524);
-#endif
     CPPUNIT_TEST(testTableInSection);
     CPPUNIT_TEST_SUITE_END();
 
@@ -4953,7 +4949,6 @@ void SwUiWriterTest::testTdf58604()
 #endif
 }
 
-#if 0
 void SwUiWriterTest::testTdf108524()
 {
     createDoc("tdf108524.odt");
@@ -4966,7 +4961,6 @@ void SwUiWriterTest::testTdf108524()
     // and it was cut off.
     assertXPath(pXmlDoc, "/root/page[2]/body/tab/row/cell/section", 1);
 }
-#endif
 
 void SwUiWriterTest::testTableInSection()
 {
diff --git a/sw/source/core/layout/sectfrm.cxx b/sw/source/core/layout/sectfrm.cxx
index b94ba4582d85..331b4be8fc66 100644
--- a/sw/source/core/layout/sectfrm.cxx
+++ b/sw/source/core/layout/sectfrm.cxx
@@ -22,6 +22,7 @@
 #include <fmtftn.hxx>
 #include <fmtclbl.hxx>
 #include "sectfrm.hxx"
+#include "cellfrm.hxx"
 #include "section.hxx"
 #include <IDocumentSettingAccess.hxx>
 #include "rootfrm.hxx"
@@ -587,6 +588,16 @@ namespace
             return pLayFrame->GetNextLayoutLeaf();
         return pLayFrame;
     }
+
+    /// Checks if pFrame is in a table, which itself is in a section.
+    bool IsInTableInSection(SwFrame* pFrame)
+    {
+        if (!pFrame->IsInTab())
+            return false;
+
+        // The frame is in a table, see if the table is in a section.
+        return pFrame->FindTabFrame()->IsInSct();
+    }
 }
 
 void SwSectionFrame::MoveContentAndDelete( SwSectionFrame* pDel, bool bSave )
@@ -1439,9 +1450,9 @@ SwLayoutFrame *SwFrame::GetNextSctLeaf( MakePageType eMakePage )
         return static_cast<SwLayoutFrame*>(static_cast<SwLayoutFrame*>(GetUpper()->GetNext())->Lower());
     if( GetUpper()->IsColBodyFrame() && GetUpper()->GetUpper()->GetNext() )
         return static_cast<SwLayoutFrame*>(static_cast<SwLayoutFrame*>(GetUpper()->GetUpper()->GetNext())->Lower());
-    // Inside a section, in tables, or sections of headers/footers, there can be only
+    // Inside a table-in-section, or sections of headers/footers, there can be only
     // one column shift be made, one of the above shortcuts should have applied!
-    if( GetUpper()->IsInTab() || FindFooterOrHeader() )
+    if( IsInTableInSection(GetUpper()) || FindFooterOrHeader() )
         return nullptr;
 
     SwSectionFrame *pSect = FindSctFrame();
@@ -1498,7 +1509,23 @@ SwLayoutFrame *SwFrame::GetNextSctLeaf( MakePageType eMakePage )
     const bool bBody = IsInDocBody();
     const bool bFootnotePage = FindPageFrame()->IsFootnotePage();
 
+    // The "pLayLeaf is in a table" case is rejected by default, so that it
+    // can't happen that we try to move a table to one of its own cells.
+    bool bLayLeafTableAllowed = false;
     SwLayoutFrame *pLayLeaf;
+
+    SwLayoutFrame* pCellLeaf = nullptr;
+    if (IsInTab())
+    {
+        // We are in a table, see if there is a follow cell frame created already.
+        pCellLeaf = GetNextCellLeaf();
+        if (!pCellLeaf)
+        {
+            SAL_WARN("sw.layout", "section is in table, but the table is not split");
+            return nullptr;
+        }
+    }
+
     // A shortcut for TabFrames such that not all cells need to be visited
     if( bWrongPage )
         pLayLeaf = nullptr;
@@ -1507,6 +1534,16 @@ SwLayoutFrame *SwFrame::GetNextSctLeaf( MakePageType eMakePage )
         SwContentFrame* pTmpCnt = static_cast<SwTabFrame*>(this)->FindLastContent();
         pLayLeaf = pTmpCnt ? pTmpCnt->GetUpper() : nullptr;
     }
+    else if (pCellLeaf && !IsInTableInSection(this))
+    {
+        // This frame is in a table-not-in-section, its follow should be
+        // inserted under the follow of the frame's cell.
+        pLayLeaf = pCellLeaf;
+        if (pLayLeaf->FindTabFrame() == FindTabFrame())
+            SAL_WARN("sw.layout", "my table frame and my follow's table frame is the same");
+        // In this case pLayLeaf pointing to an in-table frame is OK.
+        bLayLeafTableAllowed = true;
+    }
     else
     {
         pLayLeaf = GetNextLayoutLeaf();
@@ -1534,10 +1571,10 @@ SwLayoutFrame *SwFrame::GetNextSctLeaf( MakePageType eMakePage )
                 pLayLeaf = nullptr;
                 continue;
             }
-            // Once inBody always inBody, don't step into tables and not into other sections
+            // Once inBody always inBody, don't step into tables-in-sections and not into other sections
             if ( (bBody && !pLayLeaf->IsInDocBody()) ||
                  (IsInFootnote() != pLayLeaf->IsInFootnote() ) ||
-                 pLayLeaf->IsInTab() ||
+                 (pLayLeaf->IsInTab() && !bLayLeafTableAllowed) ||
                  ( pLayLeaf->IsInSct() && ( !pSect->HasFollow()
                    || pSect->GetFollow() != pLayLeaf->FindSctFrame() ) ) )
             {


More information about the Libreoffice-commits mailing list