sw/qa/core/header_footer/HeaderFooterTest.cxx                 |   13 ++++++++++
 sw/qa/core/header_footer/data/tdf1159013_firstHeaderCopy.docx |binary
 sw/source/writerfilter/dmapper/DomainMapper_Impl.cxx          |   10 +++++++
 sw/source/writerfilter/dmapper/DomainMapper_Impl.hxx          |   12 +++++++++
 sw/source/writerfilter/dmapper/PropertyMap.cxx                |    6 +++-
 5 files changed, 39 insertions(+), 2 deletions(-)

New commits:
commit eaca93b19ebf91e495c0985f304bfa6687c55c8d
Author:     Justin Luth <jl...@mail.com>
AuthorDate: Tue Jul 9 20:41:34 2024 -0400
Commit:     Tomaž Vajngerl <qui...@gmail.com>
CommitDate: Thu Jul 11 08:55:32 2024 +0200

    tdf#159013 writerfilter: link to the correct first-page header
    
    We have always done this wrong, but previous to
    quikee's 24.2 4b0fa253a4540f5461397815d290586f9ddabe61
    it left the first page blank (I expect),
    while recently it was copying the "normal" header.
    
    In order to avoid a UNO copy assert (if copying an empty footer)
    track the header and footer style separately.
    Alternatively I could have probably removed the UNO assert.
    Alternatively, I could track if we ever had a first header
    and a first footer - at that point they will be copied to same style.
    
    make CppunitTest_sw_core_header_footer \
        CPPUNIT_TEST_NAME=testTdf1159013_firstHeaderCopy
    
    Change-Id: I7c5046731766a70625b1a6a8696239297369e2c5
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/170259
    Tested-by: Jenkins
    Reviewed-by: Justin Luth <jl...@mail.com>
    Reviewed-by: Tomaž Vajngerl <qui...@gmail.com>

diff --git a/sw/qa/core/header_footer/HeaderFooterTest.cxx 
b/sw/qa/core/header_footer/HeaderFooterTest.cxx
index acfd77f1270e..763012652c7c 100644
--- a/sw/qa/core/header_footer/HeaderFooterTest.cxx
+++ b/sw/qa/core/header_footer/HeaderFooterTest.cxx
@@ -525,6 +525,19 @@ CPPUNIT_TEST_FIXTURE(HeaderFooterTest, 
testTdf145998_firstHeader)
     CPPUNIT_ASSERT_EQUAL(u"Normal Header"_ustr, 
parseDump("/root/page[2]/header/txt"_ostr));
 }
 
