[Libreoffice-commits] core.git: Branch 'distro/nisz/libreoffice-7-0' - sc/qa sc/source

Attila Szűcs (via logerrit) logerrit at kemper.freedesktop.org
Thu Feb 18 09:37:10 UTC 2021


 sc/qa/unit/data/ods/tdf121716_EvenHeaderFooter.ods |binary
 sc/qa/unit/subsequent_export-test.cxx              |   52 ++++++++++++++++++---
 sc/source/filter/excel/xepage.cxx                  |   49 +++++++++++++++++--
 sc/source/filter/excel/xipage.cxx                  |    8 ++-
 sc/source/filter/excel/xlpage.cxx                  |    3 +
 sc/source/filter/inc/xlpage.hxx                    |    9 +++
 6 files changed, 106 insertions(+), 15 deletions(-)

New commits:
commit 74ff90587db28aa199fdbcae0abb7f37f83fb617
Author:     Attila Szűcs <szucs.attila3 at nisz.hu>
AuthorDate: Thu Jul 23 14:51:01 2020 +0200
Commit:     Gabor Kelemen <kelemen.gabor2 at nisz.hu>
CommitDate: Thu Feb 18 10:36:27 2021 +0100

    tdf#121716 XLSX export: fix loss of left header (footer)
    
    when footer (header) is shared (even).
    
    Co-authored-by: Tibor Nagy (NISZ)
    
    Change-Id: I6e656f2df1f9b6522af933bd1c71b8d60bbfe19f
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/99315
    Tested-by: László Németh <nemeth at numbertext.org>
    Reviewed-by: László Németh <nemeth at numbertext.org>
    (cherry picked from commit a858284092e976fa284d5ed118e366d9860ec9bb)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/111048
    Tested-by: Gabor Kelemen <kelemen.gabor2 at nisz.hu>
    Reviewed-by: Gabor Kelemen <kelemen.gabor2 at nisz.hu>

diff --git a/sc/qa/unit/data/ods/tdf121716_EvenHeaderFooter.ods b/sc/qa/unit/data/ods/tdf121716_EvenHeaderFooter.ods
new file mode 100644
index 000000000000..2666a9d4291e
Binary files /dev/null and b/sc/qa/unit/data/ods/tdf121716_EvenHeaderFooter.ods differ
diff --git a/sc/qa/unit/subsequent_export-test.cxx b/sc/qa/unit/subsequent_export-test.cxx
index 56f38a3697a9..e84a464ab886 100644
--- a/sc/qa/unit/subsequent_export-test.cxx
+++ b/sc/qa/unit/subsequent_export-test.cxx
@@ -257,8 +257,9 @@ public:
     void testTdf131372();
     void testTdf122331();
     void testTdf83779();
-    void testTdf134817_HeaderFooterTextWith2SectionXLSX();
+    void testTdf121716_ExportEvenHeaderFooterXLSX();
     void testTdf134459_HeaderFooterColorXLSX();
+    void testTdf134817_HeaderFooterTextWith2SectionXLSX();
     void testHeaderFontStyleXLSX();
     void testTdf135828_Shape_Rect();
     void testTdf123353();
@@ -414,6 +415,7 @@ public:
     CPPUNIT_TEST(testTdf131372);
     CPPUNIT_TEST(testTdf122331);
     CPPUNIT_TEST(testTdf83779);
+    CPPUNIT_TEST(testTdf121716_ExportEvenHeaderFooterXLSX);
     CPPUNIT_TEST(testTdf134817_HeaderFooterTextWith2SectionXLSX);
     CPPUNIT_TEST(testTdf134459_HeaderFooterColorXLSX);
     CPPUNIT_TEST(testHeaderFontStyleXLSX);
@@ -5195,20 +5197,36 @@ void ScExportTest::testTdf83779()
     xShell->DoClose();
 }
 
