Kaydet (Commit) f991b842 authored tarafından Miklos Vajna's avatar Miklos Vajna

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/38965Reviewed-by: 's avatarMiklos Vajna <vmiklos@collabora.co.uk>
Tested-by: 's avatarJenkins <ci@libreoffice.org>
üst ecf88f83
...@@ -41,6 +41,7 @@ class SwFootnoteFrame; ...@@ -41,6 +41,7 @@ class SwFootnoteFrame;
class SwFootnoteBossFrame; class SwFootnoteBossFrame;
class SwTabFrame; class SwTabFrame;
class SwRowFrame; class SwRowFrame;
class SwCellFrame;
class SwFlowFrame; class SwFlowFrame;
class SwContentFrame; class SwContentFrame;
class SfxPoolItem; class SfxPoolItem;
...@@ -223,6 +224,7 @@ class SW_DLLPUBLIC SwFrame: public SwClient, public SfxBroadcaster ...@@ -223,6 +224,7 @@ class SW_DLLPUBLIC SwFrame: public SwClient, public SfxBroadcaster
const SwLayoutFrame* ImplGetNextLayoutLeaf( bool bFwd ) const; const SwLayoutFrame* ImplGetNextLayoutLeaf( bool bFwd ) const;
SwPageFrame* ImplFindPageFrame(); SwPageFrame* ImplFindPageFrame();
SwCellFrame* ImplFindCellFrame();
protected: protected:
SwSortedObjs* mpDrawObjs; // draw objects, can be 0 SwSortedObjs* mpDrawObjs; // draw objects, can be 0
...@@ -762,6 +764,12 @@ public: ...@@ -762,6 +764,12 @@ public:
virtual void dumpAsXmlAttributes(xmlTextWriterPtr writer) const; virtual void dumpAsXmlAttributes(xmlTextWriterPtr writer) const;
void dumpChildrenAsXml(xmlTextWriterPtr writer) const; void dumpChildrenAsXml(xmlTextWriterPtr writer) const;
bool IsCollapse() 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 inline bool SwFrame::IsInDocBody() const
......
...@@ -459,6 +459,18 @@ SwTabFrame* SwFrame::ImplFindTabFrame() ...@@ -459,6 +459,18 @@ SwTabFrame* SwFrame::ImplFindTabFrame()
return static_cast<SwTabFrame*>(pRet); 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() SwSectionFrame* SwFrame::ImplFindSctFrame()
{ {
SwFrame *pRet = this; SwFrame *pRet = this;
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include <fmtftn.hxx> #include <fmtftn.hxx>
#include <fmtclbl.hxx> #include <fmtclbl.hxx>
#include "sectfrm.hxx" #include "sectfrm.hxx"
#include "cellfrm.hxx"
#include "section.hxx" #include "section.hxx"
#include <IDocumentSettingAccess.hxx> #include <IDocumentSettingAccess.hxx>
#include "rootfrm.hxx" #include "rootfrm.hxx"
...@@ -587,6 +588,16 @@ namespace ...@@ -587,6 +588,16 @@ namespace
return pLayFrame->GetNextLayoutLeaf(); return pLayFrame->GetNextLayoutLeaf();
return pLayFrame; 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 ) void SwSectionFrame::MoveContentAndDelete( SwSectionFrame* pDel, bool bSave )
...@@ -1439,9 +1450,9 @@ SwLayoutFrame *SwFrame::GetNextSctLeaf( MakePageType eMakePage ) ...@@ -1439,9 +1450,9 @@ SwLayoutFrame *SwFrame::GetNextSctLeaf( MakePageType eMakePage )
return static_cast<SwLayoutFrame*>(static_cast<SwLayoutFrame*>(GetUpper()->GetNext())->Lower()); return static_cast<SwLayoutFrame*>(static_cast<SwLayoutFrame*>(GetUpper()->GetNext())->Lower());
if( GetUpper()->IsColBodyFrame() && GetUpper()->GetUpper()->GetNext() ) if( GetUpper()->IsColBodyFrame() && GetUpper()->GetUpper()->GetNext() )
return static_cast<SwLayoutFrame*>(static_cast<SwLayoutFrame*>(GetUpper()->GetUpper()->GetNext())->Lower()); 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! // one column shift be made, one of the above shortcuts should have applied!
if( GetUpper()->IsInTab() || FindFooterOrHeader() ) if( IsInTableInSection(GetUpper()) || FindFooterOrHeader() )
return nullptr; return nullptr;
SwSectionFrame *pSect = FindSctFrame(); SwSectionFrame *pSect = FindSctFrame();
...@@ -1498,6 +1509,9 @@ SwLayoutFrame *SwFrame::GetNextSctLeaf( MakePageType eMakePage ) ...@@ -1498,6 +1509,9 @@ SwLayoutFrame *SwFrame::GetNextSctLeaf( MakePageType eMakePage )
const bool bBody = IsInDocBody(); const bool bBody = IsInDocBody();
const bool bFootnotePage = FindPageFrame()->IsFootnotePage(); 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 *pLayLeaf;
// A shortcut for TabFrames such that not all cells need to be visited // A shortcut for TabFrames such that not all cells need to be visited
if( bWrongPage ) if( bWrongPage )
...@@ -1507,6 +1521,16 @@ SwLayoutFrame *SwFrame::GetNextSctLeaf( MakePageType eMakePage ) ...@@ -1507,6 +1521,16 @@ SwLayoutFrame *SwFrame::GetNextSctLeaf( MakePageType eMakePage )
SwContentFrame* pTmpCnt = static_cast<SwTabFrame*>(this)->FindLastContent(); SwContentFrame* pTmpCnt = static_cast<SwTabFrame*>(this)->FindLastContent();
pLayLeaf = pTmpCnt ? pTmpCnt->GetUpper() : nullptr; 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 else
{ {
pLayLeaf = GetNextLayoutLeaf(); pLayLeaf = GetNextLayoutLeaf();
...@@ -1534,10 +1558,10 @@ SwLayoutFrame *SwFrame::GetNextSctLeaf( MakePageType eMakePage ) ...@@ -1534,10 +1558,10 @@ SwLayoutFrame *SwFrame::GetNextSctLeaf( MakePageType eMakePage )
pLayLeaf = nullptr; pLayLeaf = nullptr;
continue; 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()) || if ( (bBody && !pLayLeaf->IsInDocBody()) ||
(IsInFootnote() != pLayLeaf->IsInFootnote() ) || (IsInFootnote() != pLayLeaf->IsInFootnote() ) ||
pLayLeaf->IsInTab() || (pLayLeaf->IsInTab() && !bLayLeafTableAllowed) ||
( pLayLeaf->IsInSct() && ( !pSect->HasFollow() ( pLayLeaf->IsInSct() && ( !pSect->HasFollow()
|| pSect->GetFollow() != pLayLeaf->FindSctFrame() ) ) ) || pSect->GetFollow() != pLayLeaf->FindSctFrame() ) ) )
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment