From ceee3b41103d9ce6ef43c4762fc0fa78ab3ef303 Mon Sep 17 00:00:00 2001 From: Miklos Vajna Date: Mon, 16 Oct 2017 18:03:15 +0200 Subject: tdf#113153 sw: fix layout loop with split in-table sections The problem was in SwFrame::GetNextSctLeaf(): it called WrongPageDesc() to find out if pLayLeaf is a container that is on an acceptable page, but it was too aggressive, and discarded a split table cell that was in a follow table (so later it'll be moved to a next page), but on the same page. The result was that a new page was created, but later in ::doInsertPage() we noticed this unnecessary page and removed it. The effect of that was that the in-progress layout action's m_bIsAgain flag was set to true, restart the layout again and again. Given that in-table split sections never need to create a new page frame for the follow section (the cell does this for us already), just don't discard pLayLeaf when WrongPageDesc() finds it and we're in the split section-in-table case. Change-Id: Iea98a26c14fc1fb3154378eab24daa2fd6e84459 Reviewed-on: https://gerrit.libreoffice.org/43429 Reviewed-by: Miklos Vajna Tested-by: Jenkins (cherry picked from commit a69f48d923628facf7113ebc739a8273c4069122) --- sw/qa/extras/uiwriter/data/tdf113153.fodt | 677 ++++++++++++++++++++++++++++++ sw/qa/extras/uiwriter/uiwriter.cxx | 34 ++ sw/source/core/layout/sectfrm.cxx | 6 +- 3 files changed, 716 insertions(+), 1 deletion(-) create mode 100644 sw/qa/extras/uiwriter/data/tdf113153.fodt diff --git a/sw/qa/extras/uiwriter/data/tdf113153.fodt b/sw/qa/extras/uiwriter/data/tdf113153.fodt new file mode 100644 index 000000000000..5661f4ca0a3f --- /dev/null +++ b/sw/qa/extras/uiwriter/data/tdf113153.fodt @@ -0,0 +1,677 @@ + + + + LibreOfficeDev/5.2.5.1$Linux_X86_64 LibreOffice_project/1d78847be47e76f7fda105d8b497db1c9f60e3a7 + + + 0 + 0 + 70758 + 32583 + true + false + + + view2 + 5916 + 901 + 0 + 0 + 70757 + 32581 + 0 + 0 + false + 70 + false + + + + + false + true + true + true + true + 0 + true + + false + false + false + false + false + false + false + false + false + false + false + false + false + true + false + true + true + false + false + false + false + + false + false + true + false + false + + false + false + false + false + true + 374081 + false + true + true + false + true + true + false + true + 0 + false + true + high-resolution + false + false + false + true + true + true + + true + false + false + false + true + false + false + false + + false + false + 104774 + false + 1 + true + false + false + 0 + false + false + + + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + row before nested table + + + + + + + + + + + + + T20:A1-01 + T20:A1-02 + T20:A1-03 + T20:A1-04 + T20:A1-05 + T20:A1-06 + T20:A1-07 + T20:A1-08 + T20:A1-09 + T20:A1-10 + T20:A1-11 + + + T20:B1 + + + T20:C1 + + + T20:D1 + + + + + + T20:A2-01 + T20:A2-02 + T20:A2-03 + T20:A2-04 + T20:A2-05 + T20:A2-06 + T20:A2-07 + T20:A2-08 + T20:A2-09 + T20:A2-10 + T20:A2-11 + T20:A2-12 + T20:A2-13 + T20:A2-14 + T20:A2-15 + T20:A2-16 + T20:A2-17 + T20:A2-18 + T20:A2-19 + T20:A2-20 + T20:A2-21 + T20:A2-22 + T20:A2-23 + T20:A2-24 + T20:A2-25 + T20:A2-26 + T20:A2-27 + T20:A2-28 + + + + + T20:B2 + + + + + T20:C2 + + + + + T20:D2 + + + + + + + + + + + + diff --git a/sw/qa/extras/uiwriter/uiwriter.cxx b/sw/qa/extras/uiwriter/uiwriter.cxx index f6f7bbc980e1..deb4b6c33b6d 100644 --- a/sw/qa/extras/uiwriter/uiwriter.cxx +++ b/sw/qa/extras/uiwriter/uiwriter.cxx @@ -206,6 +206,7 @@ public: void testTableInSectionInTable(); void testSectionInTableInTable(); void testSectionInTableInTable2(); + void testSectionInTableInTable3(); void testTdf112160(); void testTdf112741(); void testTdf112860(); @@ -321,6 +322,7 @@ public: CPPUNIT_TEST(testTableInSectionInTable); CPPUNIT_TEST(testSectionInTableInTable); CPPUNIT_TEST(testSectionInTableInTable2); + CPPUNIT_TEST(testSectionInTableInTable3); CPPUNIT_TEST(testTdf112160); CPPUNIT_TEST(testLinesMoveBackwardsInSectionInTable); CPPUNIT_TEST(testTdf112741); @@ -3884,6 +3886,38 @@ void SwUiWriterTest::testSectionInTableInTable2() CPPUNIT_ASSERT_EQUAL(nSection1, nSection2Precede); } +void SwUiWriterTest::testSectionInTableInTable3() +{ + createDoc("tdf113153.fodt"); + + uno::Reference xTablesSupplier(mxComponent, uno::UNO_QUERY); + uno::Reference xTables(xTablesSupplier->getTextTables(), uno::UNO_QUERY); + uno::Reference xTable(xTables->getByIndex(1), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(OUString("Table16"), xTable->getName()); + + uno::Reference xRowSupplier(xTable, uno::UNO_QUERY); + uno::Reference xRows = xRowSupplier->getRows(); + uno::Reference xRow(xRows->getByIndex(1), uno::UNO_QUERY); + xRow->setPropertyValue("IsSplitAllowed", uno::makeAny(true)); + // This never returned. + calcLayout(); + + xmlDocPtr pXmlDoc = parseLayoutDump(); + 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(); + sal_uInt32 nTable2Follow = getXPath(pXmlDoc, "//page[2]//body/tab", "follow").toUInt32(); + sal_uInt32 nTable3 = getXPath(pXmlDoc, "//page[3]//body/tab", "id").toUInt32(); + sal_uInt32 nTable3Precede = getXPath(pXmlDoc, "//page[3]//body/tab", "precede").toUInt32(); + + // Make sure the outer table frames are linked together properly. + CPPUNIT_ASSERT_EQUAL(nTable2, nTable1Follow); + CPPUNIT_ASSERT_EQUAL(nTable1, nTable2Precede); + CPPUNIT_ASSERT_EQUAL(nTable3, nTable2Follow); + CPPUNIT_ASSERT_EQUAL(nTable2, nTable3Precede); +} + void SwUiWriterTest::testTdf112160() { // Assert that the A2 cell is on page 1. diff --git a/sw/source/core/layout/sectfrm.cxx b/sw/source/core/layout/sectfrm.cxx index 313e289a0e9b..ade4cca59962 100644 --- a/sw/source/core/layout/sectfrm.cxx +++ b/sw/source/core/layout/sectfrm.cxx @@ -1591,7 +1591,11 @@ SwLayoutFrame *SwFrame::GetNextSctLeaf( MakePageType eMakePage ) pLayLeaf = pLayLeaf->GetNextLayoutLeaf(); continue; } - if( WrongPageDesc( pNxtPg ) ) + // Page desc is never wrong in case of sections-in-tables: in that + // case pLayLeaf points to our section's cell's follow, which is + // fine to be on the same page. New page creation is handled when + // creating / moving the cell frame. + if( WrongPageDesc( pNxtPg ) && !bLayLeafTableAllowed ) { if( bWrongPage ) break; // there's a column between me and my right page -- cgit