+CPPUNIT_TEST_FIXTURE(HeaderFooterTest, testTdf1159013_firstHeaderCopy)
+{
+    // given a document with a first-header-section, a non-first-section, then 
a first-link-section
+    createSwDoc("tdf1159013_firstHeaderCopy.docx");
+    saveAndReload(u"Office Open XML Text"_ustr);
+
+    // Sanity check - always good to test when dealing with page styles and 
breaks.
+    CPPUNIT_ASSERT_EQUAL(5, getPages());
+
+    // This was copying the non-first-section header instead of "linking" to 
the first
+    CPPUNIT_ASSERT_EQUAL(u"First Page header"_ustr, 
parseDump("/root/page[5]/header/txt"_ostr));
+}
+
 CPPUNIT_TEST_FIXTURE(HeaderFooterTest, testEvenPageOddPageFooter_Import)
 {
     // Related tdf#135216
diff --git a/sw/qa/core/header_footer/data/tdf1159013_firstHeaderCopy.docx 
b/sw/qa/core/header_footer/data/tdf1159013_firstHeaderCopy.docx
new file mode 100644
index 000000000000..fa2c84cbe4cd
Binary files /dev/null and 
b/sw/qa/core/header_footer/data/tdf1159013_firstHeaderCopy.docx differ
diff --git a/sw/source/writerfilter/dmapper/DomainMapper_Impl.cxx 
b/sw/source/writerfilter/dmapper/DomainMapper_Impl.cxx
index 6cecc59dd4a4..f36232dba47e 100644
--- a/sw/source/writerfilter/dmapper/DomainMapper_Impl.cxx
+++ b/sw/source/writerfilter/dmapper/DomainMapper_Impl.cxx
@@ -3992,6 +3992,16 @@ void DomainMapper_Impl::PopPageHeaderFooter(PagePartType 
ePagePartType, PageType
     if (pSectionContext)
     {
         pSectionContext->clearHeaderFooterLinkToPrevious(ePagePartType, eType);
+
+        // remember most recent "first page" header/footer so follow sections 
can "link" to them
+        if (eType == PageType::FIRST)
+        {
+            if (ePagePartType == PagePartType::Header)
+                m_pLastFirstHeader = pSectionContext->GetPageStyle(*this);
+            else if (ePagePartType == PagePartType::Footer)
+                m_pLastFirstFooter = pSectionContext->GetPageStyle(*this);
+        }
+
         m_HeaderFooterSeen.emplace(ePagePartType, eType);
     }
 
diff --git a/sw/source/writerfilter/dmapper/DomainMapper_Impl.hxx 
b/sw/source/writerfilter/dmapper/DomainMapper_Impl.hxx
index 1697ee9e849d..a4040b1f09d4 100644
--- a/sw/source/writerfilter/dmapper/DomainMapper_Impl.hxx
+++ b/sw/source/writerfilter/dmapper/DomainMapper_Impl.hxx
@@ -617,6 +617,8 @@ private:
 
     PropertyMapPtr                  m_pTopContext;
     tools::SvRef<SectionPropertyMap> m_pLastSectionContext;
+    rtl::Reference<SwXPageStyle> m_pLastFirstHeader; // last page style with 
different first header
+    rtl::Reference<SwXPageStyle> m_pLastFirstFooter; // last page style with 
different first footer
     PropertyMapPtr           m_pLastCharacterContext;
 
     ::std::vector<DeletableTabStop> m_aCurrentTabStops;
@@ -714,6 +716,16 @@ public:
         return m_pLastSectionContext.get( );
     }
 
+    const rtl::Reference<SwXPageStyle>& GetLastFirstHeader() const
+    {
+        return m_pLastFirstHeader;
+    }
+
+    const rtl::Reference<SwXPageStyle>& GetLastFirstFooter() const
+    {
+        return m_pLastFirstFooter;
+    }
+
     css::uno::Reference<css::container::XNameContainer> const & 
GetPageStyles();
     OUString GetUnusedPageStyleName();
     css::uno::Reference<css::container::XNameContainer> const & 
GetCharacterStyles();
diff --git a/sw/source/writerfilter/dmapper/PropertyMap.cxx 
b/sw/source/writerfilter/dmapper/PropertyMap.cxx
index 3eeaf79ce4f8..c4754c6095ee 100644
--- a/sw/source/writerfilter/dmapper/PropertyMap.cxx
+++ b/sw/source/writerfilter/dmapper/PropertyMap.cxx
@@ -1063,7 +1063,8 @@ void copyHeaderFooter(const DomainMapper_Impl& rDM_Impl,
         if (bCopyLeftHeader && bEvenAndOdd)
             copyHeaderFooterTextProperty(xPreviousStyle, xStyle, 
PROP_HEADER_TEXT_LEFT);
         if (bCopyFirstHeader && bTitlePage)
-            copyHeaderFooterTextProperty(xPreviousStyle, xStyle, 
PROP_HEADER_TEXT_FIRST);
+            copyHeaderFooterTextProperty(rDM_Impl.GetLastFirstHeader(), xStyle,
+                                         PROP_HEADER_TEXT_FIRST);
     }
 
     if (bPreviousHasFooter && bCopyFooter)
@@ -1073,7 +1074,8 @@ void copyHeaderFooter(const DomainMapper_Impl& rDM_Impl,
         if (bCopyLeftFooter && bEvenAndOdd)
             copyHeaderFooterTextProperty(xPreviousStyle, xStyle, 
PROP_FOOTER_TEXT_LEFT);
         if (bCopyFirstFooter && bTitlePage)
-            copyHeaderFooterTextProperty(xPreviousStyle, xStyle, 
PROP_FOOTER_TEXT_FIRST);
+            copyHeaderFooterTextProperty(rDM_Impl.GetLastFirstFooter(), xStyle,
+                                         PROP_FOOTER_TEXT_FIRST);
     }
 
     xStyle->setPropertyValue(sHeaderIsOn, uno::Any(bPreviousHasHeader || 
bHasHeader));

Reply via email to