-void ScExportTest::testTdf134817_HeaderFooterTextWith2SectionXLSX()
+void ScExportTest::testTdf121716_ExportEvenHeaderFooterXLSX()
 {
-    // Header/footer text with multiple selection should be exported, and imported properly
-    ScDocShellRef xShell = loadDoc("tdf134817_HeaderFooterTextWith2Section.", FORMAT_XLSX);
+    // Header and footer on even pages should be exported properly
+    // If there are separate odd/even header, but only 1 footer for all pages (this is possible only in LibreOffice)
+    //  then the footer will be duplicated to have the same footer separately for even/odd pages
+
+    ScDocShellRef xShell = loadDoc("tdf121716_EvenHeaderFooter.", FORMAT_ODS);
     CPPUNIT_ASSERT(xShell.is());
 
     ScDocShellRef xDocSh = saveAndReload(&(*xShell), FORMAT_XLSX);
     CPPUNIT_ASSERT(xDocSh.is());
 
-    xmlDocUniquePtr pDoc = XPathHelper::parseExport2(*this, *xDocSh, m_xSFactory, "xl/worksheets/sheet1.xml", FORMAT_XLSX);
+    std::shared_ptr<utl::TempFile> pXPathFile = ScBootstrapFixture::exportTo(&(*xDocSh), FORMAT_XLSX);
+    xmlDocUniquePtr pDoc = XPathHelper::parseExport(pXPathFile, m_xSFactory, "xl/worksheets/sheet1.xml");
     CPPUNIT_ASSERT(pDoc);
 
-    assertXPathContent(pDoc, "/x:worksheet/x:headerFooter/x:oddHeader", "&L&\"Abadi,Regular\"&11aaa&\"Bembo,Regular\"&20bbb");
-    assertXPathContent(pDoc, "/x:worksheet/x:headerFooter/x:oddFooter", "&R&\"Cambria,Regular\"&14camb&\"Dante,Regular\"&18dant");
+    assertXPath(pDoc, "/x:worksheet/x:headerFooter", "differentOddEven", "true");
+    assertXPathContent(pDoc, "/x:worksheet/x:headerFooter/x:oddHeader", "&Lodd/right&Cpage&Rheader");
+    assertXPathContent(pDoc, "/x:worksheet/x:headerFooter/x:oddFooter", "&Lboth&C&12page&Rfooter");
+    assertXPathContent(pDoc, "/x:worksheet/x:headerFooter/x:evenHeader", "&Lpage&Cheader&Reven/left");
+    assertXPathContent(pDoc, "/x:worksheet/x:headerFooter/x:evenFooter", "&Lboth&C&12page&Rfooter");
+
+    pDoc = XPathHelper::parseExport(pXPathFile, m_xSFactory, "xl/worksheets/sheet2.xml");
+    CPPUNIT_ASSERT(pDoc);
+
+    assertXPath(pDoc, "/x:worksheet/x:headerFooter", "differentOddEven", "true");
+    assertXPathContent(pDoc, "/x:worksheet/x:headerFooter/x:oddHeader", "&Coddh");
+    assertXPathContent(pDoc, "/x:worksheet/x:headerFooter/x:oddFooter", "&Coddf");
+    assertXPathContent(pDoc, "/x:worksheet/x:headerFooter/x:evenHeader", "&Cevenh");
+    assertXPathContent(pDoc, "/x:worksheet/x:headerFooter/x:evenFooter", "&Levenf");
 
     xDocSh->DoClose();
 }
@@ -5227,6 +5245,26 @@ void ScExportTest::testTdf134459_HeaderFooterColorXLSX()
 
     assertXPathContent(pDoc, "/x:worksheet/x:headerFooter/x:oddHeader", "&L&Kc06040l&C&K4c3789c&Rr");
     assertXPathContent(pDoc, "/x:worksheet/x:headerFooter/x:oddFooter", "&Ll&C&K64cf5fc&R&Kcd15aar");
