summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sw/qa/extras/layout/data/tdf155611_table_and_nested_section.fodt33
-rw-r--r--sw/qa/extras/layout/layout2.cxx28
-rw-r--r--sw/source/core/layout/sectfrm.cxx16
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