oox/source/token/properties.txt                      |    4 +
 reportdesign/source/core/api/ReportDefinition.cxx    |    4 +
 sc/inc/scitems.hxx                                   |   55 ++++++++++---------
 sc/inc/unonames.hxx                                  |    4 +
 sc/qa/unit/data/xlsx/tdf121715.xlsx                  |binary
 sc/qa/unit/subsequent_export-test2.cxx               |   21 +++++++
 sc/source/core/data/docpool.cxx                      |    9 ++-
 sc/source/filter/excel/xepage.cxx                    |   47 +++++++++++++---
 sc/source/filter/excel/xipage.cxx                    |    2 
 sc/source/filter/excel/xlpage.cxx                    |    2 
 sc/source/filter/inc/pagesettings.hxx                |    6 +-
 sc/source/filter/inc/xlpage.hxx                      |    9 ++-
 sc/source/filter/oox/pagesettings.cxx                |   30 ++++++----
 sc/source/filter/xml/XMLTableHeaderFooterContext.cxx |    5 +
 sc/source/filter/xml/XMLTableHeaderFooterContext.hxx |    2 
 sc/source/filter/xml/XMLTableMasterPageExport.cxx    |   24 ++++++++
 sc/source/filter/xml/xmlfonte.cxx                    |    3 -
 sc/source/filter/xml/xmlstyli.cxx                    |    4 -
 sc/source/ui/inc/printfun.hxx                        |    2 
 sc/source/ui/pagedlg/tphf.cxx                        |    4 +
 sc/source/ui/unoobj/styleuno.cxx                     |    6 ++
 sc/source/ui/view/printfun.cxx                       |   12 +++-
 22 files changed, 200 insertions(+), 55 deletions(-)

New commits:
commit b9993369b4011cd8f367e439f5248096827f1efc
Author:     Daniel Arato (NISZ) <arato.dan...@nisz.hu>
AuthorDate: Tue Jun 8 11:53:42 2021 +0200
Commit:     László Németh <nem...@numbertext.org>
CommitDate: Tue Jun 29 22:50:43 2021 +0200

    tdf#121715 XLSX: support custom first page header/footer
    
    Add XLSX import/export support for a different header or
    footer (activated separately) on the first page.
    Print preview is also extended to support this.
    
    Note: only ODS export is supported, yet. Follow-up commits
    are going to add ODS import and UI support.
    
    Change-Id: Icd3a40131bdbcd5d5a42f98c86a71345a5745051
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/116842
    Tested-by: László Németh <nem...@numbertext.org>
    Reviewed-by: László Németh <nem...@numbertext.org>
    (cherry picked from commit 19fa853ce12136b5c14e0c5a0aa906c296b75388)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/118067
    Tested-by: Jenkins

diff --git a/oox/source/token/properties.txt b/oox/source/token/properties.txt
index 980c1bb8c0f2..68b5e2d14af5 100644
--- a/oox/source/token/properties.txt
+++ b/oox/source/token/properties.txt
@@ -184,6 +184,10 @@ Filter
 FilterCriteriaSource
 FilterOptions
 FirstLineOffset
+FirstPageFooterContent
+FirstPageHeaderContent
+FirstPageFooterIsShared
+FirstPageHeaderIsShared
 FirstPageNumber
 FocusOnClick
 FontCharset
diff --git a/reportdesign/source/core/api/ReportDefinition.cxx 
b/reportdesign/source/core/api/ReportDefinition.cxx
index fd6bf1bb56c1..839ec947ca36 100644
--- a/reportdesign/source/core/api/ReportDefinition.cxx
+++ b/reportdesign/source/core/api/ReportDefinition.cxx
@@ -149,6 +149,7 @@
 #define SC_UNO_PAGE_HDRON           "HeaderIsOn"
 #define SC_UNO_PAGE_HDRDYNAMIC      "HeaderIsDynamicHeight"
 #define SC_UNO_PAGE_HDRSHARED       "HeaderIsShared"
+#define SC_UNO_PAGE_FIRSTHDRSHARED  "FirstPageHeaderIsShared"
 #define SC_UNO_PAGE_FTRBACKCOL      "FooterBackColor"
 #define SC_UNO_PAGE_FTRBACKTRAN     "FooterBackTransparent"
 #define SC_UNO_PAGE_FTRGRFFILT      "FooterBackGraphicFilter"
@@ -171,6 +172,7 @@
 #define SC_UNO_PAGE_FTRON           "FooterIsOn"
 #define SC_UNO_PAGE_FTRDYNAMIC      "FooterIsDynamicHeight"
 #define SC_UNO_PAGE_FTRSHARED       "FooterIsShared"
