sw/qa/extras/ooxmlexport/data/tdf69635.docx   |binary
 sw/qa/extras/ooxmlexport/ooxmlexport14.cxx    |    5 +
 sw/qa/extras/ooxmlexport/ooxmlexport16.cxx    |   56 +++++++++++++++
 sw/qa/extras/ooxmlexport/ooxmlexport4.cxx     |   22 +++---
 sw/qa/extras/ooxmlexport/ooxmlexport5.cxx     |    6 -
 sw/qa/extras/ooxmlexport/ooxmlexport6.cxx     |    2 
 sw/qa/extras/ooxmlexport/ooxmlexport7.cxx     |   12 +--
 sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx |    2 
 sw/source/filter/ww8/docxexport.cxx           |    9 +-
 sw/source/filter/ww8/docxexport.hxx           |    3 
 sw/source/filter/ww8/rtfexport.cxx            |   10 +-
 sw/source/filter/ww8/rtfexport.hxx            |    6 +
 sw/source/filter/ww8/wrtw8sty.cxx             |   95 +++++++++++++++++++++++---
 sw/source/filter/ww8/wrtww8.hxx               |    8 +-
 14 files changed, 189 insertions(+), 47 deletions(-)

New commits:
commit d9caf9814696c747e4b0277bc7377ba09aead334
Author:     Daniel Arato (NISZ) <arato.dan...@nisz.hu>
AuthorDate: Fri Feb 5 12:07:48 2021 +0100
Commit:     Tünde Tóth <toth.tu...@nisz.hu>
CommitDate: Thu Oct 21 11:42:19 2021 +0200

    tdf#69635 DOCX: export hidden (shared) headers/footers
    
    Exporting to .docx used to lose all header and footer
    content that was not visible in the document at the
    moment of saving. This commit forces the DocxExport
    class to output all headers and footers even when
    the "Same content on left and right pages" option
    is turned on.
    
    Change-Id: I6a52f216f1e1b386d887ec614198766670b5bce3
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/113158
    Tested-by: László Németh <nem...@numbertext.org>
    Reviewed-by: László Németh <nem...@numbertext.org>
    (cherry picked from commit 88e6a1bfeac86e0c89d2ff08c908c2b5ae061177)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/123970
    Tested-by: Tünde Tóth <toth.tu...@nisz.hu>
    Reviewed-by: Tünde Tóth <toth.tu...@nisz.hu>

