diff options
-rw-r--r-- | sw/qa/extras/layout/data/tdf155611_table_and_nested_section.fodt | 33 | ||||
-rw-r--r-- | sw/qa/extras/layout/layout2.cxx | 28 | ||||
-rw-r--r-- | sw/source/core/layout/sectfrm.cxx | 16 |
3 files changed, 76 insertions, 1 deletions
diff --git a/sw/qa/extras/layout/data/tdf155611_table_and_nested_section.fodt b/sw/qa/extras/layout/data/tdf155611_table_and_nested_section.fodt new file mode 100644 index 000000000000..28c0701ea2fc --- /dev/null +++ b/sw/qa/extras/layout/data/tdf155611_table_and_nested_section.fodt @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<office:document xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" office:version="1.3" office:mimetype="application/vnd.oasis.opendocument.text"> + <office:body> + <office:text> + <text:section text:name="Outer section"> + <table:table> + <table:table-column table:number-columns-repeated="2"/> + <table:table-row> + <table:table-cell> + <text:p>foo</text:p> + </table:table-cell> + <table:table-cell> + <text:p>bar</text:p> + <table:table> + <table:table-column/> + <table:table-row> + <table:table-cell> + <text:p>baz</text:p> + </table:table-cell> + </table:table-row> + </table:table> + </table:table-cell> + </table:table-row> + </table:table> + <text:section text:name="Inner section"> + <text:p>abc</text:p> + </text:section> + </text:section> + <text:p/> + </office:text> + </office:body> +</office:document>
\ No newline at end of file diff --git a/sw/qa/extras/layout/layout2.cxx b/sw/qa/extras/layout/layout2.cxx index 59e9d7d9f43c..70ebd9843ceb 100644 --- a/sw/qa/extras/layout/layout2.cxx +++ b/sw/qa/extras/layout/layout2.cxx @@ -1815,6 +1815,34 @@ CPPUNIT_TEST_FIXTURE(SwLayoutWriter2, testTdf154113) "Section3. End selection here -->"); } +CPPUNIT_TEST_FIXTURE(SwLayoutWriter2, testTdf155611) +{ + createSwDoc(DATA_DIRECTORY, "tdf155611_table_and_nested_section.fodt"); + Scheduler::ProcessEventsToIdle(); + + xmlDocUniquePtr pXml = parseLayoutDump(); + CPPUNIT_ASSERT(pXml); + + // Check the layout: single page, two section frames (no section frames after the one for Inner + // section), correct table structure and content in the first section frame, including nested + // table in the last cell, and the last section text. + assertXPath(pXml, "/root/page"); + // Without the fix in place, this would fail with + // - Expected: 2 + // - Actual : 3 + assertXPath(pXml, "/root/page/body/section", 2); + assertXPath(pXml, "/root/page/body/section[1]/tab"); + assertXPath(pXml, "/root/page/body/section[1]/tab/row"); + assertXPath(pXml, "/root/page/body/section[1]/tab/row/cell", 2); + assertXPath(pXml, "/root/page/body/section[1]/tab/row/cell[1]/txt/Text[@Portion='foo']"); + assertXPath(pXml, "/root/page/body/section[1]/tab/row/cell[2]/txt/Text[@Portion='bar']"); + assertXPath(pXml, + "/root/page/body/section[1]/tab/row/cell[2]/tab/row/cell/txt/Text[@Portion='baz']"); + assertXPath(pXml, "/root/page/body/section[2]/txt[1]/Text[@Portion='abc']"); + + // Also must not crash on close because of a frame that accidentally fell off of the layout +} + CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/core/layout/sectfrm.cxx b/sw/source/core/layout/sectfrm.cxx index 111c31f7d3b6..1163e048e64b 100644 --- a/sw/source/core/layout/sectfrm.cxx +++ b/sw/source/core/layout/sectfrm.cxx @@ -519,7 +519,21 @@ void SwSectionFrame::MergeNext( SwSectionFrame* pNxt ) SwSectionFrame* SwSectionFrame::SplitSect( SwFrame* pFrameStartAfter, SwFrame* pFramePutAfter ) { assert(!pFrameStartAfter || IsAnLower(pFrameStartAfter)); - SwFrame* pSav = pFrameStartAfter ? pFrameStartAfter->FindNext() : ContainsAny(); + SwFrame* pSav; + if (pFrameStartAfter) + { + pSav = pFrameStartAfter->FindNext(); + // If pFrameStartAfter is a complex object like table, and it has no next, + // its FindNext may return its own last subframe. In this case, assume that + // we are at the end. + if (pSav && pFrameStartAfter->IsLayoutFrame()) + if (static_cast<SwLayoutFrame*>(pFrameStartAfter)->IsAnLower(pSav)) + pSav = nullptr; + } + else + { + pSav = ContainsAny(); + } if (pSav && !IsAnLower(pSav)) pSav = nullptr; // we are at the very end |