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

tdf#113520 sw split sections in tables: avoid empty page after content del

The problem was that since split sections are allowed in nested tables,
deleting enough content so that the full content of a page is removed
results in an empty page, having only a 0 height table.  I.e. the split
section gets removed properly, the inner table (and its row and column)
as well, but the outer table is still there, though it is marked to have
0 height.

This results in a situation that the previous page doesn't have free
space (the in-table section tries to take as much space as it can), but
on the other hand we try (and fail) to move the 0 height table on the
current page to the previous one, as it doesn't have free space. At the
end the "empty" page still has an invisible table frame, so it is not
removed.

Fix the problem by allowing the move of a 0 height follow table frame
from the current page to the previous one, even it has no empty space.

Change-Id: I2a5fac88b8b7dc2b91d041b58a4ad1b328f56a6b
Reviewed-on: https://gerrit.libreoffice.org/44059Reviewed-by: 's avatarMiklos Vajna <vmiklos@collabora.co.uk>
Tested-by: 's avatarJenkins <ci@libreoffice.org>
üst 0c364fa7
This diff is collapsed.
...@@ -271,6 +271,7 @@ public: ...@@ -271,6 +271,7 @@ public:
void testSectionInTableInTable(); void testSectionInTableInTable();
void testSectionInTableInTable2(); void testSectionInTableInTable2();
void testSectionInTableInTable3(); void testSectionInTableInTable3();
void testSectionInTableInTable4();
void testTdf112160(); void testTdf112160();
void testLinesMoveBackwardsInSectionInTable(); void testLinesMoveBackwardsInSectionInTable();
void testTdf112741(); void testTdf112741();
...@@ -436,6 +437,7 @@ public: ...@@ -436,6 +437,7 @@ public:
CPPUNIT_TEST(testSectionInTableInTable); CPPUNIT_TEST(testSectionInTableInTable);
CPPUNIT_TEST(testSectionInTableInTable2); CPPUNIT_TEST(testSectionInTableInTable2);
CPPUNIT_TEST(testSectionInTableInTable3); CPPUNIT_TEST(testSectionInTableInTable3);
CPPUNIT_TEST(testSectionInTableInTable4);
CPPUNIT_TEST(testTdf112160); CPPUNIT_TEST(testTdf112160);
CPPUNIT_TEST(testLinesMoveBackwardsInSectionInTable); CPPUNIT_TEST(testLinesMoveBackwardsInSectionInTable);
CPPUNIT_TEST(testTdf112741); CPPUNIT_TEST(testTdf112741);
...@@ -5442,6 +5444,41 @@ void SwUiWriterTest::testSectionInTableInTable3() ...@@ -5442,6 +5444,41 @@ void SwUiWriterTest::testSectionInTableInTable3()
CPPUNIT_ASSERT_EQUAL(nTable2, nTable3Precede); CPPUNIT_ASSERT_EQUAL(nTable2, nTable3Precede);
} }
void SwUiWriterTest::testSectionInTableInTable4()
{
SwDoc* pDoc = createDoc("tdf113520.fodt");
xmlDocPtr pXmlDoc = parseLayoutDump();
assertXPath(pXmlDoc, "/root/page", 3);
sal_uInt32 nPage1LastNode = getXPath(pXmlDoc, "/root/page[1]/body/tab/row/cell[1]/tab/row/cell[1]/section/txt[last()]", "txtNodeIndex").toUInt32();
CPPUNIT_ASSERT_EQUAL(OUString("Section1:P10"), pDoc->GetNodes()[nPage1LastNode]->GetTextNode()->GetText());
sal_uInt32 nPage3FirstNode = getXPath(pXmlDoc, "/root/page[3]/body/tab/row/cell[1]/tab/row/cell[1]/section/txt[1]", "txtNodeIndex").toUInt32();
CPPUNIT_ASSERT_EQUAL(OUString("Section1:P23"), pDoc->GetNodes()[nPage3FirstNode]->GetTextNode()->GetText());
// Remove page 2.
SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
while (pWrtShell->GetCursor()->Start()->nNode.GetIndex() < nPage1LastNode)
pWrtShell->Down(/*bSelect=*/false);
pWrtShell->EndPara();
while (pWrtShell->GetCursor()->End()->nNode.GetIndex() < nPage3FirstNode)
pWrtShell->Down(/*bSelect=*/true);
pWrtShell->EndPara(/*bSelect=*/true);
pWrtShell->DelLeft();
// Assert that the page is removed.
discardDumpedLayout();
pXmlDoc = parseLayoutDump();
// This was 3, page 2 was emptied, but it wasn't removed.
assertXPath(pXmlDoc, "/root/page", 2);
// Make sure the outer table frames are linked together properly.
sal_uInt32 nTable1 = getXPath(pXmlDoc, "//page[1]//body/tab", "id").toUInt32();
sal_uInt32 nTable1Follow = getXPath(pXmlDoc, "//page[1]//body/tab", "follow").toUInt32();
sal_uInt32 nTable2 = getXPath(pXmlDoc, "//page[2]//body/tab", "id").toUInt32();
sal_uInt32 nTable2Precede = getXPath(pXmlDoc, "//page[2]//body/tab", "precede").toUInt32();
CPPUNIT_ASSERT_EQUAL(nTable2, nTable1Follow);
CPPUNIT_ASSERT_EQUAL(nTable1, nTable2Precede);
}
void SwUiWriterTest::testTdf112160() void SwUiWriterTest::testTdf112160()
{ {
// Assert that the A2 cell is on page 1. // Assert that the A2 cell is on page 1.
......
...@@ -2108,7 +2108,13 @@ void SwTabFrame::MakeAll(vcl::RenderContext* pRenderContext) ...@@ -2108,7 +2108,13 @@ void SwTabFrame::MakeAll(vcl::RenderContext* pRenderContext)
SwTwips nDeadLine = aRectFnSet.GetPrtBottom(*pTmp); SwTwips nDeadLine = aRectFnSet.GetPrtBottom(*pTmp);
if ( bBrowseMode ) if ( bBrowseMode )
nDeadLine += pTmp->Grow( LONG_MAX, true ); nDeadLine += pTmp->Grow( LONG_MAX, true );
if( aRectFnSet.BottomDist( getSwFrame(), nDeadLine ) > 0 ) bool bFits = aRectFnSet.BottomDist(getSwFrame(), nDeadLine) > 0;
if (!bFits && aRectFnSet.GetHeight(GetFollow()->getSwFrame()) == 0)
// The follow should move backwards, so allow the case
// when the upper has no space, but the follow is
// empty.
bFits = aRectFnSet.BottomDist(getSwFrame(), nDeadLine) >= 0;
if (bFits)
{ {
// First, we remove an existing follow flow line. // First, we remove an existing follow flow line.
if ( HasFollowFlowLine() ) if ( HasFollowFlowLine() )
...@@ -3413,7 +3419,12 @@ bool SwTabFrame::ShouldBwdMoved( SwLayoutFrame *pNewUpper, bool, bool &rReformat ...@@ -3413,7 +3419,12 @@ bool SwTabFrame::ShouldBwdMoved( SwLayoutFrame *pNewUpper, bool, bool &rReformat
rReformat = true; rReformat = true;
return true; return true;
} }
if (!m_bLockBackMove && nSpace > 0) bool bFits = nSpace > 0;
if (!bFits && aRectFnSet.GetHeight(getSwFrame()) == 0)
// This frame fits into pNewUpper in case it has no space, but this
// frame is empty.
bFits = nSpace >= 0;
if (!m_bLockBackMove && bFits)
{ {
// #i26945# - check, if follow flow line // #i26945# - check, if follow flow line
// contains frame, which are moved forward due to its object // contains frame, which are moved forward due to its object
......
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