diff --git a/sw/qa/extras/ooxmlexport/data/tdf69635.docx 
b/sw/qa/extras/ooxmlexport/data/tdf69635.docx
new file mode 100644
index 000000000000..94cced4d2ae4
Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/tdf69635.docx differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport14.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport14.cxx
index a740b6295999..2ee47d611adf 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport14.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport14.cxx
@@ -671,7 +671,12 @@ 
DECLARE_OOXMLEXPORT_TEST(testTdf130167_spilloverHeaderShape, "testTdf130167_spil
     uno::Reference<container::XIndexAccess> xNameAccess(
         xTextGraphicObjectsSupplier->getGraphicObjects(), uno::UNO_QUERY);
     // graphics from discarded headers were being added to the text body. 
Reduced from 5 to 2 shapes overall.
+<<<<<<< HEAD   (7b6bf0 tdf#142128 sw: set author-color strikethrough for 
AS_CHAR im)
     CPPUNIT_ASSERT(xNameAccess->getCount() < 4);
+=======
+    // CPPUNIT_ASSERT(xNameAccess->getCount() <= 4); -> What about hidden 
headers?
+    CPPUNIT_ASSERT_LESS(sal_Int32(9), xNameAccess->getCount());
+>>>>>>> CHANGE (88e6a1 tdf#69635 DOCX: export hidden (shared) headers/footers)
 }
 
 DECLARE_OOXMLEXPORT_TEST(testTdf124986, "tdf124986.docx")
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport16.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport16.cxx
index 7e890145210d..a20c8bfb9fe3 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport16.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport16.cxx
@@ -50,6 +50,62 @@ DECLARE_OOXMLEXPORT_TEST(testTdf138892_noNumbering, 
"tdf138892_noNumbering.docx"
     CPPUNIT_ASSERT_MESSAGE("Para3: <blank line>", 
getProperty<OUString>(getParagraph(3), "NumberingStyleName").isEmpty());
 }
 
+DECLARE_OOXMLEXPORT_TEST(testTdf141231_arabicHebrewNumbering, 
"tdf141231_arabicHebrewNumbering.docx")
+{
+    // The page's numbering type: instead of Hebrew, this was default 
style::NumberingType::ARABIC (4).
+    auto nActual = 
getProperty<sal_Int16>(getStyles("PageStyles")->getByName("Standard"), 
"NumberingType");
+    CPPUNIT_ASSERT_EQUAL(style::NumberingType::NUMBER_HEBREW, nActual);
+
+    // The footnote numbering type: instead of arabicAbjad, this was the 
default style::NumberingType::ARABIC.
+    uno::Reference<text::XFootnotesSupplier> xFootnotesSupplier(mxComponent, 
uno::UNO_QUERY);
+    uno::Reference<beans::XPropertySet> xFootnoteSettings = 
xFootnotesSupplier->getFootnoteSettings();
+    nActual = 
getProperty<sal_Int16>(xFootnotesSupplier->getFootnoteSettings(), 
"NumberingType");
+    CPPUNIT_ASSERT_EQUAL(style::NumberingType::CHARS_ARABIC_ABJAD, nActual);
+}
+
+DECLARE_OOXMLEXPORT_TEST(testGutterLeft, "gutter-left.docx")
+{
+    uno::Reference<beans::XPropertySet> xPageStyle;
+    getStyles("PageStyles")->getByName("Standard") >>= xPageStyle;
+    sal_Int32 nGutterMargin{};
+    xPageStyle->getPropertyValue("GutterMargin") >>= nGutterMargin;
+    // Without the accompanying fix in place, this test would have failed with:
+    // - Expected: 1270
+    // - Actual  : 0
+    // i.e. gutter margin was lost.
+    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1270), nGutterMargin);
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testGutterTop)
+{
+    load(mpTestDocumentPath, "gutter-top.docx");
+    save("Office Open XML Text", maTempFile);
+    mbExported = true;
+    xmlDocUniquePtr pXmlSettings = parseExport("word/settings.xml");
+    CPPUNIT_ASSERT(pXmlSettings);
+    // Without the accompanying fix in place, this test would have failed with:
+    // - Expected: 1
+    // - Actual  : 0
+    // i.e. <w:gutterAtTop> was lost.
+    assertXPath(pXmlSettings, "/w:settings/w:gutterAtTop", 1);
+}
+
+DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testTdf69635, "tdf69635.docx")
+{
+    xmlDocUniquePtr pXmlHeader1 = parseExport("word/header1.xml");
+    xmlDocUniquePtr pXmlSettings = parseExport("word/settings.xml");
+    CPPUNIT_ASSERT(pXmlHeader1);
+    CPPUNIT_ASSERT(pXmlSettings);
+
+    // Without the accompanying fix in place, this test would have failed with:
+    // - Expected: "left"
+    // - Actual  : "right"
+    assertXPathContent(pXmlHeader1, "/w:hdr/w:p/w:r/w:t", "left");
+
+    // Make sure "left" appears as a hidden header
+    assertXPath(pXmlSettings, "/w:settings/w:evenAndOddHeaders", 0);
+}
+
 DECLARE_OOXMLEXPORT_TEST(testTdf140668, "tdf140668.docx")
 {
     // Don't crash when document is opened
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport4.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport4.cxx
index 49cc931b1b27..dcf7062eca36 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport4.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport4.cxx
@@ -399,10 +399,10 @@ DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testChartInFooter, 
"chart-in-footer.docx")
     // fdo#73872: document contains chart in footer.
     // The problem was that  footer1.xml.rels files for footer1.xml
     // files were missing from docx file after roundtrip.
-    xmlDocUniquePtr pXmlDoc = parseExport("word/_rels/footer1.xml.rels");
+    xmlDocUniquePtr pXmlDoc = parseExport("word/_rels/footer2.xml.rels");
 
-    // Check footer1.xml.rels contains in doc after roundtrip.
-    // Check Id = rId1 in footer1.xml.rels
+    // Check footer2.xml.rels contains in doc after roundtrip.
+    // Check Id = rId1 in footer2.xml.rels
     assertXPath(pXmlDoc,"/rels:Relationships/rels:Relationship","Id","rId1");
     assertXPath(pXmlDoc,
         "/rels:Relationships/rels:Relationship[@Id='rId1']",
@@ -416,12 +416,12 @@ DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testChartInFooter, 
"chart-in-footer.docx")
         "application/vnd.openxmlformats-officedocument.drawingml.chart+xml");
 
     // check the content too