+
+    xDocSh->DoClose();
+}
+
+void ScExportTest::testTdf134817_HeaderFooterTextWith2SectionXLSX()
+{
+    // Header/footer text with multiple selection should be exported, and imported properly
+    ScDocShellRef xShell = loadDoc("tdf134817_HeaderFooterTextWith2Section.", FORMAT_XLSX);
+    CPPUNIT_ASSERT(xShell.is());
+
+    ScDocShellRef xDocSh = saveAndReload(&(*xShell), FORMAT_XLSX);
+    CPPUNIT_ASSERT(xDocSh.is());
+
+    xmlDocUniquePtr pDoc = XPathHelper::parseExport2(*this, *xDocSh, m_xSFactory, "xl/worksheets/sheet1.xml", FORMAT_XLSX);
+    CPPUNIT_ASSERT(pDoc);
+
+    assertXPathContent(pDoc, "/x:worksheet/x:headerFooter/x:oddHeader", "&L&\"Abadi,Regular\"&11aaa&\"Bembo,Regular\"&20bbb");
+    assertXPathContent(pDoc, "/x:worksheet/x:headerFooter/x:oddFooter", "&R&\"Cambria,Regular\"&14camb&\"Dante,Regular\"&18dant");
+
+    xDocSh->DoClose();
 }
 
 void ScExportTest::testHeaderFontStyleXLSX()
diff --git a/sc/source/filter/excel/xepage.cxx b/sc/source/filter/excel/xepage.cxx
index aea06c72157b..3941bd191f92 100644
--- a/sc/source/filter/excel/xepage.cxx
+++ b/sc/source/filter/excel/xepage.cxx
@@ -58,7 +58,14 @@ XclExpHeaderFooter::XclExpHeaderFooter( sal_uInt16 nRecId, const OUString& rHdrS
 void XclExpHeaderFooter::SaveXml( XclExpXmlStream& rStrm )
 {
     sax_fastparser::FSHelperPtr& rWorksheet = rStrm.GetCurrentStream();
-    sal_Int32 nElement = GetRecId() == EXC_ID_HEADER ?  XML_oddHeader : XML_oddFooter;
+    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_FOOTER:
+        default:                 nElement = XML_oddFooter;
+    }
     rWorksheet->startElement(nElement);
     rWorksheet->writeEscaped( maHdrString );
     rWorksheet->endElement( nElement );
@@ -252,7 +259,6 @@ XclExpPageSettings::XclExpPageSettings( const XclExpRoot& rRoot ) :
             maData.mnFitToWidth = rScaleToItem.GetWidth();
             maData.mnFitToHeight = rScaleToItem.GetHeight();
             maData.mbFitToPages = true;
-
         }
         else if( ScfTools::CheckItem( rItemSet, ATTR_PAGE_SCALETOPAGES, false ) && nPages )
         {
@@ -267,6 +273,7 @@ XclExpPageSettings::XclExpPageSettings( const XclExpRoot& rRoot ) :
         }
 
         maData.mxBrushItem.reset( new SvxBrushItem( rItemSet.Get( ATTR_BACKGROUND ) ) );
+        maData.mbUseEvenHF = false;
 
         // *** header and footer ***
 
@@ -279,6 +286,18 @@ XclExpPageSettings::XclExpPageSettings( const XclExpRoot& rRoot ) :
             const ScPageHFItem& rHFItem = rItemSet.Get( ATTR_PAGE_HEADERRIGHT );
             aHFConv.GenerateString( rHFItem.GetLeftArea(), rHFItem.GetCenterArea(), rHFItem.GetRightArea() );
             maData.maHeader = aHFConv.GetHFString();
