diff options
author | Miklos Vajna <vmiklos@collabora.co.uk> | 2016-03-23 16:44:43 +0100 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.co.uk> | 2016-03-23 16:36:48 +0000 |
commit | b4b5dbee1ec7770ed64d7270de46d5cfc06b87b6 (patch) | |
tree | 861f662a721df5bd3f6a2569db0d3ae49864972f | |
parent | 11231f9179db9821effc884e8adade48fdf89938 (diff) |
tdf#88453 sw layout: fix split of nested tables with large amount of rows
This does not fix the original bugdoc, just the case described in
comment 2. The bugdoc has an outer table of a single cell, and that cell
has a nested table with a single column and many rows.
When we split the table, we set the height of the last row frame to
zero, then the height of the last but one, and so on, till the reduced
table fits the page, then move the 0-height frames to the next page, and
so on. All this recursively, to support nested tables.
The problem is that 0-height is set only for the contents of the cell
frames, but not for the cell or row frames themselves, so in case e.g.
the default ~0.10cm inner margin of the cell frames, even a 0-height
text frame results in a cell frame height of 111 twips. And this error
can accumlate if there are enough rows, e.g. with the default fonts 123
rows are enough to trigger the situation when even a completely reduced
table doesn't fit the first page frame, and the layout throws up its
hands.
Fix the problem by setting the height of the cell and row frames to 0 as
well in case their content is 0-sized anyway (so a re-format will later
restore their correct height).
Change-Id: Iefbbb7bd6ef97a9a81929eb2599adb961e52fd38
Reviewed-on: https://gerrit.libreoffice.org/23476
Reviewed-by: Miklos Vajna <vmiklos@collabora.co.uk>
Tested-by: Jenkins <ci@libreoffice.org>
-rw-r--r-- | sw/qa/extras/uiwriter/data/tdf88453.odt | bin | 0 -> 21235 bytes | |||
-rw-r--r-- | sw/qa/extras/uiwriter/uiwriter.cxx | 12 | ||||
-rw-r--r-- | sw/source/core/layout/tabfrm.cxx | 23 |
3 files changed, 35 insertions, 0 deletions
diff --git a/sw/qa/extras/uiwriter/data/tdf88453.odt b/sw/qa/extras/uiwriter/data/tdf88453.odt Binary files differnew file mode 100644 index 000000000000..de8491bbb4f9 --- /dev/null +++ b/sw/qa/extras/uiwriter/data/tdf88453.odt diff --git a/sw/qa/extras/uiwriter/uiwriter.cxx b/sw/qa/extras/uiwriter/uiwriter.cxx index 068322859076..ef694d9ddfd0 100644 --- a/sw/qa/extras/uiwriter/uiwriter.cxx +++ b/sw/qa/extras/uiwriter/uiwriter.cxx @@ -187,6 +187,7 @@ public: void testTdf96536(); void testTdf96479(); void testTdf96961(); + void testTdf88453(); void testClassificationPaste(); CPPUNIT_TEST_SUITE(SwUiWriterTest); @@ -278,6 +279,7 @@ public: CPPUNIT_TEST(testTdf96536); CPPUNIT_TEST(testTdf96479); CPPUNIT_TEST(testTdf96961); + CPPUNIT_TEST(testTdf88453); CPPUNIT_TEST(testClassificationPaste); CPPUNIT_TEST_SUITE_END(); @@ -3248,6 +3250,16 @@ void SwUiWriterTest::testTdf96961() CPPUNIT_ASSERT(nLast > nOther); } +void SwUiWriterTest::testTdf88453() +{ + createDoc("tdf88453.odt"); + calcLayout(); + xmlDocPtr pXmlDoc = parseLayoutDump(); + // This was 0: the table does not fit the first page, but it wasn't split + // to continue on the second page. + assertXPath(pXmlDoc, "/root/page[2]/body/tab", 1); +} + namespace { diff --git a/sw/source/core/layout/tabfrm.cxx b/sw/source/core/layout/tabfrm.cxx index de4f7496e9e6..2f16c985ccd1 100644 --- a/sw/source/core/layout/tabfrm.cxx +++ b/sw/source/core/layout/tabfrm.cxx @@ -331,6 +331,7 @@ static void lcl_ShrinkCellsAndAllContent( SwRowFrame& rRow ) SwCellFrame* pCurrMasterCell = static_cast<SwCellFrame*>(rRow.Lower()); SWRECTFN( pCurrMasterCell ) + bool bAllCellsCollapsed = true; while ( pCurrMasterCell ) { // NEW TABLES @@ -347,6 +348,7 @@ static void lcl_ShrinkCellsAndAllContent( SwRowFrame& rRow ) // we have to start with the last lower frame, otherwise // the shrink will not shrink the current cell SwFrame* pTmp = rToAdjust.GetLastLower(); + bool bAllLowersCollapsed = true; if ( pTmp && pTmp->IsRowFrame() ) { @@ -373,6 +375,9 @@ static void lcl_ShrinkCellsAndAllContent( SwRowFrame& rRow ) pTmp->Shrink( (pTmp->Frame().*fnRect->fnGetHeight)() ); (pTmp->Prt().*fnRect->fnSetTop)( 0 ); (pTmp->Prt().*fnRect->fnSetHeight)( 0 ); + + if ((pTmp->Frame().*fnRect->fnGetHeight)() > 0) + bAllLowersCollapsed = false; } pTmp = pTmp->GetPrev(); @@ -384,8 +389,26 @@ static void lcl_ShrinkCellsAndAllContent( SwRowFrame& rRow ) false ); } + if (bAllLowersCollapsed) + { + // All lower frame of this cell have 0 height -> set height of the cell itself as well. + (pCurrMasterCell->Frame().*fnRect->fnSetHeight)(0); + (pCurrMasterCell->Prt().*fnRect->fnSetTop)(0); + (pCurrMasterCell->Prt().*fnRect->fnSetHeight)(0); + } + else + bAllCellsCollapsed = false; + pCurrMasterCell = static_cast<SwCellFrame*>(pCurrMasterCell->GetNext()); } + + if (bAllCellsCollapsed) + { + // All cells have 0 height -> set height of row as well. + (rRow.Frame().*fnRect->fnSetHeight)(0); + (rRow.Prt().*fnRect->fnSetTop)(0); + (rRow.Prt().*fnRect->fnSetHeight)(0); + } } // Local helper function to move the content from rSourceLine to rDestLine |