-    xmlDocUniquePtr pXmlDocFooter1 = parseExport("word/footer1.xml");
-    assertXPath(pXmlDocFooter1,
+    xmlDocUniquePtr pXmlDocFooter2 = parseExport("word/footer2.xml");
+    assertXPath(pXmlDocFooter2,
         "/w:ftr/w:p[1]/w:r/w:drawing/wp:inline/a:graphic/a:graphicData",
         "uri",
         "http://schemas.openxmlformats.org/drawingml/2006/chart";);
-    assertXPath(pXmlDocFooter1,
+    assertXPath(pXmlDocFooter2,
         
"/w:ftr/w:p[1]/w:r/w:drawing/wp:inline/a:graphic/a:graphicData/c:chart",
         "id",
         "rId1");
@@ -837,7 +837,7 @@ DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testOLEObjectinHeader, 
"2129393649.docx")
     // Problem was relationship entry for oleobject from header was
     // exported into document.xml.rels file because of this rels file
     // for headers were missing from document/word/rels.
-    xmlDocUniquePtr pXmlDoc = parseExport("word/_rels/header1.xml.rels");
+    xmlDocUniquePtr pXmlDoc = parseExport("word/_rels/header2.xml.rels");
 
     
assertXPath(pXmlDoc,"/rels:Relationships/rels:Relationship[1]","Id","rId1");
 
@@ -850,12 +850,12 @@ 
DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testOLEObjectinHeader, "2129393649.docx")
         "application/vnd.openxmlformats-officedocument.oleObject");
 
     // check the content too
-    xmlDocUniquePtr pXmlDocHeader1 = parseExport("word/header1.xml");
-    assertXPath(pXmlDocHeader1,
+    xmlDocUniquePtr pXmlDocHeader2 = parseExport("word/header2.xml");
+    assertXPath(pXmlDocHeader2,
         "/w:hdr/w:tbl/w:tr[1]/w:tc[2]/w:p[1]/w:r/w:object/o:OLEObject",
         "ProgID",
         "Word.Picture.8");
-    xmlDocUniquePtr pXmlDocHeader2 = parseExport("word/header2.xml");
+    xmlDocUniquePtr pXmlDocHeader3 = parseExport("word/header3.xml");
     assertXPath(pXmlDocHeader2,
         "/w:hdr/w:tbl/w:tr[1]/w:tc[2]/w:p[1]/w:r/w:object/o:OLEObject",
         "ProgID",
@@ -1031,7 +1031,7 @@ DECLARE_OOXMLEXPORT_TEST(testTdf103001, "tdf103001.docx")
     uno::Reference<packages::zip::XZipFileAccess2> xNameAccess = 
packages::zip::ZipFileAccess::createWithURL(comphelper::getComponentContext(m_xSFactory),
 maTempFile.GetURL());
     // This failed: header reused the RelId of the body text, even if RelIds
     // are local to their stream.
-    CPPUNIT_ASSERT(xNameAccess->hasByName("word/_rels/header1.xml.rels"));
+    CPPUNIT_ASSERT(xNameAccess->hasByName("word/_rels/header2.xml.rels"));
 }
 
 DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testTdf92521, "tdf92521.odt")
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport5.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport5.cxx
index 404db9c59ef9..7021aa2c9c65 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport5.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport5.cxx
@@ -1031,7 +1031,7 @@ DECLARE_OOXMLEXPORT_TEST(test2colHeader, 
"2col-header.docx")
 DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testfdo83048, "fdo83048.docx")
 {
     // Issue was wrong SDT properties were getting exported for Date SDT
-    xmlDocUniquePtr pXmlDoc = parseExport("word/footer1.xml");
+    xmlDocUniquePtr pXmlDoc = parseExport("word/footer2.xml");
 
     // Make sure Date is inside SDT tag.
     // This will happen only if right SDT properties are exported.
@@ -1052,7 +1052,7 @@ DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testSdt2Run, 
"sdt-2-run.docx")
 
 DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testFD083057, "fdo83057.docx")
 {
-    xmlDocUniquePtr pXmlDoc = parseExport("word/header1.xml");
+    xmlDocUniquePtr pXmlDoc = parseExport("word/header2.xml");
 
     // A fly frame was attached to a para which started with a hint (run) 
containing an SDT.
     // This SDT was handled while exporting the FLYFRAME and also the text of 
the run.
@@ -1341,7 +1341,7 @@ DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testTdf112287, 
"tdf112287.docx")
 DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testZOrderInHeader, 