+#define SC_UNO_PAGE_FIRSTFTRSHARED  "FirstPageFooterIsShared"
 
 namespace reportdesign
 {
@@ -309,6 +311,7 @@ OStyle::OStyle()
     registerPropertyNoMember(SC_UNO_PAGE_FTRDYNAMIC,  
++i,nBound,cppu::UnoType<bool>::get(), css::uno::Any(false));
     registerPropertyNoMember(SC_UNO_PAGE_FTRON,       
++i,nBound,cppu::UnoType<bool>::get(), css::uno::Any(false));
     registerPropertyNoMember(SC_UNO_PAGE_FTRSHARED,   
++i,nBound,cppu::UnoType<bool>::get(), css::uno::Any(false));
+    registerPropertyNoMember(SC_UNO_PAGE_FIRSTFTRSHARED, 
++i,nBound,cppu::UnoType<bool>::get(), css::uno::Any(false));
     registerPropertyNoMember(SC_UNO_PAGE_FTRLEFTBOR,  ++i,nBound, 
cppu::UnoType<table::BorderLine2>::get(), css::uno::Any(table::BorderLine2()));
     registerPropertyNoMember(SC_UNO_PAGE_FTRLEFTBDIS, ++i,nBound, 
cppu::UnoType<sal_Int32>::get(), css::uno::makeAny<sal_Int32>(0));
     registerPropertyNoMember(SC_UNO_PAGE_FTRLEFTMAR,  ++i,nBound, 
cppu::UnoType<sal_Int32>::get(), css::uno::makeAny<sal_Int32>(0));
@@ -332,6 +335,7 @@ OStyle::OStyle()
     registerPropertyNoMember(SC_UNO_PAGE_HDRDYNAMIC,  
++i,nBound|nMayBeVoid,cppu::UnoType<bool>::get(), css::uno::Any(false));
     registerPropertyNoMember(SC_UNO_PAGE_HDRON,       
++i,nBound|nMayBeVoid,cppu::UnoType<bool>::get(), css::uno::Any(false));
     registerPropertyNoMember(SC_UNO_PAGE_HDRSHARED,   
++i,nBound|nMayBeVoid,cppu::UnoType<bool>::get(), css::uno::Any(false));
+    registerPropertyNoMember(SC_UNO_PAGE_FIRSTHDRSHARED, 
++i,nBound|nMayBeVoid,cppu::UnoType<bool>::get(), css::uno::Any(false));
     registerPropertyNoMember(SC_UNO_PAGE_HDRLEFTBOR,  ++i,nBound|nMayBeVoid, 
cppu::UnoType<table::BorderLine2>::get(), css::uno::Any(table::BorderLine2()));
     registerPropertyNoMember(SC_UNO_PAGE_HDRLEFTBDIS, ++i,nBound|nMayBeVoid, 
cppu::UnoType<sal_Int32>::get(), css::uno::makeAny<sal_Int32>(0));
     registerPropertyNoMember(SC_UNO_PAGE_HDRLEFTMAR,  ++i,nBound|nMayBeVoid, 
cppu::UnoType<sal_Int32>::get(), css::uno::makeAny<sal_Int32>(0));
diff --git a/sc/inc/scitems.hxx b/sc/inc/scitems.hxx
index 07e9b0f6d7de..eb9771b0d3af 100644
--- a/sc/inc/scitems.hxx
+++ b/sc/inc/scitems.hxx
@@ -175,31 +175,34 @@ constexpr TypedWhichId<SfxBoolItem> ATTR_PAGE_VERCENTER 
(163);
 constexpr TypedWhichId<SfxBoolItem> ATTR_PAGE_ON (164);     // editor: 
header/footer-page
 constexpr TypedWhichId<SfxBoolItem> ATTR_PAGE_DYNAMIC (165);
 constexpr TypedWhichId<SfxBoolItem> ATTR_PAGE_SHARED (166);
-
-constexpr TypedWhichId<SfxBoolItem> ATTR_PAGE_NOTES (167);     // editor: table
-constexpr TypedWhichId<SfxBoolItem> ATTR_PAGE_GRID (168);
-constexpr TypedWhichId<SfxBoolItem> ATTR_PAGE_HEADERS (169);
-constexpr TypedWhichId<ScViewObjectModeItem> ATTR_PAGE_CHARTS (170);
-constexpr TypedWhichId<ScViewObjectModeItem> ATTR_PAGE_OBJECTS (171);
-constexpr TypedWhichId<ScViewObjectModeItem> ATTR_PAGE_DRAWINGS (172);
-constexpr TypedWhichId<SfxBoolItem> ATTR_PAGE_TOPDOWN (173);
-constexpr TypedWhichId<SfxUInt16Item> ATTR_PAGE_SCALE (174);
-constexpr TypedWhichId<SfxUInt16Item> ATTR_PAGE_SCALETOPAGES (175);
-constexpr TypedWhichId<SfxUInt16Item> ATTR_PAGE_FIRSTPAGENO (176);
-
-constexpr TypedWhichId<ScPageHFItem> ATTR_PAGE_HEADERLEFT (177);     // 
contents of header/
-constexpr TypedWhichId<ScPageHFItem> ATTR_PAGE_FOOTERLEFT (178);     // footer 
(left)
-constexpr TypedWhichId<ScPageHFItem> ATTR_PAGE_HEADERRIGHT (179);     // 
contents of header/
-constexpr TypedWhichId<ScPageHFItem> ATTR_PAGE_FOOTERRIGHT (180);     // 
footer (right)
-constexpr TypedWhichId<SvxSetItem> ATTR_PAGE_HEADERSET (181);     // the 
corresponding sets
-constexpr TypedWhichId<SvxSetItem> ATTR_PAGE_FOOTERSET (182);
-
-constexpr TypedWhichId<SfxBoolItem> ATTR_PAGE_FORMULAS (183);
-constexpr TypedWhichId<SfxBoolItem> ATTR_PAGE_NULLVALS (184);
-
-constexpr TypedWhichId<ScPageScaleToItem> ATTR_PAGE_SCALETO (185);     // 
#i8868# scale printout to width/height
-
-constexpr TypedWhichId<SfxBoolItem> ATTR_HIDDEN (186);
+constexpr TypedWhichId<SfxBoolItem> ATTR_PAGE_SHARED_FIRST (167);
+
+constexpr TypedWhichId<SfxBoolItem> ATTR_PAGE_NOTES (168);     // editor: table
+constexpr TypedWhichId<SfxBoolItem> ATTR_PAGE_GRID (169);
+constexpr TypedWhichId<SfxBoolItem> ATTR_PAGE_HEADERS (170);
+constexpr TypedWhichId<ScViewObjectModeItem> ATTR_PAGE_CHARTS (171);
+constexpr TypedWhichId<ScViewObjectModeItem> ATTR_PAGE_OBJECTS (172);
+constexpr TypedWhichId<ScViewObjectModeItem> ATTR_PAGE_DRAWINGS (173);
+constexpr TypedWhichId<SfxBoolItem> ATTR_PAGE_TOPDOWN (174);
+constexpr TypedWhichId<SfxUInt16Item> ATTR_PAGE_SCALE (175);
+constexpr TypedWhichId<SfxUInt16Item> ATTR_PAGE_SCALETOPAGES (176);
+constexpr TypedWhichId<SfxUInt16Item> ATTR_PAGE_FIRSTPAGENO (177);
+
+constexpr TypedWhichId<ScPageHFItem> ATTR_PAGE_HEADERLEFT (178);     // 
contents of header/
+constexpr TypedWhichId<ScPageHFItem> ATTR_PAGE_FOOTERLEFT (179);     // footer 
(left)
+constexpr TypedWhichId<ScPageHFItem> ATTR_PAGE_HEADERRIGHT (180);    // 
contents of header/
+constexpr TypedWhichId<ScPageHFItem> ATTR_PAGE_FOOTERRIGHT (181);    // footer 
(right)
+constexpr TypedWhichId<ScPageHFItem> ATTR_PAGE_HEADERFIRST (182);    // 
contents of header/
+constexpr TypedWhichId<ScPageHFItem> ATTR_PAGE_FOOTERFIRST (183);    // footer 
(first page)
+constexpr TypedWhichId<SvxSetItem> ATTR_PAGE_HEADERSET (184);     // the 
corresponding sets
+constexpr TypedWhichId<SvxSetItem> ATTR_PAGE_FOOTERSET (185);
+
+constexpr TypedWhichId<SfxBoolItem> ATTR_PAGE_FORMULAS (186);
+constexpr TypedWhichId<SfxBoolItem> ATTR_PAGE_NULLVALS (187);
+
+constexpr TypedWhichId<ScPageScaleToItem> ATTR_PAGE_SCALETO (188);     // 
#i8868# scale printout to width/height
+
+constexpr TypedWhichId<SfxBoolItem> ATTR_HIDDEN (189);
 
 constexpr sal_uInt16 ATTR_ENDINDEX(ATTR_HIDDEN);        // end of pool-range
 
@@ -219,6 +222,8 @@ constexpr sal_uInt16 ATTR_ENDINDEX(ATTR_HIDDEN);        // 
end of pool-range
 #define SID_SCATTR_PAGE_FOOTERLEFT      ATTR_PAGE_FOOTERLEFT
 #define SID_SCATTR_PAGE_HEADERRIGHT     ATTR_PAGE_HEADERRIGHT
 #define SID_SCATTR_PAGE_FOOTERRIGHT     ATTR_PAGE_FOOTERRIGHT
+#define SID_SCATTR_PAGE_HEADERFIRST     ATTR_PAGE_HEADERFIRST
+#define SID_SCATTR_PAGE_FOOTERFIRST     ATTR_PAGE_FOOTERFIRST
 #define SID_SCATTR_PAGE_FORMULAS        ATTR_PAGE_FORMULAS
 #define SID_SCATTR_PAGE_NULLVALS        ATTR_PAGE_NULLVALS
 #define SID_SCATTR_PAGE_SCALETO         ATTR_PAGE_SCALETO
diff --git a/sc/inc/unonames.hxx b/sc/inc/unonames.hxx
index fb24cc62b6bb..c4e7a234f1a3 100644
--- a/sc/inc/unonames.hxx
+++ b/sc/inc/unonames.hxx
@@ -441,10 +441,14 @@
 #define SC_UNO_PAGE_SCALETOX        "ScaleToPagesX"
 #define SC_UNO_PAGE_SCALETOY        "ScaleToPagesY"
 #define SC_UNO_PAGE_FIRSTPAGE       "FirstPageNumber"
+#define SC_UNO_PAGE_FIRSTHDRSHARED  "FirstPageHeaderIsShared"
+#define SC_UNO_PAGE_FIRSTFTRSHARED  "FirstPageFooterIsShared"
 #define SC_UNO_PAGE_LEFTHDRCONT     "LeftPageHeaderContent"
 #define SC_UNO_PAGE_LEFTFTRCONT     "LeftPageFooterContent"
 #define SC_UNO_PAGE_RIGHTHDRCON     "RightPageHeaderContent"
 #define SC_UNO_PAGE_RIGHTFTRCON     "RightPageFooterContent"
+#define SC_UNO_PAGE_FIRSTHDRCONT    "FirstPageHeaderContent"
+#define SC_UNO_PAGE_FIRSTFTRCONT    "FirstPageFooterContent"
 #define SC_UNO_PAGE_PRINTFORMUL     "PrintFormulas"
 #define SC_UNO_PAGE_PRINTZERO       "PrintZeroValues"
 #define SC_UNO_PAGE_HDRBACKCOL      "HeaderBackColor"
diff --git a/sc/qa/unit/data/xlsx/tdf121715.xlsx 
b/sc/qa/unit/data/xlsx/tdf121715.xlsx
new file mode 100644
index 000000000000..4163f6bc5de2
Binary files /dev/null and b/sc/qa/unit/data/xlsx/tdf121715.xlsx differ
diff --git a/sc/qa/unit/subsequent_export-test2.cxx 
b/sc/qa/unit/subsequent_export-test2.cxx
index 310d88a60f33..8e4f77ebbd79 100644
--- a/sc/qa/unit/subsequent_export-test2.cxx
+++ b/sc/qa/unit/subsequent_export-test2.cxx
@@ -163,6 +163,7 @@ public:
     void testTdf81470();
     void testTdf122331();
     void testTdf83779();
+    void testTdf121715_FirstPageHeaderFooterXLSX();
     void testTdf121716_ExportEvenHeaderFooterXLSX();
     void testTdf134459_HeaderFooterColorXLSX();
     void testTdf134817_HeaderFooterTextWith2SectionXLSX();
@@ -256,6 +257,7 @@ public:
     CPPUNIT_TEST(testTdf81470);
     CPPUNIT_TEST(testTdf122331);
     CPPUNIT_TEST(testTdf83779);
+    CPPUNIT_TEST(testTdf121715_FirstPageHeaderFooterXLSX);
     CPPUNIT_TEST(testTdf121716_ExportEvenHeaderFooterXLSX);
     CPPUNIT_TEST(testTdf134459_HeaderFooterColorXLSX);
     CPPUNIT_TEST(testTdf134817_HeaderFooterTextWith2SectionXLSX);
@@ -1679,6 +1681,25 @@ void ScExportTest2::testTdf83779()
     xShell->DoClose();
 }
 
