sw/source/core/inc/frame.hxx      |    8 ++++++++
 sw/source/core/layout/findfrm.cxx |   12 ++++++++++++
 sw/source/core/layout/sectfrm.cxx |   32 ++++++++++++++++++++++++++++----
 3 files changed, 48 insertions(+), 4 deletions(-)

New commits:
commit f991b842addddeada6dc45c4054deeca5aa7f17b
Author: Miklos Vajna <vmik...@collabora.co.uk>
Date:   Mon Jun 19 15:24:12 2017 +0200

    tdf#108524 sw: attempt to split section frames inside table cells
    
    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.
    
    Change-Id: I16ebb2d30870b145a2378d46603324ab267b0dd3
    Reviewed-on: https://gerrit.libreoffice.org/38965
    Reviewed-by: Miklos Vajna <vmik...@collabora.co.uk>
    Tested-by: Jenkins <c...@libreoffice.org>

diff --git a/sw/source/core/inc/frame.hxx b/sw/source/core/inc/frame.hxx
index 5e72455c35e8..47512147f30e 100644
--- a/sw/source/core/inc/frame.hxx
+++ b/sw/source/core/inc/frame.hxx
@@ -41,6 +41,7 @@ class SwFootnoteFrame;
 class SwFootnoteBossFrame;
 class SwTabFrame;
 class SwRowFrame;
+class SwCellFrame;
 class SwFlowFrame;
 class SwContentFrame;
 class SfxPoolItem;
@@ -223,6 +224,7 @@ class SW_DLLPUBLIC SwFrame: public SwClient, public 
SfxBroadcaster
     const SwLayoutFrame* ImplGetNextLayoutLeaf( bool bFwd ) const;
 
     SwPageFrame* ImplFindPageFrame();
+    SwCellFrame* ImplFindCellFrame();
 
 protected:
     SwSortedObjs* mpDrawObjs;    // draw objects, can be 0
@@ -762,6 +764,12 @@ public:
     virtual void dumpAsXmlAttributes(xmlTextWriterPtr writer) const;
     void dumpChildrenAsXml(xmlTextWriterPtr writer) const;
     bool IsCollapse() const;
+
+    /// Find the nearest table cell frame that contains us, if any.
+    SwCellFrame* FindCellFrame()
+    {
+        return IsInTab() ? ImplFindCellFrame() : nullptr;
+    }
 };
 
 inline bool SwFrame::IsInDocBody() const
diff --git a/sw/source/core/layout/findfrm.cxx 
b/sw/source/core/layout/findfrm.cxx
index 74942256bef4..df630a270c5c 100644
--- a/sw/source/core/layout/findfrm.cxx
+++ b/sw/source/core/layout/findfrm.cxx
@@ -459,6 +459,18 @@ SwTabFrame* SwFrame::ImplFindTabFrame()
     return static_cast<SwTabFrame*>(pRet);
 }
 
+SwCellFrame* SwFrame::ImplFindCellFrame()
+{
+    SwFrame *pRet = this;
+    while (!pRet->IsCellFrame())
+    {
+        pRet = pRet->GetUpper();
+        if (!pRet)
+            return nullptr;
+    }
+    return static_cast<SwCellFrame*>(pRet);
+}
+
 SwSectionFrame* SwFrame::ImplFindSctFrame()
 {
     SwFrame *pRet = this;
diff --git a/sw/source/core/layout/sectfrm.cxx 
b/sw/source/core/layout/sectfrm.cxx
index b94ba4582d85..06c186c5d4c2 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,6 +1509,9 @@ 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;
     // A shortcut for TabFrames such that not all cells need to be visited
     if( bWrongPage )
@@ -1507,6 +1521,16 @@ SwLayoutFrame *SwFrame::GetNextSctLeaf( MakePageType 
eMakePage )
         SwContentFrame* pTmpCnt = 
static_cast<SwTabFrame*>(this)->FindLastContent();
         pLayLeaf = pTmpCnt ? pTmpCnt->GetUpper() : nullptr;
     }
+    else if (IsInTab() && !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 = FindCellFrame()->GetFollowCell();
+        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 +1558,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() ) ) )
             {
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to