"tdf120760_ZOrderInHeader.docx")
 {
     // tdf#120760 Check that the Z-Order of the background is smaller than the 
front shape's.
-    xmlDocUniquePtr pXml = parseExport("word/header1.xml");
+    xmlDocUniquePtr pXml = parseExport("word/header2.xml");
 
     // Get the Z-Order of the background image and of the shape in front of it.
     sal_Int32 nBackground = getXPath(pXml, 
"/w:hdr/w:p[1]/w:r[1]/w:drawing/wp:anchor", "relativeHeight").toInt32();
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport6.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport6.cxx
index cc63f77e5c56..21a4d11a9dde 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport6.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport6.cxx
@@ -852,7 +852,7 @@ 
DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testShapeThemePreservation, "shape-theme-pre
 
 DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testFDO73546, "FDO73546.docx")
 {
-    xmlDocUniquePtr pXmlDoc = parseExport("word/header1.xml");
+    xmlDocUniquePtr pXmlDoc = parseExport("word/header2.xml");
     assertXPath(pXmlDoc, 
"/w:hdr/w:p[1]/w:r[3]/mc:AlternateContent/mc:Choice/w:drawing/wp:anchor", 
"distL","0");
 }
 
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport7.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport7.cxx
index 2e8c2c45aa42..243e2371476f 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport7.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport7.cxx
@@ -102,12 +102,12 @@ DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testTextWatermark, 
"textWatermark.docx")
     //The problem was that the watermark ID was not preserved,
     //and Word uses the object ID to identify if it is a watermark.
     //It has to have the 'PowerPlusWaterMarkObject' string in it
-    xmlDocUniquePtr pXmlHeader1 = parseExport("word/header1.xml");
+    xmlDocUniquePtr pXmlHeader2 = parseExport("word/header2.xml");
 
-    assertXPath(pXmlHeader1, 
"/w:hdr[1]/w:p[1]/w:r[1]/w:pict[1]/v:shape[1]","id","PowerPlusWaterMarkObject93701316");
+    assertXPath(pXmlHeader2, 
"/w:hdr[1]/w:p[1]/w:r[1]/w:pict[1]/v:shape[1]","id","PowerPlusWaterMarkObject93701316");
 
     //The second problem was that Word uses also "o:spid"
-    const OUString& sSpid = getXPath(pXmlHeader1, 
"/w:hdr[1]/w:p[1]/w:r[1]/w:pict[1]/v:shape[1]","spid");
+    const OUString& sSpid = getXPath(pXmlHeader2, 
"/w:hdr[1]/w:p[1]/w:r[1]/w:pict[1]/v:shape[1]","spid");
     CPPUNIT_ASSERT(!sSpid.isEmpty());
 }
 
@@ -117,10 +117,10 @@ DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testPictureWatermark, 
"pictureWatermark.docx
     //and Word uses the object ID to identify if it is a watermark.
     //It has to have the 'WordPictureWaterMarkObject' string in it
 
-    xmlDocUniquePtr pXmlHeader1 = parseExport("word/header1.xml");
+    xmlDocUniquePtr pXmlHeader2 = parseExport("word/header2.xml");
 
     // Check the watermark ID
-    assertXPath(pXmlHeader1, 
"/w:hdr[1]/w:p[1]/w:r[1]/mc:AlternateContent[1]/mc:Fallback[1]/w:pict[1]/v:shape[1]","id","WordPictureWatermark11962361");
+    assertXPath(pXmlHeader2, 
"/w:hdr[1]/w:p[1]/w:r[1]/mc:AlternateContent[1]/mc:Fallback[1]/w:pict[1]/v:shape[1]","id","WordPictureWatermark11962361");
 }
 
 
@@ -882,7 +882,7 @@ DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testfdo80895, 
"fdo80895.docx")
     // resultant shape was with <a:noFill/> prop in <wps:spPr> hence was not 
visible.
     // Checking there is a shape in header without <a:noFill/> element.
 
-    xmlDocUniquePtr pXmlDoc = parseExport("word/header1.xml");
+    xmlDocUniquePtr pXmlDoc = parseExport("word/header2.xml");
     assertXPath(pXmlDoc, 
"/w:hdr/w:p/w:r/mc:AlternateContent/mc:Choice/w:drawing/wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:spPr/a:noFill",0);
     assertXPath(pXmlDoc, 
"/w:hdr/w:p/w:r/mc:AlternateContent/mc:Choice/w:drawing/wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:spPr/a:ln/a:noFill",0);
 
diff --git a/sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx
index 40f93ab67664..f93d5b924ea4 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx
@@ -536,7 +536,7 @@ DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testfdo82492, 
"fdo82492.docx")
 DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testSdtHeader, "sdt-header.docx")
 {
     // Problem was that w:sdt elements in headers were lost on import.
-    xmlDocUniquePtr pXmlDoc = parseExport("word/header1.xml");
+    xmlDocUniquePtr pXmlDoc = parseExport("word/header2.xml");
     // This was 0, w:sdt (and then w:date) was missing.
     assertXPath(pXmlDoc, "//w:sdt/w:sdtPr/w:date", 1);
 }
