diff options
-rw-r--r-- | sw/source/core/inc/frame.hxx | 8 | ||||
-rw-r--r-- | sw/source/core/layout/findfrm.cxx | 12 | ||||
-rw-r--r-- | sw/source/core/layout/sectfrm.cxx | 32 |
3 files changed, 48 insertions, 4 deletions
diff --git a/sw/source/core/inc/frame.hxx b/sw/source/core/inc/frame.hxx index df85c55ae326..37bc0c08f09c 100644 --- a/sw/source/core/inc/frame.hxx +++ b/sw/source/core/inc/frame.hxx @@ -42,6 +42,7 @@ class SwFootnoteFrame; class SwFootnoteBossFrame; class SwTabFrame; class SwRowFrame; +class SwCellFrame; class SwFlowFrame; class SwContentFrame; class SfxPoolItem; @@ -227,6 +228,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 @@ -770,6 +772,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 fb5854a80c9c..d0981628b2eb 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 86dac9e92664..f23a93c3ebd3 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() ) ) ) { |