+void ScExportTest2::testTdf121715_FirstPageHeaderFooterXLSX()
+{
+    // Check if first page header and footer are exported properly
+    ScDocShellRef xShell = loadDoc(u"tdf121715.", FORMAT_XLSX);
+    CPPUNIT_ASSERT(xShell.is());
+
+    std::shared_ptr<utl::TempFile> pXPathFile
+        = ScBootstrapFixture::exportTo(&(*xShell), FORMAT_XLSX);
+    xmlDocUniquePtr pDoc
+        = XPathHelper::parseExport(pXPathFile, m_xSFactory, 
"xl/worksheets/sheet1.xml");
+    CPPUNIT_ASSERT(pDoc);
+
+    assertXPath(pDoc, "/x:worksheet/x:headerFooter", "differentFirst", "true");
+    assertXPathContent(pDoc, "/x:worksheet/x:headerFooter/x:firstHeader", 
"&CFirst Page Header");
+    assertXPathContent(pDoc, "/x:worksheet/x:headerFooter/x:firstFooter", 
"&CFirst Page Footer");
+
+    xShell->DoClose();
+}
+
 void ScExportTest2::testTdf121716_ExportEvenHeaderFooterXLSX()
 {
     // Header and footer on even pages should be exported properly
diff --git a/sc/source/core/data/docpool.cxx b/sc/source/core/data/docpool.cxx
index 628c3686e2d0..66d3275cc4ab 100644
--- a/sc/source/core/data/docpool.cxx
+++ b/sc/source/core/data/docpool.cxx
@@ -157,6 +157,7 @@ SfxItemInfo const  aItemInfos[] =
     { SID_ATTR_PAGE_ON,             true },    // ATTR_PAGE_ON
     { SID_ATTR_PAGE_DYNAMIC,        true },    // ATTR_PAGE_DYNAMIC
     { SID_ATTR_PAGE_SHARED,         true },    // ATTR_PAGE_SHARED
+    { SID_ATTR_PAGE_SHARED_FIRST,   true },    // ATTR_PAGE_SHARED_FIRST
     { SID_SCATTR_PAGE_NOTES,        true },    // ATTR_PAGE_NOTES
     { SID_SCATTR_PAGE_GRID,         true },    // ATTR_PAGE_GRID
     { SID_SCATTR_PAGE_HEADERS,      true },    // ATTR_PAGE_HEADERS
@@ -171,6 +172,8 @@ SfxItemInfo const  aItemInfos[] =
     { SID_SCATTR_PAGE_FOOTERLEFT,   true },    // ATTR_PAGE_FOOTERLEFT
     { SID_SCATTR_PAGE_HEADERRIGHT,  true },    // ATTR_PAGE_HEADERRIGHT
     { SID_SCATTR_PAGE_FOOTERRIGHT,  true },    // ATTR_PAGE_FOOTERRIGHT
+    { SID_SCATTR_PAGE_HEADERFIRST,  true },    // ATTR_PAGE_HEADERFIRST
+    { SID_SCATTR_PAGE_FOOTERFIRST,  true },    // ATTR_PAGE_FOOTERFIRST
     { SID_ATTR_PAGE_HEADERSET,      true },    // ATTR_PAGE_HEADERSET
     { SID_ATTR_PAGE_FOOTERSET,      true },    // ATTR_PAGE_FOOTERSET
     { SID_SCATTR_PAGE_FORMULAS,     true },    // ATTR_PAGE_FORMULAS
@@ -206,7 +209,7 @@ ScDocumentPool::ScDocumentPool()
                                      ATTR_BORDER,     ATTR_SHADOW,
                                      ATTR_LRSPACE,    ATTR_ULSPACE,
                                      ATTR_PAGE_SIZE,  ATTR_PAGE_SIZE,
-                                     ATTR_PAGE_ON,    ATTR_PAGE_SHARED>{} );
+                                     ATTR_PAGE_ON,    
ATTR_PAGE_SHARED_FIRST>{} );
 
     pGlobalBorderInnerAttr->SetLine(nullptr, SvxBoxInfoItemLine::HORI);
     pGlobalBorderInnerAttr->SetLine(nullptr, SvxBoxInfoItemLine::VERT);
@@ -292,6 +295,7 @@ ScDocumentPool::ScDocumentPool()
     mvPoolDefaults[ ATTR_PAGE_ON         - ATTR_STARTINDEX ] = new 
SfxBoolItem( ATTR_PAGE_ON, true );
     mvPoolDefaults[ ATTR_PAGE_DYNAMIC    - ATTR_STARTINDEX ] = new 
SfxBoolItem( ATTR_PAGE_DYNAMIC, true );
     mvPoolDefaults[ ATTR_PAGE_SHARED     - ATTR_STARTINDEX ] = new 
SfxBoolItem( ATTR_PAGE_SHARED, true );
+    mvPoolDefaults[ ATTR_PAGE_SHARED_FIRST- ATTR_STARTINDEX ] = new 
SfxBoolItem( ATTR_PAGE_SHARED_FIRST, true );
     mvPoolDefaults[ ATTR_PAGE_NOTES      - ATTR_STARTINDEX ] = new 
SfxBoolItem( ATTR_PAGE_NOTES, false );
     mvPoolDefaults[ ATTR_PAGE_GRID       - ATTR_STARTINDEX ] = new 
SfxBoolItem( ATTR_PAGE_GRID, false );
     mvPoolDefaults[ ATTR_PAGE_HEADERS    - ATTR_STARTINDEX ] = new 
SfxBoolItem( ATTR_PAGE_HEADERS, false );
@@ -306,6 +310,8 @@ ScDocumentPool::ScDocumentPool()
     mvPoolDefaults[ ATTR_PAGE_FOOTERLEFT - ATTR_STARTINDEX ] = new 
ScPageHFItem( ATTR_PAGE_FOOTERLEFT );
     mvPoolDefaults[ ATTR_PAGE_HEADERRIGHT- ATTR_STARTINDEX ] = new 
ScPageHFItem( ATTR_PAGE_HEADERRIGHT );
     mvPoolDefaults[ ATTR_PAGE_FOOTERRIGHT- ATTR_STARTINDEX ] = new 
ScPageHFItem( ATTR_PAGE_FOOTERRIGHT );
+    mvPoolDefaults[ ATTR_PAGE_HEADERFIRST- ATTR_STARTINDEX ] = new 
ScPageHFItem( ATTR_PAGE_HEADERFIRST );
+    mvPoolDefaults[ ATTR_PAGE_FOOTERFIRST- ATTR_STARTINDEX ] = new 
ScPageHFItem( ATTR_PAGE_FOOTERFIRST );
     mvPoolDefaults[ ATTR_PAGE_HEADERSET  - ATTR_STARTINDEX ] = new SvxSetItem( 
ATTR_PAGE_HEADERSET, aSetItemItemSet );
     mvPoolDefaults[ ATTR_PAGE_FOOTERSET  - ATTR_STARTINDEX ] = new SvxSetItem( 
ATTR_PAGE_FOOTERSET, aSetItemItemSet );
     mvPoolDefaults[ ATTR_PAGE_FORMULAS   - ATTR_STARTINDEX ] = new 
SfxBoolItem( ATTR_PAGE_FORMULAS, false );
@@ -412,6 +418,7 @@ static bool lcl_HFPresentation
             case ATTR_PAGE_ON:
             case ATTR_PAGE_DYNAMIC:
             case ATTR_PAGE_SHARED:
+            case ATTR_PAGE_SHARED_FIRST:
             break;
 
             case ATTR_LRSPACE:
diff --git a/sc/source/filter/excel/xepage.cxx 
b/sc/source/filter/excel/xepage.cxx
index b2796ed99e11..56ecd2d6bc3b 100644
--- a/sc/source/filter/excel/xepage.cxx
+++ b/sc/source/filter/excel/xepage.cxx
@@ -60,11 +60,13 @@ void XclExpHeaderFooter::SaveXml( XclExpXmlStream& rStrm )
     sax_fastparser::FSHelperPtr& rWorksheet = rStrm.GetCurrentStream();
     sal_Int32 nElement;
     switch(GetRecId()) {
-        case EXC_ID_HEADER_EVEN: nElement = XML_evenHeader; break;
-        case EXC_ID_FOOTER_EVEN: nElement = XML_evenFooter; break;
-        case EXC_ID_HEADER:      nElement = XML_oddHeader; break;
+        case EXC_ID_HEADER_FIRST: nElement = XML_firstHeader; break;
+        case EXC_ID_FOOTER_FIRST: nElement = XML_firstFooter; break;
+        case EXC_ID_HEADER_EVEN:  nElement = XML_evenHeader; break;
+        case EXC_ID_FOOTER_EVEN:  nElement = XML_evenFooter; break;
+        case EXC_ID_HEADER:       nElement = XML_oddHeader; break;
         case EXC_ID_FOOTER:
-        default:                 nElement = XML_oddFooter;
+        default:                  nElement = XML_oddFooter;
     }
     rWorksheet->startElement(nElement);
     rWorksheet->writeEscaped( maHdrString );
@@ -277,6 +279,7 @@ XclExpPageSettings::XclExpPageSettings( const XclExpRoot& 
rRoot ) :
 
         maData.mxBrushItem.reset( new SvxBrushItem( rItemSet.Get( 
ATTR_BACKGROUND ) ) );
         maData.mbUseEvenHF = false;
+        maData.mbUseFirstHF = false;
 
         // *** header and footer ***
 
@@ -301,6 +304,17 @@ XclExpPageSettings::XclExpPageSettings( const XclExpRoot& 
rRoot ) :
                 // If maData.mbUseEvenHF become true, then we will need a copy 
of maHeader in maHeaderEven.
                 maData.maHeaderEven = maData.maHeader;
             }
+            if (rHdrItemSet.HasItem(ATTR_PAGE_SHARED_FIRST) && 
!rHdrItemSet.Get(ATTR_PAGE_SHARED_FIRST).GetValue())
+            {
+                const ScPageHFItem& rHFItemFirst = rItemSet.Get( 
ATTR_PAGE_HEADERFIRST );
+                aHFConv.GenerateString( rHFItemFirst.GetLeftArea(), 
rHFItemFirst.GetCenterArea(), rHFItemFirst.GetRightArea() );
+                maData.maHeaderFirst = aHFConv.GetHFString();
+                maData.mbUseFirstHF = true;
+            }
+            else
+            {
+                maData.maHeaderFirst = maData.maHeader;
+            }
             // header height (Excel excludes header from top margin)
             sal_Int32 nHdrHeight = rHdrItemSet.Get( ATTR_PAGE_DYNAMIC 
).GetValue() ?
                 // dynamic height: calculate header height, add header <-> 
sheet area distance
@@ -329,6 +343,17 @@ XclExpPageSettings::XclExpPageSettings( const XclExpRoot& 
rRoot ) :
             {
                 maData.maFooterEven = maData.maFooter;
             }
+            if (rFtrItemSet.HasItem(ATTR_PAGE_SHARED_FIRST) && 
!rFtrItemSet.Get(ATTR_PAGE_SHARED_FIRST).GetValue())
+            {
+                const ScPageHFItem& rHFItemFirst = rItemSet.Get( 
ATTR_PAGE_FOOTERFIRST );
+                aHFConv.GenerateString( rHFItemFirst.GetLeftArea(), 
rHFItemFirst.GetCenterArea(), rHFItemFirst.GetRightArea() );
+                maData.maFooterFirst = aHFConv.GetHFString();
+                maData.mbUseFirstHF = true;
+            }
+            else
+            {
+                maData.maFooterFirst = maData.maFooter;
+            }
             // footer height (Excel excludes footer from bottom margin)
             sal_Int32 nFtrHeight = rFtrItemSet.Get( ATTR_PAGE_DYNAMIC 
).GetValue() ?
                 // dynamic height: calculate footer height, add sheet area <-> 
footer distance
@@ -373,12 +398,13 @@ namespace {
 class XclExpXmlStartHeaderFooterElementRecord : public XclExpXmlElementRecord
 {
 public:
-    explicit XclExpXmlStartHeaderFooterElementRecord(sal_Int32 const nElement, 
bool const bDifferentOddEven = false)
-         : XclExpXmlElementRecord(nElement), 
mbDifferentOddEven(bDifferentOddEven) {}
+    explicit XclExpXmlStartHeaderFooterElementRecord(sal_Int32 const nElement, 
bool const bDifferentOddEven = false, bool const bDifferentFirst = false)
+         : XclExpXmlElementRecord(nElement), 
mbDifferentOddEven(bDifferentOddEven), mbDifferentFirst(bDifferentFirst) {}
 
     virtual void        SaveXml( XclExpXmlStream& rStrm ) override;
 private:
     bool            mbDifferentOddEven;
+    bool            mbDifferentFirst;
 };
 
 }
@@ -390,7 +416,7 @@ void 
XclExpXmlStartHeaderFooterElementRecord::SaveXml(XclExpXmlStream& rStrm)
     sax_fastparser::FSHelperPtr& rStream = rStrm.GetCurrentStream();
     rStream->startElement( mnElement,
             // OOXTODO: XML_alignWithMargins,
-            XML_differentFirst,     "false",    // OOXTODO
+            XML_differentFirst,     mbDifferentFirst   ? "true" : "false",
             XML_differentOddEven,   mbDifferentOddEven ? "true" : "false"
             // OOXTODO: XML_scaleWithDoc
     );
@@ -439,7 +465,7 @@ void XclExpPageSettings::SaveXml( XclExpXmlStream& rStrm )
 
     XclExpSetup( maData ).SaveXml( rStrm );
 
-    XclExpXmlStartHeaderFooterElementRecord(XML_headerFooter, 
maData.mbUseEvenHF).SaveXml(rStrm);
+    XclExpXmlStartHeaderFooterElementRecord(XML_headerFooter, 
maData.mbUseEvenHF, maData.mbUseFirstHF).SaveXml(rStrm);
     XclExpHeaderFooter( EXC_ID_HEADER, maData.maHeader ).SaveXml( rStrm );
     XclExpHeaderFooter( EXC_ID_FOOTER, maData.maFooter ).SaveXml( rStrm );
     if (maData.mbUseEvenHF)
@@ -447,6 +473,11 @@ void XclExpPageSettings::SaveXml( XclExpXmlStream& rStrm )
         XclExpHeaderFooter( EXC_ID_HEADER_EVEN, maData.maHeaderEven ).SaveXml( 
rStrm );
         XclExpHeaderFooter( EXC_ID_FOOTER_EVEN, maData.maFooterEven ).SaveXml( 
rStrm );
     }