+            if ( rHdrItemSet.HasItem(ATTR_PAGE_SHARED) && !rHdrItemSet.Get(ATTR_PAGE_SHARED).GetValue())
+            {
+                const ScPageHFItem& rHFItemLeft = rItemSet.Get( ATTR_PAGE_HEADERLEFT );
+                aHFConv.GenerateString( rHFItemLeft.GetLeftArea(), rHFItemLeft.GetCenterArea(), rHFItemLeft.GetRightArea() );
+                maData.maHeaderEven = aHFConv.GetHFString();
+                maData.mbUseEvenHF = true;
+            }
+            else
+            {
+                // If maData.mbUseEvenHF become true, then we will need a copy of maHeader in maHeaderEven.
+                maData.maHeaderEven = 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
@@ -296,6 +315,17 @@ XclExpPageSettings::XclExpPageSettings( const XclExpRoot& rRoot ) :
             const ScPageHFItem& rHFItem = rItemSet.Get( ATTR_PAGE_FOOTERRIGHT );
             aHFConv.GenerateString( rHFItem.GetLeftArea(), rHFItem.GetCenterArea(), rHFItem.GetRightArea() );
             maData.maFooter = aHFConv.GetHFString();
+            if (rFtrItemSet.HasItem(ATTR_PAGE_SHARED) && !rFtrItemSet.Get(ATTR_PAGE_SHARED).GetValue())
+            {
+                const ScPageHFItem& rHFItemLeft = rItemSet.Get( ATTR_PAGE_FOOTERLEFT );
+                aHFConv.GenerateString( rHFItemLeft.GetLeftArea(), rHFItemLeft.GetCenterArea(), rHFItemLeft.GetRightArea() );
+                maData.maFooterEven = aHFConv.GetHFString();
+                maData.mbUseEvenHF = true;
+            }
+            else
+            {
+                maData.maFooterEven = 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
@@ -340,10 +370,12 @@ namespace {
 class XclExpXmlStartHeaderFooterElementRecord : public XclExpXmlElementRecord
 {
 public:
-    explicit XclExpXmlStartHeaderFooterElementRecord(sal_Int32 const nElement)
-         : XclExpXmlElementRecord(nElement) {}
+    explicit XclExpXmlStartHeaderFooterElementRecord(sal_Int32 const nElement, bool const bDifferentOddEven = false)
+         : XclExpXmlElementRecord(nElement), mbDifferentOddEven(bDifferentOddEven) {}
 
     virtual void        SaveXml( XclExpXmlStream& rStrm ) override;
+private:
+    bool            mbDifferentOddEven;
 };
 
 }
@@ -356,7 +388,7 @@ void XclExpXmlStartHeaderFooterElementRecord::SaveXml(XclExpXmlStream& rStrm)
     rStream->startElement( mnElement,
             // OOXTODO: XML_alignWithMargins,
             XML_differentFirst,     "false",    // OOXTODO
-            XML_differentOddEven,   "false"     // OOXTODO
+            XML_differentOddEven,   mbDifferentOddEven ? "true" : "false"
             // OOXTODO: XML_scaleWithDoc
     );
 }
@@ -404,9 +436,14 @@ void XclExpPageSettings::SaveXml( XclExpXmlStream& rStrm )
 
     XclExpSetup( maData ).SaveXml( rStrm );
 
-    XclExpXmlStartHeaderFooterElementRecord(XML_headerFooter).SaveXml(rStrm);
+    XclExpXmlStartHeaderFooterElementRecord(XML_headerFooter, maData.mbUseEvenHF).SaveXml(rStrm);
     XclExpHeaderFooter( EXC_ID_HEADER, maData.maHeader ).SaveXml( rStrm );
     XclExpHeaderFooter( EXC_ID_FOOTER, maData.maFooter ).SaveXml( rStrm );
+    if (maData.mbUseEvenHF)
+    {
+        XclExpHeaderFooter( EXC_ID_HEADER_EVEN, maData.maHeaderEven ).SaveXml( rStrm );
+        XclExpHeaderFooter( EXC_ID_FOOTER_EVEN, maData.maFooterEven ).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 7436c3eaed2c..c0207a033b00 100644
--- a/sc/source/filter/excel/xipage.cxx
+++ b/sc/source/filter/excel/xipage.cxx
@@ -118,13 +118,17 @@ void XclImpPageSettings::ReadHeaderFooter( XclImpStream& rStrm )
 
     switch( rStrm.GetRecId() )
     {
-        case EXC_ID_HEADER:     maData.maHeader = aString;  break;
-        case EXC_ID_FOOTER:     maData.maFooter = aString;  break;
+        case EXC_ID_HEADER:          maData.maHeader = aString;  break;
+        case EXC_ID_FOOTER:          maData.maFooter = aString;  break;
+        case EXC_ID_HEADER_EVEN:     maData.maHeaderEven = aString;  break;
+        case EXC_ID_FOOTER_EVEN:     maData.maFooterEven = aString;  break;
         default:    OSL_FAIL( "XclImpPageSettings::ReadHeaderFooter - unknown record" );
     }
 
     if (maData.maHeader.getLength() > 10 && utl::ConfigManager::IsFuzzing())
         maData.maHeader = maData.maHeader.copy(0, 10);
+    if (maData.maHeaderEven.getLength() > 10 && utl::ConfigManager::IsFuzzing())
+        maData.maHeaderEven = maData.maHeaderEven.copy(0, 10);
 }
 
 void XclImpPageSettings::ReadPageBreaks( XclImpStream& rStrm )
diff --git a/sc/source/filter/excel/xlpage.cxx b/sc/source/filter/excel/xlpage.cxx
index fb08932872f1..3f13befddcfa 100644
--- a/sc/source/filter/excel/xlpage.cxx
+++ b/sc/source/filter/excel/xlpage.cxx
@@ -180,6 +180,8 @@ void XclPageData::SetDefaults()
     mxBrushItem.reset();
     maHeader.clear();
     maFooter.clear();
+    maHeaderEven.clear();
+    maFooterEven.clear();
     mfLeftMargin    = mfRightMargin    = XclTools::GetInchFromHmm( EXC_MARGIN_DEFAULT_LR );
     mfTopMargin     = mfBottomMargin   = XclTools::GetInchFromHmm( EXC_MARGIN_DEFAULT_TB );
     mfHeaderMargin  = mfFooterMargin   = XclTools::GetInchFromHmm( EXC_MARGIN_DEFAULT_HF );
@@ -193,6 +195,7 @@ void XclPageData::SetDefaults()
     mnScaling = 100;
     mnFitToWidth = mnFitToHeight = 1;
     mnHorPrintRes = mnVerPrintRes = 300;
+    mbUseEvenHF = /*mbUseFirstHF =*/ false;
     mbValid = false;
     mbPortrait = true;
     mbPrintInRows = mbBlackWhite = mbDraftQuality = mbPrintNotes = mbManualStart = mbFitToPages = false;
diff --git a/sc/source/filter/inc/xlpage.hxx b/sc/source/filter/inc/xlpage.hxx
index 8ae20f85d1ba..36190b2e8693 100644
--- a/sc/source/filter/inc/xlpage.hxx
+++ b/sc/source/filter/inc/xlpage.hxx
@@ -31,6 +31,11 @@
 const sal_uInt16 EXC_ID_HEADER              = 0x0014;
 const sal_uInt16 EXC_ID_FOOTER              = 0x0015;
 
+// (0x0016, 0x0017) EVEN HEADER, EVEN FOOTER ----------------------------------
+
+const sal_uInt16 EXC_ID_HEADER_EVEN         = 0x0016;
+const sal_uInt16 EXC_ID_FOOTER_EVEN         = 0x0017;
+
 // (0x001A, 0x001B) VERTICAL-, HORIZONTALPAGEBREAKS ---------------------------
 
 const sal_uInt16 EXC_ID_VERPAGEBREAKS       = 0x001A;
@@ -102,6 +107,8 @@ struct XclPageData
     SvxBrushItemPtr     mxBrushItem;        /// Background bitmap.
     OUString            maHeader;           /// Excel header string (empty = off).
     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).
     double              mfLeftMargin;       /// Left margin in inches.
     double              mfRightMargin;      /// Right margin in inches.
     double              mfTopMargin;        /// Top margin in inches.
@@ -123,6 +130,8 @@ struct XclPageData
     sal_uInt16          mnFitToHeight;      /// Fit to number of pages in height.
     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                mbValid;            /// false = some of the values are not valid.
     bool                mbPortrait;         /// true = portrait; false = landscape.
     bool                mbPrintInRows;      /// true = in rows; false = in columns.


More information about the Libreoffice-commits mailing list