summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJustin Luth <justin_luth@sil.org>2015-11-27 19:03:40 +0300
committerJustin Luth <justin_luth@sil.org>2016-01-18 04:30:59 +0000
commit0d127baed75929e744d5b6249f510012cfbc0e88 (patch)
tree428628b43ebaa4fdb40e6077aac0964ae9e195b4
parent57997db73725583a84dbac36bcc9c1b2829948f9 (diff)
tdf#91083 - .doc: emulate table keep-with-next paragraph
connect table with the following paragraph. Move forward to a new page together with the following paragraph if necessary. Most of the added code allows the table to split if all of the kept items do not fit on one page - allowing the emulated table to match the layout of kept tables. The only difference with .doc occurs when the table itself is larger than one page. In that case it ALWAYS starts a new page. Although it does not match .odt, it DOES match how MSWord handles that .doc. Change-Id: Ic6f495c0dc5cd4e9f8029a8cec9e31b4fab4b20f Reviewed-on: https://gerrit.libreoffice.org/20233 Reviewed-by: Justin Luth <justin_luth@sil.org> Tested-by: Justin Luth <justin_luth@sil.org>
-rw-r--r--sw/qa/extras/ww8export/ww8export.cxx3
-rw-r--r--sw/source/core/inc/flowfrm.hxx4
-rw-r--r--sw/source/core/layout/flowfrm.cxx8
-rw-r--r--sw/source/core/layout/tabfrm.cxx31
4 files changed, 29 insertions, 17 deletions
diff --git a/sw/qa/extras/ww8export/ww8export.cxx b/sw/qa/extras/ww8export/ww8export.cxx
index 949e58f4c8a3..ec0387388e0d 100644
--- a/sw/qa/extras/ww8export/ww8export.cxx
+++ b/sw/qa/extras/ww8export/ww8export.cxx
@@ -636,7 +636,8 @@ DECLARE_WW8EXPORT_TEST(testCommentExport, "comment-export.odt")
DECLARE_WW8EXPORT_TEST(testTableKeep, "tdf91083.odt")
{
//emulate table "keep with next" -do not split table
- CPPUNIT_ASSERT_EQUAL( OUString("Row 1"), parseDump("/root/page[5]/body/tab[1]/row[2]/cell[1]/txt[1]") );
+ CPPUNIT_ASSERT_EQUAL( OUString("Row 1"), parseDump("/root/page[3]/body/tab[1]/row[2]/cell[1]/txt[1]") );
+ CPPUNIT_ASSERT_EQUAL( OUString("Row 1"), parseDump("/root/page[6]/body/tab[1]/row[2]/cell[1]/txt[1]") );
}
#endif
diff --git a/sw/source/core/inc/flowfrm.hxx b/sw/source/core/inc/flowfrm.hxx
index 86771b5bc56f..e2aeb4577b07 100644
--- a/sw/source/core/inc/flowfrm.hxx
+++ b/sw/source/core/inc/flowfrm.hxx
@@ -123,7 +123,7 @@ protected:
inline bool IsFwdMoveAllowed();
// #i44049# - method <CalcContent(..)> has to check this property.
friend void CalcContent( SwLayoutFrame *pLay, bool bNoColl, bool bNoCalcFollow );
- bool IsKeepFwdMoveAllowed(); // like above, forward flow for Keep.
+ bool IsKeepFwdMoveAllowed( bool bIgnoreMyOwnKeepValue = false ); // like above, forward flow for Keep.
/** method to determine overlapping of an object that requests floating
@@ -137,7 +137,7 @@ protected:
void LockJoin() { m_bLockJoin = true; }
void UnlockJoin() { m_bLockJoin = false; }
- bool CheckMoveFwd( bool& rbMakePage, bool bKeep, bool bMovedBwd );
+ bool CheckMoveFwd( bool& rbMakePage, bool bKeep, bool bMovedBwd, bool bIgnoreMyOwnKeepValue = false );
bool MoveFwd( bool bMakePage, bool bPageBreak, bool bMoveAlways = false );
bool MoveBwd( bool &rbReformat );
virtual bool ShouldBwdMoved( SwLayoutFrame *pNewUpper, bool bHead, bool &rReformat )=0;
diff --git a/sw/source/core/layout/flowfrm.cxx b/sw/source/core/layout/flowfrm.cxx
index 7b6693076274..d7ec51ef3d3f 100644
--- a/sw/source/core/layout/flowfrm.cxx
+++ b/sw/source/core/layout/flowfrm.cxx
@@ -112,13 +112,15 @@ bool SwFlowFrame::HasLockedFollow() const
return false;
}
-bool SwFlowFrame::IsKeepFwdMoveAllowed()
+bool SwFlowFrame::IsKeepFwdMoveAllowed( bool bIgnoreMyOwnKeepValue )
{
// If all the predecessors up to the first of the chain have
// the 'keep' attribute set, and the first of the chain's
// IsFwdMoveAllowed returns false, then we're not allowed to move.
SwFrame *pFrame = &m_rThis;
if ( !pFrame->IsInFootnote() )
+ if ( bIgnoreMyOwnKeepValue && pFrame->GetIndPrev() )
+ pFrame = pFrame->GetIndPrev();
do
{ if ( pFrame->GetAttrSet()->GetKeep().GetValue() )
pFrame = pFrame->GetIndPrev();
@@ -1699,13 +1701,13 @@ SwTwips SwFlowFrame::CalcAddLowerSpaceAsLastInTableCell(
}
/// Moves the Frame forward if it seems necessary regarding the current conditions and attributes.
-bool SwFlowFrame::CheckMoveFwd( bool& rbMakePage, bool bKeep, bool )
+bool SwFlowFrame::CheckMoveFwd( bool& rbMakePage, bool bKeep, bool, bool bIgnoreMyOwnKeepValue )
{
const SwFrame* pNxt = m_rThis.GetIndNext();
if ( bKeep && //!bMovedBwd &&
( !pNxt || ( pNxt->IsTextFrame() && static_cast<const SwTextFrame*>(pNxt)->IsEmptyMaster() ) ) &&
- ( nullptr != (pNxt = m_rThis.FindNext()) ) && IsKeepFwdMoveAllowed() )
+ ( nullptr != (pNxt = m_rThis.FindNext()) ) && IsKeepFwdMoveAllowed(bIgnoreMyOwnKeepValue) )
{
if( pNxt->IsSctFrame() )
{ // Don't get fooled by empty SectionFrames
diff --git a/sw/source/core/layout/tabfrm.cxx b/sw/source/core/layout/tabfrm.cxx
index a45a1f4059d0..0e2fed891fb0 100644
--- a/sw/source/core/layout/tabfrm.cxx
+++ b/sw/source/core/layout/tabfrm.cxx
@@ -1765,7 +1765,8 @@ void SwTabFrame::MakeAll(vcl::RenderContext* pRenderContext)
const SwBorderAttrs *pAttrs = pAccess->Get();
// The beloved keep attribute
- const bool bKeep = IsKeep( pAttrs->GetAttrSet() );
+ const bool bEmulateTableKeep = AreAllRowsKeepWithNext( GetFirstNonHeadlineRow() );
+ const bool bKeep = IsKeep( pAttrs->GetAttrSet(), bEmulateTableKeep );
// All rows should keep together
const bool bDontSplit = !IsFollow() &&
@@ -1845,8 +1846,9 @@ void SwTabFrame::MakeAll(vcl::RenderContext* pRenderContext)
while ( !mbValidPos || !mbValidSize || !mbValidPrtArea )
{
const bool bMoveable = IsMoveable();
- if (bMoveable)
- if ( CheckMoveFwd( bMakePage, bKeep && KEEPTAB, bMovedBwd ) )
+ if (bMoveable &&
+ !(bMovedFwd && bEmulateTableKeep) )
+ if ( CheckMoveFwd( bMakePage, bKeep && KEEPTAB, bMovedBwd, bEmulateTableKeep ) )
{
bMovedFwd = true;
m_bCalcLowers = true;
@@ -2222,19 +2224,25 @@ void SwTabFrame::MakeAll(vcl::RenderContext* pRenderContext)
AreAllRowsKeepWithNext( pFirstNonHeadlineRow ) ) &&
!pIndPrev &&
!bDontSplit;
+ const bool bEmulateTableKeepFwdMoveAllowed = IsKeepFwdMoveAllowed(bEmulateTableKeep);
if ( pFirstNonHeadlineRow && nUnSplitted > 0 &&
- ( !bTableRowKeep || pFirstNonHeadlineRow->GetNext() || !pFirstNonHeadlineRow->ShouldRowKeepWithNext() || bAllowSplitOfRow ) &&
- ( !bDontSplit || !pIndPrev ) )
+ ( !bEmulateTableKeepFwdMoveAllowed ||
+ ( ( !bTableRowKeep || pFirstNonHeadlineRow->GetNext() ||
+ !pFirstNonHeadlineRow->ShouldRowKeepWithNext() || bAllowSplitOfRow
+ ) && ( !bDontSplit || !pIndPrev )
+ ) ) )
{
// #i29438#
- // Special DoNotSplit case:
+ // Special DoNotSplit cases:
+ // We better avoid splitting if the table keeps with next paragraph and can move fwd still.
// We better avoid splitting of a row frame if we are inside a columned
// section which has a height of 0, because this is not growable and thus
// all kinds of unexpected things could happen.
- if ( IsInSct() &&
- (FindSctFrame())->Lower()->IsColumnFrame() &&
- 0 == (GetUpper()->Frame().*fnRect->fnGetHeight)() )
+ if ( !bEmulateTableKeepFwdMoveAllowed ||
+ ( IsInSct() && (FindSctFrame())->Lower()->IsColumnFrame() &&
+ 0 == (GetUpper()->Frame().*fnRect->fnGetHeight)()
+ ) )
{
bTryToSplit = false;
}
@@ -2303,7 +2311,8 @@ void SwTabFrame::MakeAll(vcl::RenderContext* pRenderContext)
// Some more checks if we want to call the split algorithm or not:
// The repeating lines / keeping lines still fit into the upper or
// if we do not have an (in)direct Prev, we split anyway.
- if( (*fnRect->fnYDiff)(nDeadLine, nBreakLine) >=0 || !pIndPrev )
+ if( (*fnRect->fnYDiff)(nDeadLine, nBreakLine) >=0
+ || !pIndPrev || !bEmulateTableKeepFwdMoveAllowed )
{
aNotify.SetLowersComplete( false );
bSplit = true;
@@ -2320,7 +2329,7 @@ void SwTabFrame::MakeAll(vcl::RenderContext* pRenderContext)
--nThrowAwayValidLayoutLimit;
}
- const bool bSplitError = !Split( nDeadLine, bTryToSplit, ( bTableRowKeep && !bAllowSplitOfRow ) );
+ const bool bSplitError = !Split( nDeadLine, bTryToSplit, ( bTableRowKeep && !(bAllowSplitOfRow || !bEmulateTableKeepFwdMoveAllowed) ) );
if( !bTryToSplit && !bSplitError && nUnSplitted > 0 )
{
--nUnSplitted;