+    if (maData.mbUseFirstHF)
+    {
+        XclExpHeaderFooter( EXC_ID_HEADER_FIRST, maData.maHeaderFirst 
).SaveXml( rStrm );
+        XclExpHeaderFooter( EXC_ID_FOOTER_FIRST, maData.maFooterFirst 
).SaveXml( rStrm );
+    }
     XclExpXmlEndElementRecord( XML_headerFooter ).SaveXml( rStrm );
 
     XclExpPageBreaks( EXC_ID_HORPAGEBREAKS, maData.maHorPageBreaks,
diff --git a/sc/source/filter/excel/xipage.cxx 
b/sc/source/filter/excel/xipage.cxx
index c3b1853b76ea..41db8abcfbd6 100644
--- a/sc/source/filter/excel/xipage.cxx
+++ b/sc/source/filter/excel/xipage.cxx
@@ -299,6 +299,7 @@ void XclImpPageSettings::Finalize()
         aHFConv.ParseString( maData.maHeader );
         aHFConv.FillToItemSet( rItemSet, ATTR_PAGE_HEADERLEFT );
         aHFConv.FillToItemSet( rItemSet, ATTR_PAGE_HEADERRIGHT );
+        aHFConv.FillToItemSet( rItemSet, ATTR_PAGE_HEADERFIRST );
         // #i23296# In Calc, "top margin" is distance to header
         fTopMargin = maData.mfHeaderMargin;
         // Calc uses distance between header and sheet data area
@@ -335,6 +336,7 @@ void XclImpPageSettings::Finalize()
         aHFConv.ParseString( maData.maFooter );
         aHFConv.FillToItemSet( rItemSet, ATTR_PAGE_FOOTERLEFT );
         aHFConv.FillToItemSet( rItemSet, ATTR_PAGE_FOOTERRIGHT );
+        aHFConv.FillToItemSet( rItemSet, ATTR_PAGE_FOOTERFIRST );
         // #i23296# In Calc, "bottom margin" is distance to footer
         fBottomMargin = maData.mfFooterMargin;
         // Calc uses distance between footer and sheet data area
diff --git a/sc/source/filter/excel/xlpage.cxx 
b/sc/source/filter/excel/xlpage.cxx
index ef1742dd51e3..06da2e5e026e 100644
--- a/sc/source/filter/excel/xlpage.cxx
+++ b/sc/source/filter/excel/xlpage.cxx
@@ -185,7 +185,7 @@ void XclPageData::SetDefaults()
     mnScaling = 100;
     mnFitToWidth = mnFitToHeight = 1;
     mnHorPrintRes = mnVerPrintRes = 300;
-    mbUseEvenHF = /*mbUseFirstHF =*/ false;
+    mbUseEvenHF = mbUseFirstHF = false;
     mbValid = false;
     mbPortrait = true;
     mbPrintInRows = mbBlackWhite = mbDraftQuality = mbPrintNotes = 
mbManualStart = mbFitToPages = false;
diff --git a/sc/source/filter/inc/pagesettings.hxx 
b/sc/source/filter/inc/pagesettings.hxx
index 1bee649d36db..f951f3197be2 100644
--- a/sc/source/filter/inc/pagesettings.hxx
+++ b/sc/source/filter/inc/pagesettings.hxx
@@ -146,13 +146,15 @@ private:
     {
         sal_Int32           mnLeftPropId;
         sal_Int32           mnRightPropId;
+        sal_Int32           mnFirstPropId;
         sal_Int32           mnHeight;
         sal_Int32           mnBodyDist;
         bool                mbHasContent;
         bool                mbShareOddEven;
+        bool                mbShareFirst;
         bool                mbDynamicHeight;
 
-        explicit            HFHelperData( sal_Int32 nLeftPropId, sal_Int32 
nRightPropId );
+        explicit            HFHelperData( sal_Int32 nLeftPropId, sal_Int32 
nRightPropId, sal_Int32 nFirstPropId );
     };
 
 private:
@@ -161,7 +163,9 @@ private:
                             HFHelperData& orHFData,
                             const OUString& rOddContent,
                             const OUString& rEvenContent,
+                            const OUString& rFirstContent,
                             bool bUseEvenContent,
+                            bool bUseFirstContent,
                             double fPageMargin,
                             double fContentMargin );
 
diff --git a/sc/source/filter/inc/xlpage.hxx b/sc/source/filter/inc/xlpage.hxx
index 246057c67133..d200e8b804ab 100644
--- a/sc/source/filter/inc/xlpage.hxx
+++ b/sc/source/filter/inc/xlpage.hxx
@@ -35,6 +35,11 @@ const sal_uInt16 EXC_ID_FOOTER              = 0x0015;
 const sal_uInt16 EXC_ID_HEADER_EVEN         = 0x0016;
 const sal_uInt16 EXC_ID_FOOTER_EVEN         = 0x0017;
 
+// (0x0018, 0x0019) FIRST HEADER, FIRST FOOTER 
----------------------------------
+
+const sal_uInt16 EXC_ID_HEADER_FIRST        = 0x0018;
+const sal_uInt16 EXC_ID_FOOTER_FIRST        = 0x0019;
+
 // (0x001A, 0x001B) VERTICAL-, HORIZONTALPAGEBREAKS ---------------------------
 
 const sal_uInt16 EXC_ID_VERPAGEBREAKS       = 0x001A;
@@ -108,6 +113,8 @@ struct XclPageData
     OUString            maFooter;           /// Excel footer string (empty = 
off).
     OUString            maHeaderEven;       /// Excel header string for even 
pages (empty = off).
     OUString            maFooterEven;       /// Excel footer string for even 
pages (empty = off).
+    OUString            maHeaderFirst;      /// Excel header string for first 
page (empty = off).
+    OUString            maFooterFirst;      /// Excel footer string for first 
page (empty = off).
     double              mfLeftMargin;       /// Left margin in inches.
     double              mfRightMargin;      /// Right margin in inches.
     double              mfTopMargin;        /// Top margin in inches.
@@ -130,7 +137,7 @@ struct XclPageData
     sal_uInt16          mnHorPrintRes;      /// Horizontal printing resolution.
     sal_uInt16          mnVerPrintRes;      /// Vertical printing resolution.
     bool                mbUseEvenHF;        /// True = use 
maHeaderEven/maFooterEven.
-//  bool                mbUseFirstHF;       /// True = use 
maHeaderFirst/maFooterFirst.  TODO: not implemented yet.
+    bool                mbUseFirstHF;       /// True = use 
maHeaderFirst/maFooterFirst.
     bool                mbValid;            /// false = some of the values are 
not valid.
     bool                mbPortrait;         /// true = portrait; false = 
landscape.
     bool                mbPrintInRows;      /// true = in rows; false = in 
columns.
diff --git a/sc/source/filter/oox/pagesettings.cxx 
b/sc/source/filter/oox/pagesettings.cxx
index bc80fc42a1f8..44aac4a581eb 100644
--- a/sc/source/filter/oox/pagesettings.cxx
+++ b/sc/source/filter/oox/pagesettings.cxx
@@ -874,13 +874,15 @@ void HeaderFooterParser::setNewPortion( HFPortionId 
ePortion )
     }
 }
 
-PageSettingsConverter::HFHelperData::HFHelperData( sal_Int32 nLeftPropId, 
sal_Int32 nRightPropId ) :
+PageSettingsConverter::HFHelperData::HFHelperData( sal_Int32 nLeftPropId, 
sal_Int32 nRightPropId, sal_Int32 nFirstPropId ) :
     mnLeftPropId( nLeftPropId ),
     mnRightPropId( nRightPropId ),
+    mnFirstPropId( nFirstPropId ),
     mnHeight( 0 ),
     mnBodyDist( 0 ),
     mbHasContent( false ),
     mbShareOddEven( false ),
+    mbShareFirst( false ),
     mbDynamicHeight( false )
 {
 }
