[Libreoffice-commits] core.git: sw/qa sw/source

Daniel Arato (NISZ) (via logerrit) logerrit at kemper.freedesktop.org
Tue May 4 17:15:03 UTC 2021


 sw/qa/extras/ooxmlexport/data/tdf69635.docx   |binary
 sw/qa/extras/ooxmlexport/ooxmlexport14.cxx    |    2 
 sw/qa/extras/ooxmlexport/ooxmlexport16.cxx    |   16 ++++
 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, 145 insertions(+), 48 deletions(-)

New commits:
commit 88e6a1bfeac86e0c89d2ff08c908c2b5ae061177
Author:     Daniel Arato (NISZ) <arato.daniel at nisz.hu>
AuthorDate: Fri Feb 5 12:07:48 2021 +0100
Commit:     László Németh <nemeth at numbertext.org>
CommitDate: Tue May 4 19:14:22 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 <nemeth at numbertext.org>
    Reviewed-by: László Németh <nemeth at numbertext.org>

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 06c5a16e578a..24f51850e4ff 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport14.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport14.cxx
@@ -671,7 +671,7 @@ DECLARE_OOXMLEXPORT_TEST(testTdf130167_spilloverHeaderShape, "testTdf130167_spil
         xTextGraphicObjectsSupplier->getGraphicObjects(), uno::UNO_QUERY);
     // graphics from discarded headers were being added to the text body. Reduced from 5 to 2 shapes overall.
     // CPPUNIT_ASSERT(xNameAccess->getCount() <= 4); -> What about hidden headers?
-    CPPUNIT_ASSERT_LESS(sal_Int32(6), xNameAccess->getCount());
+    CPPUNIT_ASSERT_LESS(sal_Int32(9), xNameAccess->getCount());
 }
 
 DECLARE_OOXMLEXPORT_TEST(testTdf124986, "tdf124986.docx")
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport16.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport16.cxx
index d31a4ea06a8f..991bfb6817f1 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport16.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport16.cxx
@@ -119,6 +119,22 @@ CPPUNIT_TEST_FIXTURE(Test, testGutterTop)
     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 603b1010b59a..ac0930169253 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport4.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport4.cxx
@@ -398,10 +398,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']",
@@ -415,12 +415,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");
@@ -836,7 +836,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");
 
@@ -849,12 +849,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",
@@ -1030,7 +1030,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 98ba668c7231..87023aba32c2 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport5.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport5.cxx
@@ -1035,7 +1035,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.
@@ -1056,7 +1056,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.
@@ -1345,7 +1345,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 3e60031d6d59..1a3444ca923c 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 c443120fecd5..8e6267057dee 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 887ffc7560ad..e828519ed4cf 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 6527696bce29..0590fea71d35 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 381de49a7ef4..bc96ba187100 100644
--- a/sw/source/filter/ww8/docxexport.hxx
+++ b/sw/source/filter/ww8/docxexport.hxx
@@ -160,7 +160,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 ca3247ba3498..4b4712a7bf09 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 d5835a289492..c18a221fad00 100644
--- a/sw/source/filter/ww8/wrtww8.hxx
+++ b/sw/source/filter/ww8/wrtww8.hxx
@@ -784,8 +784,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,
@@ -1187,8 +1187,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; }
 


More information about the Libreoffice-commits mailing list