diff --git a/sw/source/filter/ww8/docxexport.cxx 
b/sw/source/filter/ww8/docxexport.cxx
index 3d09820e545e..86485359b60e 100644
--- a/sw/source/filter/ww8/docxexport.cxx
+++ b/sw/source/filter/ww8/docxexport.cxx
@@ -247,12 +247,13 @@ bool DocxExport::DisallowInheritingOutlineNumbering( 
const SwFormat& rFormat )
 }
 
 void DocxExport::WriteHeadersFooters( sal_uInt8 nHeadFootFlags,
-        const SwFrameFormat& rFormat, const SwFrameFormat& rLeftFormat, const 
SwFrameFormat& rFirstPageFormat, sal_uInt8 nBreakCode )
+        const SwFrameFormat& rFormat, const SwFrameFormat& rLeftHeaderFormat, 
const SwFrameFormat& rLeftFooterFormat, const SwFrameFormat& rFirstPageFormat,
+        sal_uInt8 nBreakCode, bool bEvenAndOddHeaders )
 {
     m_nHeadersFootersInSection = 1;
 
     // document setting indicating the requirement of EVEN and ODD for both 
headers and footers
-    if ( nHeadFootFlags & ( nsHdFtFlags::WW8_FOOTER_EVEN | 
nsHdFtFlags::WW8_HEADER_EVEN ))
+    if ( nHeadFootFlags & ( nsHdFtFlags::WW8_FOOTER_EVEN | 
nsHdFtFlags::WW8_HEADER_EVEN ) && bEvenAndOddHeaders )
         m_aSettings.evenAndOddHeaders = true;
 
     // Turn ON flag for 'Writing Headers \ Footers'
@@ -260,7 +261,7 @@ void DocxExport::WriteHeadersFooters( sal_uInt8 
nHeadFootFlags,
 
     // headers
     if ( nHeadFootFlags & nsHdFtFlags::WW8_HEADER_EVEN )
-        WriteHeaderFooter( &rLeftFormat, true, "even" );
+        WriteHeaderFooter( &rLeftHeaderFormat, true, "even" );
     else if ( m_aSettings.evenAndOddHeaders )
     {
         if ( nHeadFootFlags & nsHdFtFlags::WW8_HEADER_ODD )
@@ -284,7 +285,7 @@ void DocxExport::WriteHeadersFooters( sal_uInt8 
nHeadFootFlags,
 
     // footers
     if ( nHeadFootFlags & nsHdFtFlags::WW8_FOOTER_EVEN )
-        WriteHeaderFooter( &rLeftFormat, false, "even" );
+        WriteHeaderFooter( &rLeftFooterFormat, false, "even" );
     else if ( m_aSettings.evenAndOddHeaders )
     {
         if ( nHeadFootFlags & nsHdFtFlags::WW8_FOOTER_ODD )
diff --git a/sw/source/filter/ww8/docxexport.hxx 
b/sw/source/filter/ww8/docxexport.hxx
index f800b5018e66..e87cb3a3788d 100644
--- a/sw/source/filter/ww8/docxexport.hxx
+++ b/sw/source/filter/ww8/docxexport.hxx
@@ -161,7 +161,8 @@ public:
 
     /// Output the actual headers and footers.
     virtual void WriteHeadersFooters( sal_uInt8 nHeadFootFlags,
-            const SwFrameFormat& rFormat, const SwFrameFormat& rLeftFormat, 
const SwFrameFormat& rFirstPageFormat, sal_uInt8 nBreakCode ) override;
+            const SwFrameFormat& rFormat, const SwFrameFormat& 
rLeftHeaderFormat, const SwFrameFormat& rLeftFooterFormat, const SwFrameFormat& 
rFirstPageFormat,
+            sal_uInt8 nBreakCode, bool bEvenAndOddHeaders ) override;
 
     /// Write the field
     virtual void OutputField( const SwField* pField, ww::eField eFieldType,
diff --git a/sw/source/filter/ww8/rtfexport.cxx 
b/sw/source/filter/ww8/rtfexport.cxx
index 7192308f0d6e..858b3a3e2884 100644
--- a/sw/source/filter/ww8/rtfexport.cxx
+++ b/sw/source/filter/ww8/rtfexport.cxx
@@ -286,12 +286,14 @@ void RtfExport::WriteRevTab()
 }
 
 void RtfExport::WriteHeadersFooters(sal_uInt8 nHeadFootFlags, const 
SwFrameFormat& rFormat,
-                                    const SwFrameFormat& rLeftFormat,
-                                    const SwFrameFormat& rFirstPageFormat, 
sal_uInt8 /*nBreakCode*/)
+                                    const SwFrameFormat& rLeftHeaderFormat,
+                                    const SwFrameFormat& rLeftFooterFormat,
+                                    const SwFrameFormat& rFirstPageFormat, 
sal_uInt8 /*nBreakCode*/,
+                                    bool /*bEvenAndOddHeaders*/)
 {
     // headers
     if (nHeadFootFlags & nsHdFtFlags::WW8_HEADER_EVEN)
-        WriteHeaderFooter(rLeftFormat, true, OOO_STRING_SVTOOLS_RTF_HEADERL);
+        WriteHeaderFooter(rLeftHeaderFormat, true, 
OOO_STRING_SVTOOLS_RTF_HEADERL);
 
     if (nHeadFootFlags & nsHdFtFlags::WW8_HEADER_ODD)
         WriteHeaderFooter(rFormat, true, OOO_STRING_SVTOOLS_RTF_HEADER);
@@ -301,7 +303,7 @@ void RtfExport::WriteHeadersFooters(sal_uInt8 
nHeadFootFlags, const SwFrameForma
 
     // footers
     if (nHeadFootFlags & nsHdFtFlags::WW8_FOOTER_EVEN)
-        WriteHeaderFooter(rLeftFormat, false, OOO_STRING_SVTOOLS_RTF_FOOTERL);
+        WriteHeaderFooter(rLeftFooterFormat, false, 
OOO_STRING_SVTOOLS_RTF_FOOTERL);
 
     if (nHeadFootFlags & nsHdFtFlags::WW8_FOOTER_ODD)
         WriteHeaderFooter(rFormat, false, OOO_STRING_SVTOOLS_RTF_FOOTER);
diff --git a/sw/source/filter/ww8/rtfexport.hxx 
b/sw/source/filter/ww8/rtfexport.hxx
index 83b9a34a9e76..9b33c1304659 100644
--- a/sw/source/filter/ww8/rtfexport.hxx
+++ b/sw/source/filter/ww8/rtfexport.hxx
@@ -94,8 +94,10 @@ public:
 
     /// Output the actual headers and footers.
     void WriteHeadersFooters(sal_uInt8 nHeadFootFlags, const SwFrameFormat& 
rFormat,
-                             const SwFrameFormat& rLeftFormat,
-                             const SwFrameFormat& rFirstPageFormat, sal_uInt8 
nBreakCode) override;
+                             const SwFrameFormat& rLeftHeaderFormat,
+                             const SwFrameFormat& rLeftFooterFormat,
+                             const SwFrameFormat& rFirstPageFormat, sal_uInt8 
nBreakCode,
+                             bool bEvenAndOddHeaders) override;
 
     /// Write the field
     void OutputField(const SwField* pField, ww::eField eFieldType, const 
OUString& rFieldCmd,
diff --git a/sw/source/filter/ww8/wrtw8sty.cxx 
b/sw/source/filter/ww8/wrtw8sty.cxx
index 282bd90efab9..08e54ab628cf 100644
--- a/sw/source/filter/ww8/wrtw8sty.cxx
+++ b/sw/source/filter/ww8/wrtw8sty.cxx
@@ -1501,7 +1501,7 @@ void WW8AttributeOutput::TextVerticalAdjustment( const 
drawing::TextVerticalAdju
 }
 
 void WW8Export::WriteHeadersFooters( sal_uInt8 nHeadFootFlags,
-        const SwFrameFormat& rFormat, const SwFrameFormat& rLeftFormat, const 
SwFrameFormat& rFirstPageFormat, sal_uInt8 nBreakCode )
+        const SwFrameFormat& rFormat, const SwFrameFormat& rLeftHeaderFormat, 
const SwFrameFormat& rLeftFooterFormat, const SwFrameFormat& rFirstPageFormat, 
sal_uInt8 nBreakCode, bool /*bEvenAndOddHeaders*/ )
 {
     sal_uLong nCpPos = Fc2Cp( Strm().Tell() );
 
@@ -1509,7 +1509,7 @@ void WW8Export::WriteHeadersFooters( sal_uInt8 
nHeadFootFlags,
     if ( !(nHeadFootFlags & WW8_HEADER_EVEN) && pDop->fFacingPages )
         pSepx->OutHeaderFooter( *this, true, rFormat, nCpPos, nHeadFootFlags, 
WW8_HEADER_ODD, nBreakCode );
     else
-        pSepx->OutHeaderFooter( *this, true, rLeftFormat, nCpPos, 
nHeadFootFlags, WW8_HEADER_EVEN, nBreakCode );
+        pSepx->OutHeaderFooter( *this, true, rLeftHeaderFormat, nCpPos, 
nHeadFootFlags, WW8_HEADER_EVEN, nBreakCode );
     IncrementHdFtIndex();
     pSepx->OutHeaderFooter( *this, true, rFormat, nCpPos, nHeadFootFlags, 
WW8_HEADER_ODD, nBreakCode );
 
@@ -1517,7 +1517,7 @@ void WW8Export::WriteHeadersFooters( sal_uInt8 
nHeadFootFlags,
     if ( !(nHeadFootFlags & WW8_FOOTER_EVEN) && pDop->fFacingPages )
         pSepx->OutHeaderFooter( *this, false, rFormat, nCpPos, nHeadFootFlags, 
WW8_FOOTER_ODD, nBreakCode );
     else
-        pSepx->OutHeaderFooter( *this, false, rLeftFormat, nCpPos, 
nHeadFootFlags, WW8_FOOTER_EVEN, nBreakCode );
+        pSepx->OutHeaderFooter( *this, false, rLeftFooterFormat, nCpPos, 
nHeadFootFlags, WW8_FOOTER_EVEN, nBreakCode );
     IncrementHdFtIndex();
     pSepx->OutHeaderFooter( *this, false, rFormat, nCpPos, nHeadFootFlags, 
WW8_FOOTER_ODD, nBreakCode );
 
@@ -1821,10 +1821,59 @@ void MSWordExportBase::SectionProperties( const 
WW8_SepInfo& rSepInfo, WW8_PdAtt
 
     // Header or Footer
     sal_uInt8 nHeadFootFlags = 0;
-
-    const SwFrameFormat* pPdLeftFormat = bLeftRightPgChain
-        ? &pPd->GetFollow()->GetFirstLeft()
-        : &pPd->GetLeft();
+    // Should we output a w:evenAndOddHeaders tag or not?
+    // N.B.: despite its name this tag affects _both_ headers and footers!
+    bool bEvenAndOddHeaders = true;
+    bool bEvenAndOddFooters = true;
+
+    const SwFrameFormat* pPdLeftHeaderFormat = nullptr;
+    const SwFrameFormat* pPdLeftFooterFormat = nullptr;
+    if (bLeftRightPgChain)
+    {
+        const SwFrameFormat* pHeaderFormat = pPd->GetStashedFrameFormat(true, 
true, true);
+        const SwFrameFormat* pFooterFormat = pPd->GetStashedFrameFormat(false, 
true, true);
+        if (pHeaderFormat)
+        {
+            pPdLeftHeaderFormat = pHeaderFormat;
+            bEvenAndOddHeaders = false;
+        }
+        else
+        {
+            pPdLeftHeaderFormat = &pPd->GetFollow()->GetFirstLeft();
+        }
+        if (pFooterFormat)
+        {
+            pPdLeftFooterFormat = pFooterFormat;
+            bEvenAndOddFooters = false;
+        }
+        else
+        {
+            pPdLeftFooterFormat = &pPd->GetFollow()->GetFirstLeft();
+        }
+    }
+    else
+    {
+        const SwFrameFormat* pHeaderFormat = pPd->GetStashedFrameFormat(true, 
true, false);
+        const SwFrameFormat* pFooterFormat = pPd->GetStashedFrameFormat(false, 
true, false);
+        if (pHeaderFormat)
+        {
+            pPdLeftHeaderFormat = pHeaderFormat;
+            bEvenAndOddHeaders = false;
+        }
+        else
+        {
+            pPdLeftHeaderFormat = &pPd->GetLeft();
+        }
+        if (pFooterFormat)
+        {
+            pPdLeftFooterFormat = pFooterFormat;
+            bEvenAndOddFooters = false;
+        }
+        else
+        {
+            pPdLeftFooterFormat = &pPd->GetLeft();
+        }
+    }
 
     // Ensure that headers are written if section is first paragraph
     if ( nBreakCode != 0 || bEnsureHeaderFooterWritten )
@@ -1835,14 +1884,40 @@ void MSWordExportBase::SectionProperties( const 
WW8_SepInfo& rSepInfo, WW8_PdAtt
             MSWordSections::SetHeaderFlag( nHeadFootFlags, *pPdFirstPgFormat, 
WW8_HEADER_FIRST );
             MSWordSections::SetFooterFlag( nHeadFootFlags, *pPdFirstPgFormat, 
WW8_FOOTER_FIRST );
         }
+        else
+        {
+            if ( pPd->GetStashedFrameFormat(true, true, true) && 
pPdLeftHeaderFormat && pPdLeftHeaderFormat->GetHeader().GetHeaderFormat() )
+            {
+                MSWordSections::SetHeaderFlag( nHeadFootFlags, 
*pPdLeftHeaderFormat, WW8_HEADER_FIRST );
+            }
+            if ( pPd->GetStashedFrameFormat(false, true, true) && 
pPdLeftFooterFormat && pPdLeftFooterFormat->GetFooter().GetFooterFormat() )
+            {
+                MSWordSections::SetFooterFlag( nHeadFootFlags, 
*pPdLeftFooterFormat, WW8_FOOTER_FIRST );
+            }
+        }
+
         MSWordSections::SetHeaderFlag( nHeadFootFlags, *pPdFormat, 
WW8_HEADER_ODD );
         MSWordSections::SetFooterFlag( nHeadFootFlags, *pPdFormat, 
WW8_FOOTER_ODD );
 
         if ( !pPd->IsHeaderShared() || bLeftRightPgChain )
-            MSWordSections::SetHeaderFlag( nHeadFootFlags, *pPdLeftFormat, 
WW8_HEADER_EVEN );
+        {
+            MSWordSections::SetHeaderFlag( nHeadFootFlags, 
*pPdLeftHeaderFormat, WW8_HEADER_EVEN );
+        }
+        else if ( pPd->IsHeaderShared() && pPd->GetStashedFrameFormat(true, 
true, false) && pPdLeftHeaderFormat && 
pPdLeftHeaderFormat->GetHeader().GetHeaderFormat() )
+        {
+            MSWordSections::SetHeaderFlag( nHeadFootFlags, 
*pPdLeftHeaderFormat, WW8_HEADER_EVEN );
+            bEvenAndOddHeaders = false;
+        }
 
         if ( !pPd->IsFooterShared() || bLeftRightPgChain )
-            MSWordSections::SetFooterFlag( nHeadFootFlags, *pPdLeftFormat, 
WW8_FOOTER_EVEN );
+        {
+            MSWordSections::SetFooterFlag( nHeadFootFlags, 
*pPdLeftFooterFormat, WW8_FOOTER_EVEN );
+        }
+        else if ( pPd->IsFooterShared() && pPd->GetStashedFrameFormat(false, 
true, false) && pPdLeftFooterFormat && 
pPdLeftFooterFormat->GetFooter().GetFooterFormat() )
+        {
+            MSWordSections::SetFooterFlag( nHeadFootFlags, 
*pPdLeftFooterFormat, WW8_FOOTER_EVEN );
+            bEvenAndOddFooters = false;
+        }
     }
 
     // binary filters only
@@ -1873,7 +1948,7 @@ void MSWordExportBase::SectionProperties( const 
WW8_SepInfo& rSepInfo, WW8_PdAtt
         MSWordSections::SetFooterFlag(nHeadFootFlags, *pPdFormat, 
WW8_FOOTER_ODD);
     }
 
-    WriteHeadersFooters( nHeadFootFlags, *pPdFormat, *pPdLeftFormat, 
*pPdFirstPgFormat, nBreakCode );
+    WriteHeadersFooters( nHeadFootFlags, *pPdFormat, *pPdLeftHeaderFormat, 
*pPdLeftFooterFormat, *pPdFirstPgFormat, nBreakCode, bEvenAndOddHeaders && 
bEvenAndOddFooters );
 
     SetHdFtPageRoot( pOldPageRoot );
 
diff --git a/sw/source/filter/ww8/wrtww8.hxx b/sw/source/filter/ww8/wrtww8.hxx
index b301638e0375..dcc3e85e0148 100644
--- a/sw/source/filter/ww8/wrtww8.hxx
+++ b/sw/source/filter/ww8/wrtww8.hxx
@@ -781,8 +781,8 @@ public:
 
     /// Output the actual headers and footers.
     virtual void WriteHeadersFooters( sal_uInt8 nHeadFootFlags,
-            const SwFrameFormat& rFormat, const SwFrameFormat& rLeftFormat, 
const SwFrameFormat& rFirstPageFormat,
-        sal_uInt8 nBreakCode) = 0;
+            const SwFrameFormat& rFormat, const SwFrameFormat& 
rLeftHeaderFormat, const SwFrameFormat& rLeftFooterFormat, const SwFrameFormat& 
rFirstPageFormat,
+        sal_uInt8 nBreakCode, bool bEvenAndOddHeaders) = 0;
 
     /// Write the field
     virtual void OutputField( const SwField* pField, ww::eField eFieldType,
@@ -1184,8 +1184,8 @@ public:
 
     /// Output the actual headers and footers.
     virtual void WriteHeadersFooters( sal_uInt8 nHeadFootFlags,
-            const SwFrameFormat& rFormat, const SwFrameFormat& rLeftFormat, 
const SwFrameFormat& rFirstPageFormat,
-        sal_uInt8 nBreakCode) override;
+            const SwFrameFormat& rFormat, const SwFrameFormat& 
rLeftHeaderFormat, const SwFrameFormat& rLeftFooterFormat, const SwFrameFormat& 
rFirstPageFormat,
+        sal_uInt8 nBreakCode, bool bEvenAndOddHeaders) override;
 
     virtual ExportFormat GetExportFormat() const override { return 
ExportFormat::DOC; }
 

Reply via email to