@@ -888,8 +890,8 @@ PageSettingsConverter::HFHelperData::HFHelperData( 
sal_Int32 nLeftPropId, sal_In
 PageSettingsConverter::PageSettingsConverter( const WorkbookHelper& rHelper ) :
     WorkbookHelper( rHelper ),
     mxHFParser( new HeaderFooterParser( rHelper ) ),
-    maHeaderData( PROP_LeftPageHeaderContent, PROP_RightPageHeaderContent ),
-    maFooterData( PROP_LeftPageFooterContent, PROP_RightPageFooterContent )
+    maHeaderData( PROP_LeftPageHeaderContent, PROP_RightPageHeaderContent, 
PROP_FirstPageHeaderContent ),
+    maFooterData( PROP_LeftPageFooterContent, PROP_RightPageFooterContent, 
PROP_FirstPageFooterContent )
 {
 }
 
@@ -955,8 +957,8 @@ void PageSettingsConverter::writePageSettingsProperties(
     }
 
     // header/footer
-    convertHeaderFooterData( rPropSet, maHeaderData, rModel.maOddHeader, 
rModel.maEvenHeader, rModel.mbUseEvenHF, rModel.mfTopMargin,    
rModel.mfHeaderMargin );
-    convertHeaderFooterData( rPropSet, maFooterData, rModel.maOddFooter, 
rModel.maEvenFooter, rModel.mbUseEvenHF, rModel.mfBottomMargin, 
rModel.mfFooterMargin );
+    convertHeaderFooterData( rPropSet, maHeaderData, rModel.maOddHeader, 
rModel.maEvenHeader, rModel.maFirstHeader, rModel.mbUseEvenHF, 
rModel.mbUseFirstHF, rModel.mfTopMargin,    rModel.mfHeaderMargin );
+    convertHeaderFooterData( rPropSet, maFooterData, rModel.maOddFooter, 
rModel.maEvenFooter, rModel.maFirstFooter, rModel.mbUseEvenHF, 
rModel.mbUseFirstHF, rModel.mfBottomMargin, rModel.mfFooterMargin );
 
     // write all properties to property set
     const UnitConverter& rUnitConv = getUnitConverter();
@@ -977,11 +979,13 @@ void PageSettingsConverter::writePageSettingsProperties(
     aPropMap.setProperty( PROP_BottomMargin, rUnitConv.scaleToMm100( 
maFooterData.mbHasContent ? rModel.mfFooterMargin : rModel.mfBottomMargin, 
Unit::Inch ));
     aPropMap.setProperty( PROP_HeaderIsOn, maHeaderData.mbHasContent);
     aPropMap.setProperty( PROP_HeaderIsShared, maHeaderData.mbShareOddEven);
+    aPropMap.setProperty( PROP_FirstPageHeaderIsShared, 
maHeaderData.mbShareFirst);
     aPropMap.setProperty( PROP_HeaderIsDynamicHeight, 
maHeaderData.mbDynamicHeight);
     aPropMap.setProperty( PROP_HeaderHeight, maHeaderData.mnHeight);
     aPropMap.setProperty( PROP_HeaderBodyDistance, maHeaderData.mnBodyDist);
     aPropMap.setProperty( PROP_FooterIsOn, maFooterData.mbHasContent);
     aPropMap.setProperty( PROP_FooterIsShared, maFooterData.mbShareOddEven);
+    aPropMap.setProperty( PROP_FirstPageFooterIsShared, 
maFooterData.mbShareFirst);
     aPropMap.setProperty( PROP_FooterIsDynamicHeight, 
maFooterData.mbDynamicHeight);
     aPropMap.setProperty( PROP_FooterHeight, maFooterData.mnHeight);
     aPropMap.setProperty( PROP_FooterBodyDistance, maFooterData.mnBodyDist);
@@ -997,26 +1001,30 @@ void PageSettingsConverter::writePageSettingsProperties(
 
 void PageSettingsConverter::convertHeaderFooterData(
         PropertySet& rPropSet, HFHelperData& orHFData,
-        const OUString& rOddContent, const OUString& rEvenContent, bool 
bUseEvenContent,
+        const OUString& rOddContent, const OUString& rEvenContent, const 
OUString& rFirstContent,
+        bool bUseEvenContent, bool bUseFirstContent,
         double fPageMargin, double fContentMargin )
 {
     bool bHasOddContent  = !rOddContent.isEmpty();
     bool bHasEvenContent = bUseEvenContent && !rEvenContent.isEmpty();
+    bool bHasFirstContent = bUseFirstContent && !rFirstContent.isEmpty();
 
-    sal_Int32 nOddHeight  = bHasOddContent  ? writeHeaderFooter( rPropSet, 
orHFData.mnRightPropId, rOddContent  ) : 0;
-    sal_Int32 nEvenHeight = bHasEvenContent ? writeHeaderFooter( rPropSet, 
orHFData.mnLeftPropId,  rEvenContent ) : 0;
+    sal_Int32 nOddHeight   = bHasOddContent   ? writeHeaderFooter( rPropSet, 
orHFData.mnRightPropId, rOddContent   ) : 0;
+    sal_Int32 nEvenHeight  = bHasEvenContent  ? writeHeaderFooter( rPropSet, 
orHFData.mnLeftPropId,  rEvenContent  ) : 0;
+    sal_Int32 nFirstHeight = bHasFirstContent ? writeHeaderFooter( rPropSet, 
orHFData.mnFirstPropId, rFirstContent ) : 0;
 
     orHFData.mnHeight = 750;
     orHFData.mnBodyDist = 250;
-    orHFData.mbHasContent = bHasOddContent || bHasEvenContent;
+    orHFData.mbHasContent = bHasOddContent || bHasEvenContent || 
bHasFirstContent;
     orHFData.mbShareOddEven = !bUseEvenContent;
+    orHFData.mbShareFirst = !bUseFirstContent;
     orHFData.mbDynamicHeight = true;
 
     if( !orHFData.mbHasContent )
         return;
 
-    // use maximum height of odd/even header/footer
-    orHFData.mnHeight = ::std::max( nOddHeight, nEvenHeight );
+    // use maximum height of odd/even/first header/footer
+    orHFData.mnHeight = ::std::max( ::std::max( nOddHeight, nEvenHeight ), 
nFirstHeight );
     /*  Calc contains distance between bottom of header and top of page
         body in "HeaderBodyDistance" property, and distance between bottom
         of page body and top of footer in "FooterBodyDistance" property */
diff --git a/sc/source/filter/xml/XMLTableHeaderFooterContext.cxx 
b/sc/source/filter/xml/XMLTableHeaderFooterContext.cxx
index 62d3a217bbce..a34015a999cf 100644
--- a/sc/source/filter/xml/XMLTableHeaderFooterContext.cxx
+++ b/sc/source/filter/xml/XMLTableHeaderFooterContext.cxx
@@ -41,7 +41,7 @@ XMLTableHeaderFooterContext::XMLTableHeaderFooterContext( 
SvXMLImport& rImport,
                        const uno::Reference<
                             xml::sax::XFastAttributeList > & xAttrList,
                        const Reference < XPropertySet > & rPageStylePropSet,
-                       bool bFooter, bool bLeft ) :
+                       bool bFooter, bool bLeft, bool bFirst ) :
     SvXMLImportContext( rImport ),
     xPropSet( rPageStylePropSet ),
     bContainsLeft(false),
@@ -51,6 +51,7 @@ XMLTableHeaderFooterContext::XMLTableHeaderFooterContext( 
SvXMLImport& rImport,
     OUString sOn( bFooter ? OUString(SC_UNO_PAGE_FTRON) : 
OUString(SC_UNO_PAGE_HDRON) );
     OUString sContent( bFooter ? OUString(SC_UNO_PAGE_RIGHTFTRCON) : 
OUString(SC_UNO_PAGE_RIGHTHDRCON) );
     OUString sContentLeft( bFooter ? OUString(SC_UNO_PAGE_LEFTFTRCONT) : 
OUString(SC_UNO_PAGE_LEFTHDRCONT) );
+    OUString sContentFirst( bFooter ? OUString(SC_UNO_PAGE_FIRSTFTRCONT) : 
OUString(SC_UNO_PAGE_FIRSTHDRCONT) );
     OUString sShareContent( bFooter ? OUString(SC_UNO_PAGE_FTRSHARED) : 
OUString(SC_UNO_PAGE_HDRSHARED) );
     bool bDisplay( true );
     for( auto &aIter : sax_fastparser::castToFastAttributeList( xAttrList ) )
@@ -85,6 +86,8 @@ XMLTableHeaderFooterContext::XMLTableHeaderFooterContext( 
SvXMLImport& rImport,
     }
     if (bLeft)
         sCont = sContentLeft;
+    else if (bFirst)
+        sCont = sContentFirst;
     else
         sCont = sContent;
     xPropSet->getPropertyValue( sCont ) >>= xHeaderFooterContent;
diff --git a/sc/source/filter/xml/XMLTableHeaderFooterContext.hxx 
b/sc/source/filter/xml/XMLTableHeaderFooterContext.hxx
index bc7bf13241b1..ccb6a154cc4b 100644
--- a/sc/source/filter/xml/XMLTableHeaderFooterContext.hxx
+++ b/sc/source/filter/xml/XMLTableHeaderFooterContext.hxx
@@ -45,7 +45,7 @@ public:
     XMLTableHeaderFooterContext( SvXMLImport& rImport, sal_Int32 nElement,
             const css::uno::Reference< css::xml::sax::XFastAttributeList > & 
xAttrList,
             const css::uno::Reference< css::beans::XPropertySet > & 
rPageStylePropSet,
-               bool bFooter, bool bLft );
+               bool bFooter, bool bLft, bool bFirst );
 
     virtual ~XMLTableHeaderFooterContext() override;
 
diff --git a/sc/source/filter/xml/XMLTableMasterPageExport.cxx 
b/sc/source/filter/xml/XMLTableMasterPageExport.cxx
index 03078b848169..bf43b2c29fb2 100644
--- a/sc/source/filter/xml/XMLTableMasterPageExport.cxx
+++ b/sc/source/filter/xml/XMLTableMasterPageExport.cxx
@@ -116,10 +116,14 @@ void XMLTableMasterPageExport::exportMasterPageContent(
 
     Reference < sheet::XHeaderFooterContent > 
xHeaderLeft(rPropSet->getPropertyValue( SC_UNO_PAGE_LEFTHDRCONT ), 
uno::UNO_QUERY);
 
+    Reference < sheet::XHeaderFooterContent > 
xHeaderFirst(rPropSet->getPropertyValue( SC_UNO_PAGE_FIRSTHDRCONT ), 
uno::UNO_QUERY);
+
     Reference < sheet::XHeaderFooterContent > 
xFooter(rPropSet->getPropertyValue( SC_UNO_PAGE_RIGHTFTRCON ), uno::UNO_QUERY);
 
     Reference < sheet::XHeaderFooterContent > 
xFooterLeft(rPropSet->getPropertyValue( SC_UNO_PAGE_LEFTFTRCONT ), 
uno::UNO_QUERY);
 
+    Reference < sheet::XHeaderFooterContent > 
xFooterFirst(rPropSet->getPropertyValue( SC_UNO_PAGE_FIRSTFTRCONT ), 
uno::UNO_QUERY);
+
     if( bAutoStyles )
     {
         if( xHeader.is() )
@@ -134,6 +138,12 @@ void XMLTableMasterPageExport::exportMasterPageContent(
             exportHeaderFooterContent( xHeaderLeft->getLeftText(), true, false 
);
             exportHeaderFooterContent( xHeaderLeft->getRightText(), true, 
false );
         }
+        if( xHeaderFirst.is())
+        {
+            exportHeaderFooterContent( xHeaderFirst->getCenterText(), true, 
false );
+            exportHeaderFooterContent( xHeaderFirst->getLeftText(), true, 
false );
+            exportHeaderFooterContent( xHeaderFirst->getRightText(), true, 
false );
+        }
         if( xFooter.is() )
         {
             exportHeaderFooterContent( xFooter->getCenterText(), true, false );
@@ -146,6 +156,12 @@ void XMLTableMasterPageExport::exportMasterPageContent(
             exportHeaderFooterContent( xFooterLeft->getLeftText(), true, false 
);
             exportHeaderFooterContent( xFooterLeft->getRightText(), true, 
false );
         }
+        if( xFooterFirst.is())
+        {
+            exportHeaderFooterContent( xFooterFirst->getCenterText(), true, 
false );
+            exportHeaderFooterContent( xFooterFirst->getLeftText(), true, 
false );
+            exportHeaderFooterContent( xFooterFirst->getRightText(), true, 
false );
+        }
     }
     else
     {
@@ -157,6 +173,10 @@ void XMLTableMasterPageExport::exportMasterPageContent(
 
         exportHeaderFooter( xHeaderLeft, XML_HEADER_LEFT, bLeftHeader );
 
+        bool bFirstHeader(!::cppu::any2bool(rPropSet->getPropertyValue( 
SC_UNO_PAGE_FIRSTHDRSHARED )) && bHeader);
+
+        exportHeaderFooter( xHeaderFirst, XML_HEADER_FIRST, bFirstHeader );
+
         bool bFooter(::cppu::any2bool(rPropSet->getPropertyValue( 
SC_UNO_PAGE_FTRON )));
 
         exportHeaderFooter( xFooter, XML_FOOTER, bFooter );
@@ -164,6 +184,10 @@ void XMLTableMasterPageExport::exportMasterPageContent(
         bool bLeftFooter = (!::cppu::any2bool(rPropSet->getPropertyValue( 
SC_UNO_PAGE_FTRSHARED )) && bFooter);
 
         exportHeaderFooter( xFooterLeft, XML_FOOTER_LEFT, bLeftFooter );
+
+        bool bFirstFooter = (!::cppu::any2bool(rPropSet->getPropertyValue( 
SC_UNO_PAGE_FIRSTFTRSHARED )) && bFooter);
+
+        exportHeaderFooter( xFooterLeft, XML_FOOTER_FIRST, bFirstFooter );
     }
 }
 
diff --git a/sc/source/filter/xml/xmlfonte.cxx 
b/sc/source/filter/xml/xmlfonte.cxx
index 76782d1f6dae..ab8e42f4ce60 100644
--- a/sc/source/filter/xml/xmlfonte.cxx
+++ b/sc/source/filter/xml/xmlfonte.cxx
@@ -77,7 +77,8 @@ 
ScXMLFontAutoStylePool_Impl::ScXMLFontAutoStylePool_Impl(ScXMLExport& rExportP,
     sal_uInt16 const aEditWhichIds[] { EE_CHAR_FONTINFO, EE_CHAR_FONTINFO_CJK,
                                        EE_CHAR_FONTINFO_CTL };
     sal_uInt16 const aPageWhichIds[] { ATTR_PAGE_HEADERLEFT, 
ATTR_PAGE_FOOTERLEFT,
-                                       ATTR_PAGE_HEADERRIGHT, 
ATTR_PAGE_FOOTERRIGHT };
+                                       ATTR_PAGE_HEADERRIGHT, 
ATTR_PAGE_FOOTERRIGHT,
+                                       ATTR_PAGE_HEADERFIRST, 
ATTR_PAGE_FOOTERFIRST };
 
     const SfxItemPool* pItemPool(rExportP.GetDocument()->GetPool());
     AddFontItems(aWhichIds, 3, pItemPool, true);
diff --git a/sc/source/filter/xml/xmlstyli.cxx 
b/sc/source/filter/xml/xmlstyli.cxx
index a3db1cff5f0f..2c8909216445 100644
--- a/sc/source/filter/xml/xmlstyli.cxx
+++ b/sc/source/filter/xml/xmlstyli.cxx
@@ -943,7 +943,7 @@ SvXMLImportContext 
*ScMasterPageContext::CreateHeaderFooterContext(
             const css::uno::Reference< css::xml::sax::XFastAttributeList > & 
xAttrList,
             const bool bFooter,
             const bool bLeft,
-            const bool /*bFirst*/ )
+            const bool bFirst )
 {
     if (!bLeft)
     {
@@ -958,7 +958,7 @@ SvXMLImportContext 
*ScMasterPageContext::CreateHeaderFooterContext(
                                                 nElement,
                                                 xAttrList,
                                                 xPropSet,
-                                                bFooter, bLeft );
+                                                bFooter, bLeft, bFirst );
 }
 
 void ScMasterPageContext::ClearContent(const OUString& rContent)
diff --git a/sc/source/ui/inc/printfun.hxx b/sc/source/ui/inc/printfun.hxx
index 4cb4fbe8077f..e9721837a57f 100644
--- a/sc/source/ui/inc/printfun.hxx
+++ b/sc/source/ui/inc/printfun.hxx
@@ -50,6 +50,7 @@ struct ScPrintHFParam
     bool                bEnable;
     bool                bDynamic;
     bool                bShared;
+    bool                bSharedFirst;
     tools::Long                nHeight;            // in total (height + 
distance + frames)
     tools::Long                nManHeight;         // set size (min when 
dynamic)
     sal_uInt16          nDistance;
@@ -57,6 +58,7 @@ struct ScPrintHFParam
     sal_uInt16          nRight;
     const ScPageHFItem* pLeft;
     const ScPageHFItem* pRight;
+    const ScPageHFItem* pFirst;
     const SvxBoxItem*   pBorder;
     const SvxBrushItem* pBack;
     const SvxShadowItem* pShadow;
diff --git a/sc/source/ui/pagedlg/tphf.cxx b/sc/source/ui/pagedlg/tphf.cxx
index 3fb27a9cf43f..2a8af81e01ec 100644
--- a/sc/source/ui/pagedlg/tphf.cxx
+++ b/sc/source/ui/pagedlg/tphf.cxx
@@ -42,7 +42,7 @@
 
 ScHFPage::ScHFPage(weld::Container* pPage, weld::DialogController* 
pController, const SfxItemSet& rSet, sal_uInt16 nSetId)
     : SvxHFPage(pPage, pController, rSet, nSetId)
-    , aDataSet(*rSet.GetPool(), svl::Items<ATTR_PAGE, ATTR_PAGE, 
ATTR_PAGE_HEADERLEFT, ATTR_PAGE_FOOTERRIGHT>{})
+    , aDataSet(*rSet.GetPool(), svl::Items<ATTR_PAGE, ATTR_PAGE, 
ATTR_PAGE_HEADERLEFT, ATTR_PAGE_FOOTERFIRST>{})
     , nPageUsage(SvxPageUsage::All)
     , pStyleDlg(nullptr)
     , m_xBtnEdit(m_xBuilder->weld_button("buttonEdit"))
@@ -91,11 +91,13 @@ bool ScHFPage::FillItemSet( SfxItemSet* rOutSet )
     {
         rOutSet->Put( aDataSet.Get( ATTR_PAGE_HEADERLEFT ) );
         rOutSet->Put( aDataSet.Get( ATTR_PAGE_HEADERRIGHT ) );
+        rOutSet->Put( aDataSet.Get( ATTR_PAGE_HEADERFIRST ) );
     }
     else
     {
         rOutSet->Put( aDataSet.Get( ATTR_PAGE_FOOTERLEFT ) );
         rOutSet->Put( aDataSet.Get( ATTR_PAGE_FOOTERRIGHT ) );
+        rOutSet->Put( aDataSet.Get( ATTR_PAGE_FOOTERFIRST ) );
     }
 
     return bResult;
diff --git a/sc/source/ui/unoobj/styleuno.cxx b/sc/source/ui/unoobj/styleuno.cxx
index 5af2c60edfde..3d63b60513b1 100644
--- a/sc/source/ui/unoobj/styleuno.cxx
+++ b/sc/source/ui/unoobj/styleuno.cxx
@@ -194,6 +194,10 @@ static const SfxItemPropertySet * lcl_GetPageStyleSet()
         {u"" SC_UNO_PAGE_CENTERVER,   
ATTR_PAGE_VERCENTER,cppu::UnoType<bool>::get(),            0, 0 },
         {u"" SC_UNONAME_DISPNAME,     
SC_WID_UNO_DISPNAME,::cppu::UnoType<OUString>::get(),  
beans::PropertyAttribute::READONLY, 0 },
         {u"" SC_UNO_PAGE_FIRSTPAGE,   
ATTR_PAGE_FIRSTPAGENO,::cppu::UnoType<sal_Int16>::get(),      0, 0 },
+        {u"" SC_UNO_PAGE_FIRSTFTRSHARED, 
SC_WID_UNO_FOOTERSET,cppu::UnoType<bool>::get(),                       0, 0 },
+        {u"" SC_UNO_PAGE_FIRSTHDRSHARED, 
SC_WID_UNO_HEADERSET,cppu::UnoType<bool>::get(),                       0, 0 },
+        {u"" SC_UNO_PAGE_FIRSTFTRCONT, 
ATTR_PAGE_FOOTERFIRST,cppu::UnoType<sheet::XHeaderFooterContent>::get(), 0, 0 },
+        {u"" SC_UNO_PAGE_FIRSTHDRCONT, 
ATTR_PAGE_HEADERFIRST,cppu::UnoType<sheet::XHeaderFooterContent>::get(), 0, 0 },
 
         {u"" SC_UNO_PAGE_FTRBACKCOL,  
SC_WID_UNO_FOOTERSET,::cppu::UnoType<sal_Int32>::get(),           0, 0 },
         {u"" SC_UNO_PAGE_FTRGRFFILT,  
SC_WID_UNO_FOOTERSET,::cppu::UnoType<OUString>::get(),     0, 0 },
@@ -319,6 +323,7 @@ static const SfxItemPropertyMap* lcl_GetHeaderStyleMap()
         {u"" SC_UNO_PAGE_HDRDYNAMIC,  ATTR_PAGE_DYNAMIC,  
cppu::UnoType<bool>::get(),            0, 0 },
         {u"" SC_UNO_PAGE_HDRON,       ATTR_PAGE_ON,       
cppu::UnoType<bool>::get(),            0, 0 },
         {u"" SC_UNO_PAGE_HDRSHARED,   ATTR_PAGE_SHARED,   
cppu::UnoType<bool>::get(),            0, 0 },
+        {u"" SC_UNO_PAGE_FIRSTHDRSHARED, ATTR_PAGE_SHARED_FIRST, 
cppu::UnoType<bool>::get(),     0, 0 },
         {u"" SC_UNO_PAGE_HDRLEFTBOR,  ATTR_BORDER,        
::cppu::UnoType<table::BorderLine>::get(),        0, LEFT_BORDER | 
CONVERT_TWIPS },
         {u"" SC_UNO_PAGE_HDRLEFTBDIS, ATTR_BORDER,        
::cppu::UnoType<sal_Int32>::get(),    0, LEFT_BORDER_DISTANCE | CONVERT_TWIPS },
         {u"" SC_UNO_PAGE_HDRLEFTMAR,  ATTR_LRSPACE,       
::cppu::UnoType<sal_Int32>::get(),            0, MID_L_MARGIN | CONVERT_TWIPS },
@@ -359,6 +364,7 @@ static const SfxItemPropertyMap* lcl_GetFooterStyleMap()
         {u"" SC_UNO_PAGE_FTRDYNAMIC,  ATTR_PAGE_DYNAMIC,  
cppu::UnoType<bool>::get(),            0, 0 },
         {u"" SC_UNO_PAGE_FTRON,       ATTR_PAGE_ON,       
cppu::UnoType<bool>::get(),            0, 0 },
         {u"" SC_UNO_PAGE_FTRSHARED,   ATTR_PAGE_SHARED,   
cppu::UnoType<bool>::get(),            0, 0 },
+        {u"" SC_UNO_PAGE_FIRSTFTRSHARED, ATTR_PAGE_SHARED_FIRST, 
cppu::UnoType<bool>::get(),     0, 0 },
         {u"" SC_UNO_PAGE_FTRLEFTBOR,  ATTR_BORDER,        
::cppu::UnoType<table::BorderLine>::get(),        0, LEFT_BORDER | 
CONVERT_TWIPS },
         {u"" SC_UNO_PAGE_FTRLEFTBDIS, ATTR_BORDER,        
::cppu::UnoType<sal_Int32>::get(),    0, LEFT_BORDER_DISTANCE | CONVERT_TWIPS },
         {u"" SC_UNO_PAGE_FTRLEFTMAR,  ATTR_LRSPACE,       
::cppu::UnoType<sal_Int32>::get(),            0, MID_L_MARGIN | CONVERT_TWIPS },
diff --git a/sc/source/ui/view/printfun.cxx b/sc/source/ui/view/printfun.cxx
index dc084ec75689..f099247cc2c6 100644
--- a/sc/source/ui/view/printfun.cxx
+++ b/sc/source/ui/view/printfun.cxx
@@ -653,6 +653,7 @@ static void lcl_FillHFParam( ScPrintHFParam& rParam, const 
SfxItemSet* pHFSet )
         rParam.bEnable  = pHFSet->Get(ATTR_PAGE_ON).GetValue();
         rParam.bDynamic = pHFSet->Get(ATTR_PAGE_DYNAMIC).GetValue();
         rParam.bShared  = pHFSet->Get(ATTR_PAGE_SHARED).GetValue();
+        rParam.bSharedFirst = pHFSet->Get(ATTR_PAGE_SHARED_FIRST).GetValue();
         rParam.nHeight  = pHFSet->Get(ATTR_PAGE_SIZE).GetSize().Height();
         const SvxLRSpaceItem* pHFLR = &pHFSet->Get(ATTR_LRSPACE);
         tools::Long nTmp;
@@ -814,6 +815,12 @@ void ScPrintFunc::UpdateHFHeight( ScPrintHFParam& rParam )
         nMaxHeight = std::max( nMaxHeight, TextHeight( 
rParam.pRight->GetCenterArea() ) );
         nMaxHeight = std::max( nMaxHeight, TextHeight( 
rParam.pRight->GetRightArea() ) );
     }
+    if ( rParam.pFirst )
+    {
+        nMaxHeight = std::max( nMaxHeight, TextHeight( 
rParam.pFirst->GetLeftArea() ) );
+        nMaxHeight = std::max( nMaxHeight, TextHeight( 
rParam.pFirst->GetCenterArea() ) );
+        nMaxHeight = std::max( nMaxHeight, TextHeight( 
rParam.pFirst->GetRightArea() ) );
+    }
 
     rParam.nHeight = nMaxHeight + rParam.nDistance;
     if (rParam.pBorder)
@@ -868,6 +875,7 @@ void ScPrintFunc::InitParam( const ScPrintOptions* pOptions 
)
 
     aHdr.pLeft      = &pParamSet->Get(ATTR_PAGE_HEADERLEFT);      // Content
     aHdr.pRight     = &pParamSet->Get(ATTR_PAGE_HEADERRIGHT);
+    aHdr.pFirst     = &pParamSet->Get(ATTR_PAGE_HEADERFIRST);
 
     const SvxSetItem* pHeaderSetItem;
     const SfxItemSet* pHeaderSet = nullptr;
@@ -884,6 +892,7 @@ void ScPrintFunc::InitParam( const ScPrintOptions* pOptions 
)
 
     aFtr.pLeft      = &pParamSet->Get(ATTR_PAGE_FOOTERLEFT);      // Content
     aFtr.pRight     = &pParamSet->Get(ATTR_PAGE_FOOTERRIGHT);
+    aFtr.pFirst     = &pParamSet->Get(ATTR_PAGE_FOOTERFIRST);
 
     const SvxSetItem* pFooterSetItem;
     const SfxItemSet* pFooterSet = nullptr;
@@ -1742,8 +1751,9 @@ void ScPrintFunc::PrintHF( tools::Long nPageNo, bool 
bHeader, tools::Long nStart
 
     pDev->SetMapMode( aTwipMode );          // Head-/Footlines in Twips
 
+    bool bFirst = 0 == nPageNo && !rParam.bSharedFirst;
     bool bLeft = IsLeft(nPageNo) && !rParam.bShared;
-    const ScPageHFItem* pHFItem = bLeft ? rParam.pLeft : rParam.pRight;
+    const ScPageHFItem* pHFItem = bFirst ? rParam.pFirst : (bLeft ? 
rParam.pLeft : rParam.pRight);
 
     tools::Long nLineStartX = aPageRect.Left()  + rParam.nLeft;
     tools::Long nLineEndX   = aPageRect.Right() - rParam.nRight;
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to