tdf#145998 sw ms export: use page break, not section break
If possible, use a simple page break instead of a section break.
Eliminate unnecessary "page style" changes. If the page will
become that style anyway, then a simple page break will suffice.
The benefit is primarily for LO import, since it is virtually
impossible on import to know if a section is identical
to the previous section. Thus we have previously multiplied
page styles - often redundantly.
This also starts to fix a real problem with first headers showing up
on an unnecessary new page style. Unit test deals with this.
Change-Id: Ib9e24bbd579b29aa21efb2b85750ecfcb8c7e5cb
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/137273
Tested-by: Jenkins
Reviewed-by: Justin Luth <jluth@mail.com>
diff --git a/sw/qa/extras/ooxmlexport/data/tdf145998_unnecessaryPageStyles.odt b/sw/qa/extras/ooxmlexport/data/tdf145998_unnecessaryPageStyles.odt
new file mode 100644
index 0000000..82087eb
--- /dev/null
+++ b/sw/qa/extras/ooxmlexport/data/tdf145998_unnecessaryPageStyles.odt
Binary files differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport15.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport15.cxx
index 1537739..d1c565e 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport15.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport15.cxx
@@ -475,6 +475,36 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf98000_changePageStyle)
CPPUNIT_ASSERT_MESSAGE("Different page1/page2 styles", sPageOneStyle != sPageTwoStyle);
}
CPPUNIT_TEST_FIXTURE(Test, testTdf145998_unnecessaryPageStyles)
{
loadAndReload("tdf145998_unnecessaryPageStyles.odt");
// Sanity check - always good to test when dealing with page styles and breaks.
CPPUNIT_ASSERT_EQUAL(5, getPages());
// Page Style should be explicitly mentioned - otherwise it would be a "follow" style
uno::Reference<beans::XPropertySet> xPara(getParagraph(2, "2"), uno::UNO_QUERY_THROW);
CPPUNIT_ASSERT(uno::Any() != xPara->getPropertyValue("PageDescName"));
// CPPUNIT_ASSERT_EQUAL(OUString("First Page header"),
// parseDump("/root/page[2]/header/txt"));
// Page Style is converted into a page break instead. Still shows "first" header.
xPara.set(getParagraph(3, "3"), uno::UNO_QUERY_THROW);
CPPUNIT_ASSERT_EQUAL(uno::Any(), xPara->getPropertyValue("PageDescName"));
// CPPUNIT_ASSERT_EQUAL(OUString("Default page style - first page style"),
// parseDump("/root/page[3]/header/txt"));
// Page Style is converted into a page break instead. Shows the "normal" header.
xPara.set(getParagraph(5, "4"), uno::UNO_QUERY_THROW);
CPPUNIT_ASSERT_EQUAL(uno::Any(), xPara->getPropertyValue("PageDescName"));
CPPUNIT_ASSERT_EQUAL(OUString("Default page style"),
parseDump("/root/page[4]/header/txt"));
// Page Style is retained (with wrong header) in order to preserve page re-numbering.
xPara.set(getParagraph(7, "1"), uno::UNO_QUERY_THROW);
CPPUNIT_ASSERT(uno::Any() != xPara->getPropertyValue("PageDescName"));
}
CPPUNIT_TEST_FIXTURE(Test, testTdf135216_evenOddFooter)
{
loadAndReload("tdf135216_evenOddFooter.odt");
diff --git a/sw/source/filter/ww8/ww8atr.cxx b/sw/source/filter/ww8/ww8atr.cxx
index 3ee28ea..cb86dd3 100644
--- a/sw/source/filter/ww8/ww8atr.cxx
+++ b/sw/source/filter/ww8/ww8atr.cxx
@@ -520,7 +520,23 @@ void MSWordExportBase::OutputSectionBreaks( const SfxItemSet *pSet, const SwNode
if ( pItem && pItem->GetRegisteredIn() != nullptr)
{
bBreakSet = true;
bNewPageDesc = true;
// Avoid unnecessary section breaks if possible. LO can't notice identical
// sections during import, so minimize unnecessary duplication
// by substituting a simple page break when the resulting section is identical,
// unless this is needed to re-number the page.
if (!bNewPageDesc && !pItem->GetNumOffset() && m_pCurrentPageDesc
&& m_pCurrentPageDesc->GetFollow() == pItem->GetPageDesc())
{
// A section break on the very first paragraph is ignored by LO/Word
// and should NOT be turned into a page break.
SwNodeIndex aDocEnd(m_rDoc.GetNodes().GetEndOfContent());
SwNodeIndex aStart(*aDocEnd.GetNode().StartOfSectionNode(), 2);
if (rNd.GetIndex() > aStart.GetNode().GetIndex())
AttrOutput().OutputItem(SvxFormatBreakItem(SvxBreak::PageBefore, RES_BREAK));
}
else
bNewPageDesc = true;
pPgDesc = pItem;
m_pCurrentPageDesc = pPgDesc->GetPageDesc();