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();