sw/qa/extras/layout/data/tdf160958_orphans_move_section.fodt | 52 +++ sw/qa/extras/layout/data/tdf160958_page_break.fodt | 39 ++ sw/qa/extras/layout/layout3.cxx | 162 +++++++++++ sw/source/core/layout/sectfrm.cxx | 52 +++ 4 files changed, 305 insertions(+)
New commits: commit 932a01d9752d84c1919a4e5ade7b9c194c15ceaf Author: Mike Kaganski <mike.kagan...@collabora.com> AuthorDate: Thu May 30 02:23:02 2024 +0500 Commit: Miklos Vajna <vmik...@collabora.com> CommitDate: Fri May 31 16:56:16 2024 +0200 tdf#160958: merge hidden section's follows; move first-on-page section back Change-Id: I6bd6707089dcea58d5df4bef63aa769769d97ea9 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/168235 Tested-by: Jenkins Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/168204 Reviewed-by: Miklos Vajna <vmik...@collabora.com> Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com> diff --git a/sw/qa/extras/layout/data/tdf160958_orphans_move_section.fodt b/sw/qa/extras/layout/data/tdf160958_orphans_move_section.fodt new file mode 100644 index 000000000000..1306cfa6226d --- /dev/null +++ b/sw/qa/extras/layout/data/tdf160958_orphans_move_section.fodt @@ -0,0 +1,52 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<office:document xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" office:version="1.3" office:mimetype="application/vnd.oasis.opendocument.text"> + <office:font-face-decls> + <style:font-face style:name="Liberation Serif" svg:font-family="'Liberation Serif'" style:font-family-generic="roman" style:font-pitch="variable"/> + </office:font-face-decls> + <office:styles> + <style:default-style style:family="paragraph"> + <style:paragraph-properties fo:orphans="2" fo:widows="2"/> + <style:text-properties style:font-name="Liberation Serif" fo:font-size="12pt"/> + </style:default-style> + </office:styles> + <office:automatic-styles> + <style:page-layout style:name="pm1"> + <style:page-layout-properties fo:page-width="21cm" fo:page-height="297mm" style:print-orientation="portrait" fo:margin-top="2cm" fo:margin-bottom="2cm" fo:margin-left="2cm" fo:margin-right="2cm"/> + </style:page-layout> + </office:automatic-styles> + <office:master-styles> + <style:master-page style:name="Standard" style:page-layout-name="pm1"/> + </office:master-styles> + <office:body> + <office:text> + <text:p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum consequat mi quis pretium semper. Proin luctus orci ac neque venenatis, quis commodo dolor posuere. Curabitur dignissim sapien quis cursus egestas. Donec blandit auctor arcu, nec pellentesque eros molestie eget. In consectetur aliquam hendrerit. Sed cursus mauris vitae ligula pellentesque, non pellentesque urna aliquet. Fusce placerat mauris enim, nec rutrum purus semper vel. Praesent tincidunt neque eu pellentesque pharetra. Fusce pellentesque est orci.</text:p> + <text:p>Integer sodales tincidunt tristique. Sed a metus posuere, adipiscing nunc et, viverra odio. Donec auctor molestie sem, sit amet tristique lectus hendrerit sed. Cras sodales nisl sed orci mattis iaculis. Nunc eget dolor accumsan, pharetra risus a, vestibulum mauris. Nunc vulputate lobortis mollis. Vivamus nec tellus faucibus, tempor magna nec, facilisis felis. Donec commodo enim a vehicula pellentesque. Nullam vehicula vestibulum est vel ultricies.</text:p> + <text:p>Aliquam velit massa, laoreet vel leo nec, volutpat facilisis eros. Donec consequat arcu ut diam tempor luctus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Praesent vitae lacus vel leo sodales pharetra a a nibh. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nam luctus tempus nibh, fringilla dictum augue consectetur eget. Curabitur at ante sit amet tortor pharetra molestie eu nec ante. Mauris tincidunt, nibh eu sollicitudin molestie, dolor sapien congue tortor, a pulvinar sapien turpis sed ante. Donec nec est elementum, euismod nulla in, mollis nunc.</text:p> + <text:p>He heard quiet steps behind him. That didn't bode well. Who could be following him this late at night and in this deadbeat part of town? And at this particular moment, just after he pulled off the big time and was making off with the greenbacks. Was there another crook who'd had the same idea, and was now watching him and waiting for a chance to grab the fruit of his labor? Or did the steps behind him mean that one of many law officers in town was on to him and just waiting to pounce and snap those cuffs on his wrists? He nervously looked all around. Suddenly he saw the alley. Like lightning he darted off to the left and disappeared between the two warehouses almost falling over the trash can lying in the middle of the sidewalk. He tried to nervously tap his way along in the inky darkness and suddenly stiffened: it was a dead-end, he would have to go back the way he had come. The steps got louder and louder, he saw the black outline of a figure coming around the corner. Is this the end of the line? he thought pressing himself back against the wall trying to make himself invisible in the dark, was all that planning and energy wasted? He was dripping with sweat now, cold and wet, he could smell the fear coming off his clothes. Suddenly next to him, with a barely noticeable squeak, a door swung quietly to and fro in the night's breeze. Could this be the haven he'd prayed for? Slowly he slid toward the door, pressing himself more and more into the wall, into the dark, away from his enemy. Would this door save his hide?</text:p> + <text:p>foo</text:p> + <text:p>bar</text:p> + <text:p>baz</text:p> + <text:p>foo</text:p> + <text:p>bar</text:p> + <text:p>baz</text:p> + <text:p>foo</text:p> + <text:p>bar</text:p> + <text:p>baz</text:p> + <text:p>foo</text:p> + <text:p>bar</text:p> + <text:p>baz</text:p> + <text:p>foo</text:p> + <text:p>bar</text:p> + <text:p>baz</text:p> + <text:p>foo</text:p> + <text:p>bar</text:p> + <text:section text:name="Section1"> + <text:p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum consequat mi quis pretium semper. Proin luctus orci ac neque venenatis, quis commodo dolor posuere. Curabitur dignissim sapien quis cursus egestas. Donec blandit auctor arcu, nec pellentesque eros molestie eget. In consectetur aliquam hendrerit. Sed cursus mauris vitae ligula pellentesque, non pellentesque urna aliquet. Fusce placerat mauris enim, nec rutrum purus semper vel. Praesent tincidunt neque eu pellentesque pharetra. Fusce pellentesque est orci.</text:p> + <text:p>Integer sodales tincidunt tristique. Sed a metus posuere, adipiscing nunc et, viverra odio. Donec auctor molestie sem, sit amet tristique lectus hendrerit sed. Cras sodales nisl sed orci mattis iaculis. Nunc eget dolor accumsan, pharetra risus a, vestibulum mauris. Nunc vulputate lobortis mollis. Vivamus nec tellus faucibus, tempor magna nec, facilisis felis. Donec commodo enim a vehicula pellentesque. Nullam vehicula vestibulum est vel ultricies.</text:p> + <text:p>Aliquam velit massa, laoreet vel leo nec, volutpat facilisis eros. Donec consequat arcu ut diam tempor luctus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Praesent vitae lacus vel leo sodales pharetra a a nibh. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nam luctus tempus nibh, fringilla dictum augue consectetur eget. Curabitur at ante sit amet tortor pharetra molestie eu nec ante. Mauris tincidunt, nibh eu sollicitudin molestie, dolor sapien congue tortor, a pulvinar sapien turpis sed ante. Donec nec est elementum, euismod nulla in, mollis nunc.</text:p> + </text:section> + <text:p>baz</text:p> + </office:text> + </office:body> +</office:document> \ No newline at end of file diff --git a/sw/qa/extras/layout/data/tdf160958_page_break.fodt b/sw/qa/extras/layout/data/tdf160958_page_break.fodt new file mode 100644 index 000000000000..1d4d8863b073 --- /dev/null +++ b/sw/qa/extras/layout/data/tdf160958_page_break.fodt @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<office:document xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" office:version="1.3" office:mimetype="application/vnd.oasis.opendocument.text"> + <office:font-face-decls> + <style:font-face style:name="Liberation Serif" svg:font-family="'Liberation Serif'" style:font-family-generic="roman" style:font-pitch="variable"/> + </office:font-face-decls> + <office:styles> + <style:default-style style:family="paragraph"> + <style:text-properties style:use-window-font-color="true" style:font-name="Liberation Serif" fo:font-size="12pt"/> + </style:default-style> + </office:styles> + <office:automatic-styles> + <style:style style:name="P1" style:family="paragraph" style:master-page-name=""> + <style:paragraph-properties style:page-number="auto" fo:break-before="page"/> + </style:style> + <style:page-layout style:name="pm1"> + <style:page-layout-properties fo:page-width="21cm" fo:page-height="297mm" style:num-format="1" style:print-orientation="portrait" fo:margin-top="2cm" fo:margin-bottom="2cm" fo:margin-left="2cm" fo:margin-right="2cm"/> + </style:page-layout> + </office:automatic-styles> + <office:master-styles> + <style:master-page style:name="Standard" style:page-layout-name="pm1"/> + </office:master-styles> + <office:body> + <office:text> + <text:p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum consequat mi quis pretium semper. Proin luctus orci ac neque venenatis, quis commodo dolor posuere. Curabitur dignissim sapien quis cursus egestas. Donec blandit auctor arcu, nec pellentesque eros molestie eget. In consectetur aliquam hendrerit. Sed cursus mauris vitae ligula pellentesque, non pellentesque urna aliquet. Fusce placerat mauris enim, nec rutrum purus semper vel. Praesent tincidunt neque eu pellentesque pharetra. Fusce pellentesque est orci.</text:p> + <text:section text:name="Section1"> + <text:p text:style-name="P1"/> + <text:p/> + <text:p/> + <text:p>Integer sodales tincidunt tristique. Sed a metus posuere, adipiscing nunc et, viverra odio. Donec auctor molestie sem, sit amet tristique lectus hendrerit sed. Cras sodales nisl sed orci mattis iaculis. Nunc eget dolor accumsan, pharetra risus a, vestibulum mauris. Nunc vulputate lobortis mollis. <text:soft-page-break/>Vivamus nec tellus faucibus, tempor magna nec, facilisis felis. Donec commodo enim a vehicula pellentesque. Nullam vehicula vestibulum est vel ultricies.</text:p> + <text:p/> + <text:p/> + <text:p/> + </text:section> + <text:p>Aliquam velit massa, laoreet vel leo nec, volutpat facilisis eros. Donec consequat arcu ut diam tempor luctus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Praesent vitae lacus vel leo sodales pharetra a a nibh. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nam luctus tempus nibh, fringilla dictum augue consectetur eget. Curabitur at ante sit amet tortor pharetra molestie eu nec ante. Mauris tincidunt, nibh eu sollicitudin molestie, dolor sapien congue tortor, a pulvinar sapien turpis sed ante. Donec nec est elementum, euismod nulla in, mollis nunc.</text:p> + <text:p/> + </office:text> + </office:body> +</office:document> \ No newline at end of file diff --git a/sw/qa/extras/layout/layout3.cxx b/sw/qa/extras/layout/layout3.cxx index d553162f1636..8f555e0bf6ba 100644 --- a/sw/qa/extras/layout/layout3.cxx +++ b/sw/qa/extras/layout/layout3.cxx @@ -11,6 +11,7 @@ #include <comphelper/propertysequence.hxx> #include <com/sun/star/linguistic2/XHyphenator.hpp> #include <com/sun/star/text/WrapTextMode.hpp> +#include <com/sun/star/text/XTextSectionsSupplier.hpp> #include <vcl/event.hxx> #include <vcl/scheduler.hxx> #include <editeng/fontitem.hxx> @@ -2374,6 +2375,167 @@ CPPUNIT_TEST_FIXTURE(SwLayoutWriter3, testTdf160526) assertXPath(pExportDump, "//page[2]/body/txt/anchored/SwAnchoredDrawObject"_ostr); } +CPPUNIT_TEST_FIXTURE(SwLayoutWriter3, testTdf160958_page_break) +{ + // Given a document with a section with the first paragraph having a page break + createSwDoc("tdf160958_page_break.fodt"); + auto pExportDump = parseLayoutDump(); + assertXPath(pExportDump, "//page"_ostr, 2); + // A single paragraph on the first page, with 6 lines + assertXPath(pExportDump, "//page[1]/body/txt"_ostr, 1); + assertXPath(pExportDump, "//page[1]/body/txt/SwParaPortion/SwLineLayout"_ostr, 6); + // A section with 7 paragraphs, and two more paragraphs after the section + assertXPath(pExportDump, "//page[2]/body/section"_ostr, 1); + assertXPath(pExportDump, "//page[2]/body/section/txt"_ostr, 7); + assertXPath(pExportDump, "//page[2]/body/section/txt[1]/SwParaPortion"_ostr, 0); + assertXPath(pExportDump, "//page[2]/body/section/txt[2]/SwParaPortion"_ostr, 0); + assertXPath(pExportDump, "//page[2]/body/section/txt[3]/SwParaPortion"_ostr, 0); + assertXPath(pExportDump, "//page[2]/body/section/txt[4]/SwParaPortion/SwLineLayout"_ostr, 5); + assertXPath(pExportDump, "//page[2]/body/section/txt[5]/SwParaPortion"_ostr, 0); + assertXPath(pExportDump, "//page[2]/body/section/txt[6]/SwParaPortion"_ostr, 0); + assertXPath(pExportDump, "//page[2]/body/section/txt[7]/SwParaPortion"_ostr, 0); + assertXPath(pExportDump, "//page[2]/body/txt"_ostr, 2); + assertXPath(pExportDump, "//page[2]/body/txt[1]/SwParaPortion/SwLineLayout"_ostr, 7); + assertXPath(pExportDump, "//page[2]/body/txt[2]/SwParaPortion"_ostr, 0); + + // Hide the section + auto xTextSectionsSupplier = mxComponent.queryThrow<css::text::XTextSectionsSupplier>(); + auto xSections = xTextSectionsSupplier->getTextSections(); + CPPUNIT_ASSERT(xSections); + auto xSection = xSections->getByName(u"Section1"_ustr).queryThrow<css::beans::XPropertySet>(); + xSection->setPropertyValue(u"IsVisible"_ustr, css::uno::Any(false)); + + discardDumpedLayout(); + calcLayout(); + pExportDump = parseLayoutDump(); + assertXPath(pExportDump, "//page"_ostr, 1); + // Three paragraphs and a hidden section on the first page + assertXPath(pExportDump, "//page/body/txt"_ostr, 3); + assertXPath(pExportDump, "//page/body/section"_ostr, 1); + + assertXPath(pExportDump, "//page/body/section/infos/bounds"_ostr, "height"_ostr, "0"); + assertXPath(pExportDump, "//page/body/txt[1]/SwParaPortion/SwLineLayout"_ostr, 6); + assertXPath(pExportDump, "//page/body/section/txt"_ostr, 7); + + assertXPath(pExportDump, "//page/body/txt[2]/SwParaPortion/SwLineLayout"_ostr, 7); + assertXPath(pExportDump, "//page/body/txt[3]/SwParaPortion"_ostr, 0); + + // Show the section again + xSection->setPropertyValue(u"IsVisible"_ustr, css::uno::Any(true)); + + // Check that the layout has been restored + discardDumpedLayout(); + calcLayout(); + pExportDump = parseLayoutDump(); + assertXPath(pExportDump, "//page"_ostr, 2); + assertXPath(pExportDump, "//page[1]/body/txt"_ostr, 1); + assertXPath(pExportDump, "//page[1]/body/txt/SwParaPortion/SwLineLayout"_ostr, 6); + assertXPath(pExportDump, "//page[2]/body/section"_ostr, 1); + assertXPath(pExportDump, "//page[2]/body/section/txt"_ostr, 7); + assertXPath(pExportDump, "//page[2]/body/section/txt[1]/SwParaPortion"_ostr, 0); + assertXPath(pExportDump, "//page[2]/body/section/txt[2]/SwParaPortion"_ostr, 0); + assertXPath(pExportDump, "//page[2]/body/section/txt[3]/SwParaPortion"_ostr, 0); + assertXPath(pExportDump, "//page[2]/body/section/txt[4]/SwParaPortion/SwLineLayout"_ostr, 5); + assertXPath(pExportDump, "//page[2]/body/section/txt[5]/SwParaPortion"_ostr, 0); + assertXPath(pExportDump, "//page[2]/body/section/txt[6]/SwParaPortion"_ostr, 0); + assertXPath(pExportDump, "//page[2]/body/section/txt[7]/SwParaPortion"_ostr, 0); + assertXPath(pExportDump, "//page[2]/body/txt"_ostr, 2); + assertXPath(pExportDump, "//page[2]/body/txt[1]/SwParaPortion/SwLineLayout"_ostr, 7); + assertXPath(pExportDump, "//page[2]/body/txt[2]/SwParaPortion"_ostr, 0); +} + +CPPUNIT_TEST_FIXTURE(SwLayoutWriter3, testTdf160958_orphans) +{ + // Given a document with a section which moves to the next page as a whole, because of orphans + createSwDoc("tdf160958_orphans_move_section.fodt"); + auto pExportDump = parseLayoutDump(); + assertXPath(pExportDump, "//page"_ostr, 2); + // 21 paragraphs on the first page + assertXPath(pExportDump, "//page[1]/body/txt"_ostr, 21); + assertXPath(pExportDump, "//page[1]/body/txt[1]/SwParaPortion/SwLineLayout"_ostr, 6); + assertXPath(pExportDump, "//page[1]/body/txt[2]/SwParaPortion/SwLineLayout"_ostr, 5); + assertXPath(pExportDump, "//page[1]/body/txt[3]/SwParaPortion/SwLineLayout"_ostr, 7); + assertXPath(pExportDump, "//page[1]/body/txt[4]/SwParaPortion/SwLineLayout"_ostr, 16); + assertXPath(pExportDump, "//page[1]/body/txt[5]/SwParaPortion/SwLineLayout"_ostr, 1); + assertXPath(pExportDump, "//page[1]/body/txt[6]/SwParaPortion/SwLineLayout"_ostr, 1); + assertXPath(pExportDump, "//page[1]/body/txt[7]/SwParaPortion/SwLineLayout"_ostr, 1); + assertXPath(pExportDump, "//page[1]/body/txt[8]/SwParaPortion/SwLineLayout"_ostr, 1); + assertXPath(pExportDump, "//page[1]/body/txt[9]/SwParaPortion/SwLineLayout"_ostr, 1); + assertXPath(pExportDump, "//page[1]/body/txt[10]/SwParaPortion/SwLineLayout"_ostr, 1); + assertXPath(pExportDump, "//page[1]/body/txt[11]/SwParaPortion/SwLineLayout"_ostr, 1); + assertXPath(pExportDump, "//page[1]/body/txt[12]/SwParaPortion/SwLineLayout"_ostr, 1); + assertXPath(pExportDump, "//page[1]/body/txt[13]/SwParaPortion/SwLineLayout"_ostr, 1); + assertXPath(pExportDump, "//page[1]/body/txt[14]/SwParaPortion/SwLineLayout"_ostr, 1); + assertXPath(pExportDump, "//page[1]/body/txt[15]/SwParaPortion/SwLineLayout"_ostr, 1); + assertXPath(pExportDump, "//page[1]/body/txt[16]/SwParaPortion/SwLineLayout"_ostr, 1); + assertXPath(pExportDump, "//page[1]/body/txt[17]/SwParaPortion/SwLineLayout"_ostr, 1); + assertXPath(pExportDump, "//page[1]/body/txt[18]/SwParaPortion/SwLineLayout"_ostr, 1); + assertXPath(pExportDump, "//page[1]/body/txt[19]/SwParaPortion/SwLineLayout"_ostr, 1); + assertXPath(pExportDump, "//page[1]/body/txt[20]/SwParaPortion/SwLineLayout"_ostr, 1); + assertXPath(pExportDump, "//page[1]/body/txt[21]/SwParaPortion/SwLineLayout"_ostr, 1); + // A section and one more paragraph after the section + assertXPath(pExportDump, "//page[2]/body/section"_ostr, 1); + assertXPath(pExportDump, "//page[2]/body/section/txt"_ostr, 3); + assertXPath(pExportDump, "//page[2]/body/section/txt[1]/SwParaPortion/SwLineLayout"_ostr, 6); + assertXPath(pExportDump, "//page[2]/body/section/txt[2]/SwParaPortion/SwLineLayout"_ostr, 5); + assertXPath(pExportDump, "//page[2]/body/section/txt[3]/SwParaPortion/SwLineLayout"_ostr, 7); + assertXPath(pExportDump, "//page[2]/body/txt"_ostr, 1); + assertXPath(pExportDump, "//page[2]/body/txt[1]/SwParaPortion/SwLineLayout"_ostr, 1); + + // Hide the section + auto xTextSectionsSupplier = mxComponent.queryThrow<css::text::XTextSectionsSupplier>(); + auto xSections = xTextSectionsSupplier->getTextSections(); + CPPUNIT_ASSERT(xSections); + auto xSection = xSections->getByName(u"Section1"_ustr).queryThrow<css::beans::XPropertySet>(); + xSection->setPropertyValue(u"IsVisible"_ustr, css::uno::Any(false)); + + discardDumpedLayout(); + calcLayout(); + pExportDump = parseLayoutDump(); + assertXPath(pExportDump, "//page"_ostr, 1); + assertXPath(pExportDump, "//page/body/txt"_ostr, 22); + assertXPath(pExportDump, "//page/body/section"_ostr, 1); + assertXPath(pExportDump, "//page/body/section/infos/bounds"_ostr, "height"_ostr, "0"); + + // Show the section again + xSection->setPropertyValue(u"IsVisible"_ustr, css::uno::Any(true)); + + // Check that the layout has been restored + discardDumpedLayout(); + calcLayout(); + pExportDump = parseLayoutDump(); + assertXPath(pExportDump, "//page"_ostr, 2); + assertXPath(pExportDump, "//page[1]/body/txt"_ostr, 21); + assertXPath(pExportDump, "//page[1]/body/txt[1]/SwParaPortion/SwLineLayout"_ostr, 6); + assertXPath(pExportDump, "//page[1]/body/txt[2]/SwParaPortion/SwLineLayout"_ostr, 5); + assertXPath(pExportDump, "//page[1]/body/txt[3]/SwParaPortion/SwLineLayout"_ostr, 7); + assertXPath(pExportDump, "//page[1]/body/txt[4]/SwParaPortion/SwLineLayout"_ostr, 16); + assertXPath(pExportDump, "//page[1]/body/txt[5]/SwParaPortion/SwLineLayout"_ostr, 1); + assertXPath(pExportDump, "//page[1]/body/txt[6]/SwParaPortion/SwLineLayout"_ostr, 1); + assertXPath(pExportDump, "//page[1]/body/txt[7]/SwParaPortion/SwLineLayout"_ostr, 1); + assertXPath(pExportDump, "//page[1]/body/txt[8]/SwParaPortion/SwLineLayout"_ostr, 1); + assertXPath(pExportDump, "//page[1]/body/txt[9]/SwParaPortion/SwLineLayout"_ostr, 1); + assertXPath(pExportDump, "//page[1]/body/txt[10]/SwParaPortion/SwLineLayout"_ostr, 1); + assertXPath(pExportDump, "//page[1]/body/txt[11]/SwParaPortion/SwLineLayout"_ostr, 1); + assertXPath(pExportDump, "//page[1]/body/txt[12]/SwParaPortion/SwLineLayout"_ostr, 1); + assertXPath(pExportDump, "//page[1]/body/txt[13]/SwParaPortion/SwLineLayout"_ostr, 1); + assertXPath(pExportDump, "//page[1]/body/txt[14]/SwParaPortion/SwLineLayout"_ostr, 1); + assertXPath(pExportDump, "//page[1]/body/txt[15]/SwParaPortion/SwLineLayout"_ostr, 1); + assertXPath(pExportDump, "//page[1]/body/txt[16]/SwParaPortion/SwLineLayout"_ostr, 1); + assertXPath(pExportDump, "//page[1]/body/txt[17]/SwParaPortion/SwLineLayout"_ostr, 1); + assertXPath(pExportDump, "//page[1]/body/txt[18]/SwParaPortion/SwLineLayout"_ostr, 1); + assertXPath(pExportDump, "//page[1]/body/txt[19]/SwParaPortion/SwLineLayout"_ostr, 1); + assertXPath(pExportDump, "//page[1]/body/txt[20]/SwParaPortion/SwLineLayout"_ostr, 1); + assertXPath(pExportDump, "//page[1]/body/txt[21]/SwParaPortion/SwLineLayout"_ostr, 1); + assertXPath(pExportDump, "//page[2]/body/section"_ostr, 1); + assertXPath(pExportDump, "//page[2]/body/section/txt"_ostr, 3); + assertXPath(pExportDump, "//page[2]/body/section/txt[1]/SwParaPortion/SwLineLayout"_ostr, 6); + assertXPath(pExportDump, "//page[2]/body/section/txt[2]/SwParaPortion/SwLineLayout"_ostr, 5); + assertXPath(pExportDump, "//page[2]/body/section/txt[3]/SwParaPortion/SwLineLayout"_ostr, 7); + assertXPath(pExportDump, "//page[2]/body/txt"_ostr, 1); + assertXPath(pExportDump, "//page[2]/body/txt[1]/SwParaPortion/SwLineLayout"_ostr, 1); +} + 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 78278da9cb38..e051d056b081 100644 --- a/sw/source/core/layout/sectfrm.cxx +++ b/sw/source/core/layout/sectfrm.cxx @@ -833,6 +833,42 @@ void SwSectionFrame::MakeAll(vcl::RenderContext* pRenderContext) setFramePrintAreaValid(true); return; } + + if (!GetPrev() && !IsFollow() && IsInDocBody() && IsHiddenNow()) + { + // This may be the first frame on a page, and it may had moved to that page because its + // content required that (a page break in the first paragraph, or a tall first line, or + // "do not break paragraph" setting, or the like). Try to move back, to allow following + // frames to move back, if possible. Sections cannot move back; workaround by a call to + // GetPrevSctLeaf(), which may return a candidate upper frame on a previous page, or it + // may create a new master for this at the end of the previous page. Cut and paste this + // appropriately; then drop the temporary, if needed. + if (SwLayoutFrame* moveBackPos = GetPrevSctLeaf()) + { + SwLayoutFrame* newUpper = moveBackPos; + SwFrame* newSibling = nullptr; + const bool temporaryMasterCreated = IsFollow(); + if (temporaryMasterCreated) + { + assert(moveBackPos == &GetPrecede()->GetFrame()); + newUpper = moveBackPos->GetUpper(); + newSibling = moveBackPos->GetNext(); // actually, will be also nullptr + } + if (newUpper != GetUpper()) + { + // Can't use MoveSubTree, because the move needs to fire events to re-layout + Cut(); + Paste(newUpper, newSibling); + } + if (temporaryMasterCreated) + { + moveBackPos->Cut(); + DestroyFrame(moveBackPos); + } + assert(!IsFollow()); + } + } + LockJoin(); // I don't let myself to be destroyed on the way while( GetNext() && GetNext() == GetFollow() ) @@ -843,6 +879,17 @@ void SwSectionFrame::MakeAll(vcl::RenderContext* pRenderContext) break; } + if (GetFollow() && IsHiddenNow()) + { + // Merge all the follows of this hidden section + while (auto* follow = GetFollow()) + { + MergeNext(follow); + if (GetFollow() == follow) // failed to merge + break; // avoid endless loop + } + } + // OD 2004-03-15 #116561# - In online layout join the follows, if section // can grow. const SwViewShell *pSh = getRootFrame()->GetCurrShell(); @@ -2677,6 +2724,11 @@ void SwSectionFrame::SwClientNotify(const SwModify& rMod, const SfxHint& rHint) { InvalidateAll(); InvalidateObjs(false); + { + // Set it to a huge positive value, to make sure a recalculation fires + SwFrameAreaDefinition::FrameAreaWriteAccess area(*this); + SwRectFnSet(this).SetHeight(area, std::numeric_limits<tools::Long>::max()); + } for (SwFrame* pLowerFrame = Lower(); pLowerFrame; pLowerFrame = pLowerFrame->GetNext()) {