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));