From 1b0f859c625b32c9fb21d0fc67b786f464794389 Mon Sep 17 00:00:00 2001 From: Miklos Vajna Date: Thu, 6 Feb 2020 14:47:08 +0100 Subject: DOCX export: fix handling of section starts that originally had headers Both the DOC import (in wwSectionManager::InsertSegments()) and DOCX import (in SectionPropertyMap::CloseSectionGroup()) have a mechanism to try to attach changed headers/footers from a continuous section break somewhere, so they are not lost. This means that even if the rendering of such documents is OK, explicit code is needed to undo the effect of the importer at export time, or those headers will be lost. Start doing this for the DOCX export case when the headers/footers are placed at the "previous-in-practice" paragraph, more cases (handled at the import side) can be added later. (cherry picked from commit 26f2a9e1a10a22e864e71ee7c94934821703e021) Conflicts: sw/source/filter/ww8/wrtw8sty.cxx Change-Id: Ic2304a74919d18da3ba9cb4afe301e0247a50dc2 --- sw/source/filter/ww8/wrtw8sty.cxx | 80 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) (limited to 'sw/source/filter/ww8/wrtw8sty.cxx') diff --git a/sw/source/filter/ww8/wrtw8sty.cxx b/sw/source/filter/ww8/wrtw8sty.cxx index d04cfeb8e6f8..2908f78fef0e 100644 --- a/sw/source/filter/ww8/wrtw8sty.cxx +++ b/sw/source/filter/ww8/wrtw8sty.cxx @@ -34,6 +34,7 @@ #include #include #include +#include #include #include "wrtww8.hxx" #include @@ -60,6 +61,7 @@ #include #include #include +#include #include "sprmids.hxx" @@ -1518,6 +1520,76 @@ void WW8Export::WriteHeadersFooters( sal_uInt8 nHeadFootFlags, pSepx->OutHeaderFooter( *this, false, rFirstPageFormat, nCpPos, nHeadFootFlags, WW8_FOOTER_FIRST, nBreakCode ); } +namespace +{ +/** + * Find a node near the section start that has a page break, it may have a follow header/footer for + * us. + */ +bool WriteNextStyleHeaderFooter(sal_uInt8 nBreakCode, sal_uInt8 nHeadFootFlags, + const SwPageDesc* pPd, const WW8_SepInfo& rSepInfo) +{ + if (nBreakCode != 0) + { + // Not a continuous section break. + return false; + } + + if (nHeadFootFlags != 0) + { + // Would write some header/footer anyway. + return false; + } + + if (!pPd->GetFollow()) + { + // Page style has no follow style. + return false; + } + + // We start a continuous section break without headers/footers. Possibly the importer had + // headers/footers for this section break and put them to the closest page break's page style's + // next page style. See "find a node in the section that has a page break" in writerfilter/. + // Try the last-in-practice paragraph of the previous section. + const SwSectionFormat* pSection = rSepInfo.pSectionFormat; + if (pSection == reinterpret_cast(sal_IntPtr(-1))) + { + return false; + } + + const SwNodeIndex* pSectionStart = pSection->GetContent().GetContentIdx(); + if (!pSectionStart) + { + return false; + } + + SwPaM aPaM(*pSectionStart); + aPaM.Move(fnMoveBackward); + if (!aPaM.GetNode().IsTextNode()) + { + return false; + } + + SwTextNode* pTextNode = aPaM.GetNode().GetTextNode(); + const SwAttrSet* pParaProps = &pTextNode->GetSwAttrSet(); + sal_uInt32 nCharHeight = pParaProps->GetSize().GetHeight(); + if (nCharHeight > 20) + { + return false; + } + + aPaM.Move(fnMoveBackward); + if (!aPaM.GetNode().IsTextNode()) + { + return false; + } + + pTextNode = aPaM.GetNode().GetTextNode(); + pParaProps = &pTextNode->GetSwAttrSet(); + return pParaProps->HasItem(RES_PAGEDESC); +} +} + void MSWordExportBase::SectionProperties( const WW8_SepInfo& rSepInfo, WW8_PdAttrDesc* pA ) { const SwPageDesc* pPd = rSepInfo.pPageDesc; @@ -1769,6 +1841,14 @@ void MSWordExportBase::SectionProperties( const WW8_SepInfo& rSepInfo, WW8_PdAtt const SwTextNode *pOldPageRoot = GetHdFtPageRoot(); SetHdFtPageRoot( rSepInfo.pPDNd ? rSepInfo.pPDNd->GetTextNode() : nullptr ); + if (GetExportFormat() == ExportFormat::DOCX + && WriteNextStyleHeaderFooter(nBreakCode, nHeadFootFlags, pPd, rSepInfo)) + { + pPdFormat = &pPd->GetFollow()->GetMaster(); + MSWordSections::SetHeaderFlag(nHeadFootFlags, *pPdFormat, WW8_HEADER_ODD); + MSWordSections::SetFooterFlag(nHeadFootFlags, *pPdFormat, WW8_FOOTER_ODD); + } + WriteHeadersFooters( nHeadFootFlags, *pPdFormat, *pPdLeftFormat, *pPdFirstPgFormat, nBreakCode ); SetHdFtPageRoot( pOldPageRoot ); -- cgit