diff options
author | Michael Stahl <Michael.Stahl@cib.de> | 2020-08-13 11:07:37 +0200 |
---|---|---|
committer | Michael Stahl <Michael.Stahl@cib.de> | 2020-10-16 11:09:31 +0200 |
commit | a10fe43af77b877cc2d4a9ce5a1787755f9ce870 (patch) | |
tree | a27954891b88eb67e36e86cb83b79e2c02706408 | |
parent | cff383a342ef5e520709dfcb0a61571ea305cd61 (diff) |
sw: DOCX export: for soft-page-breaks, export continuous section breaks
When a section break is produced based on layout information such as
soft-page-break and follow page style, it's a bad idea to generate a
page break because the break may be in a different position in Word,
particularly if it was inside a fieldmark instruction.
It wouldn't work that well to ignore such page breaks in
MSWordExportBase::NeedTextNodeSplit() because then they would be created
when reaching the next node anyway, via FindPageDesc() fall-back to
layout.
Unfortunately this breaks the test tdf113849_evenAndOddHeaders.odt
which has a page style with follow-page-style on the first page; on
re-import from DOCX, the continuous section is now no longer converted
to a page break, so pages 2-3 have the wrong header/footers... this
seems impossible to fix in general in the import because it doesn't know
whether the continuous section break coincides with a layout page break.
Arguably this worked before mostly by accident? tdf#113849 isn't about
this afaics... Change the test file to have an explicit page break
there, which round-trips as intended. The real fix would be adding
continuous page style change to Writer i guess...
Change-Id: I00ffe3971607c148a7d5c13b89afb936718611c0
-rw-r--r-- | sw/qa/extras/ooxmlexport/data/tdf113849_evenAndOddHeaders.odt | bin | 24355 -> 24333 bytes | |||
-rw-r--r-- | sw/source/filter/ww8/docxexport.cxx | 8 | ||||
-rw-r--r-- | sw/source/filter/ww8/docxexport.hxx | 3 | ||||
-rw-r--r-- | sw/source/filter/ww8/rtfexport.cxx | 2 | ||||
-rw-r--r-- | sw/source/filter/ww8/rtfexport.hxx | 4 | ||||
-rw-r--r-- | sw/source/filter/ww8/wrtw8nds.cxx | 2 | ||||
-rw-r--r-- | sw/source/filter/ww8/wrtw8sty.cxx | 14 | ||||
-rw-r--r-- | sw/source/filter/ww8/wrtww8.hxx | 17 | ||||
-rw-r--r-- | sw/source/filter/ww8/ww8atr.cxx | 13 |
9 files changed, 39 insertions, 24 deletions
diff --git a/sw/qa/extras/ooxmlexport/data/tdf113849_evenAndOddHeaders.odt b/sw/qa/extras/ooxmlexport/data/tdf113849_evenAndOddHeaders.odt Binary files differindex d9aa0ae23541..ae9b2af14ee7 100644 --- a/sw/qa/extras/ooxmlexport/data/tdf113849_evenAndOddHeaders.odt +++ b/sw/qa/extras/ooxmlexport/data/tdf113849_evenAndOddHeaders.odt diff --git a/sw/source/filter/ww8/docxexport.cxx b/sw/source/filter/ww8/docxexport.cxx index a212f4e5c9b8..74f06116484a 100644 --- a/sw/source/filter/ww8/docxexport.cxx +++ b/sw/source/filter/ww8/docxexport.cxx @@ -619,7 +619,8 @@ sal_uLong DocxExport::ReplaceCr( sal_uInt8 ) void DocxExport::PrepareNewPageDesc( const SfxItemSet* pSet, const SwNode& rNd, const SwFormatPageDesc* pNewPgDescFormat, - const SwPageDesc* pNewPgDesc ) + const SwPageDesc* pNewPgDesc, + bool const bViaLayout) { // tell the attribute output that we are ready to write the section // break [has to be output inside paragraph properties] @@ -632,13 +633,12 @@ void DocxExport::PrepareNewPageDesc( const SfxItemSet* pSet, if ( pNewPgDescFormat ) { - m_pSections->AppendSection( *pNewPgDescFormat, rNd, pFormat, nLnNm ); + m_pSections->AppendSection(*pNewPgDescFormat, rNd, pFormat, nLnNm, bViaLayout); } else if ( pNewPgDesc ) { - m_pSections->AppendSection( pNewPgDesc, rNd, pFormat, nLnNm ); + m_pSections->AppendSection(pNewPgDesc, rNd, pFormat, nLnNm, bViaLayout); } - } void DocxExport::InitStyles() diff --git a/sw/source/filter/ww8/docxexport.hxx b/sw/source/filter/ww8/docxexport.hxx index 00b908dc7efa..35e37a98ae39 100644 --- a/sw/source/filter/ww8/docxexport.hxx +++ b/sw/source/filter/ww8/docxexport.hxx @@ -218,7 +218,8 @@ protected: virtual void PrepareNewPageDesc( const SfxItemSet* pSet, const SwNode& rNd, const SwFormatPageDesc* pNewPgDescFormat, - const SwPageDesc* pNewPgDesc ) override; + const SwPageDesc* pNewPgDesc, + bool bViaLayout ) override; private: /// Setup pStyles and write styles.xml diff --git a/sw/source/filter/ww8/rtfexport.cxx b/sw/source/filter/ww8/rtfexport.cxx index 366cc18b3b0c..0e8733b48d63 100644 --- a/sw/source/filter/ww8/rtfexport.cxx +++ b/sw/source/filter/ww8/rtfexport.cxx @@ -948,7 +948,7 @@ ErrCode RtfExport::ExportDocument_Impl() void RtfExport::PrepareNewPageDesc(const SfxItemSet* pSet, const SwNode& rNd, const SwFormatPageDesc* pNewPgDescFormat, - const SwPageDesc* pNewPgDesc) + const SwPageDesc* pNewPgDesc, bool const) { const SwSectionFormat* pFormat = GetSectionFormat(rNd); const sal_uLong nLnNm = GetSectionLineNo(pSet, rNd); diff --git a/sw/source/filter/ww8/rtfexport.hxx b/sw/source/filter/ww8/rtfexport.hxx index 055aa50ff04e..527574ad701e 100644 --- a/sw/source/filter/ww8/rtfexport.hxx +++ b/sw/source/filter/ww8/rtfexport.hxx @@ -125,8 +125,8 @@ protected: /// Get ready for a new section. void PrepareNewPageDesc(const SfxItemSet* pSet, const SwNode& rNd, - const SwFormatPageDesc* pNewPgDescFormat, - const SwPageDesc* pNewPgDesc) override; + const SwFormatPageDesc* pNewPgDescFormat, const SwPageDesc* pNewPgDesc, + bool bViaLayout) override; /// Return value indicates if an inherited outline numbering is suppressed. bool DisallowInheritingOutlineNumbering(const SwFormat& rFormat) override; diff --git a/sw/source/filter/ww8/wrtw8nds.cxx b/sw/source/filter/ww8/wrtw8nds.cxx index 74783f3e7110..dc6abf17899e 100644 --- a/sw/source/filter/ww8/wrtw8nds.cxx +++ b/sw/source/filter/ww8/wrtw8nds.cxx @@ -2742,7 +2742,7 @@ void MSWordExportBase::OutputTextNode( SwTextNode& rNode ) // too. const SwPageDesc* pNextPageDesc = m_pCurrentPageDesc->GetFollow(); assert(pNextPageDesc); - PrepareNewPageDesc( rNode.GetpSwAttrSet(), rNode, nullptr , pNextPageDesc); + PrepareNewPageDesc( rNode.GetpSwAttrSet(), rNode, nullptr , pNextPageDesc, true); } } else if (!bNeedParaSplit) diff --git a/sw/source/filter/ww8/wrtw8sty.cxx b/sw/source/filter/ww8/wrtw8sty.cxx index eb06b97195bb..e264d51a1ff2 100644 --- a/sw/source/filter/ww8/wrtw8sty.cxx +++ b/sw/source/filter/ww8/wrtw8sty.cxx @@ -1092,12 +1092,13 @@ const WW8_SepInfo* MSWordSections::CurrentSectionInfo() } void MSWordSections::AppendSection( const SwPageDesc* pPd, - const SwSectionFormat* pSectionFormat, sal_uLong nLnNumRestartNo, bool bIsFirstParagraph ) + const SwSectionFormat*const pSectionFormat, sal_uLong const nLnNumRestartNo, + bool const bIsFirstParagraph, bool const bIsContinuous) { if (HeaderFooterWritten()) { return; // #i117955# prevent new sections in endnotes } - aSects.emplace_back( pPd, pSectionFormat, nLnNumRestartNo, boost::none, nullptr, bIsFirstParagraph ); + aSects.emplace_back(pPd, pSectionFormat, nLnNumRestartNo, boost::none, nullptr, bIsFirstParagraph, bIsContinuous); NeedsDocumentProtected( aSects.back() ); } @@ -1112,13 +1113,14 @@ void WW8_WrPlcSepx::AppendSep( WW8_CP nStartCp, const SwPageDesc* pPd, } void MSWordSections::AppendSection( const SwFormatPageDesc& rPD, - const SwNode& rNd, const SwSectionFormat* pSectionFormat, sal_uLong nLnNumRestartNo ) + const SwNode& rNd, const SwSectionFormat*const pSectionFormat, + sal_uLong const nLnNumRestartNo, bool const bIsContinuous) { if (HeaderFooterWritten()) { return; // #i117955# prevent new sections in endnotes } - WW8_SepInfo aI( rPD.GetPageDesc(), pSectionFormat, nLnNumRestartNo, rPD.GetNumOffset(), &rNd ); + WW8_SepInfo aI(rPD.GetPageDesc(), pSectionFormat, nLnNumRestartNo, rPD.GetNumOffset(), &rNd, false, bIsContinuous); aSects.push_back( aI ); NeedsDocumentProtected( aI ); @@ -1548,9 +1550,9 @@ void MSWordExportBase::SectionProperties( const WW8_SepInfo& rSepInfo, WW8_PdAtt /* sprmSBkc, break code: 0 No break, 1 New column 2 New page, 3 Even page, 4 Odd page */ - sal_uInt8 nBreakCode = 2; // default start new page + sal_uInt8 nBreakCode = rSepInfo.isContinuous ? 0 : 2; // default start new page bool bOutPgDscSet = true, bLeftRightPgChain = false, bOutputStyleItemSet = false; - bool bEnsureHeaderFooterWritten = rSepInfo.pSectionFormat && rSepInfo.bIsFirstParagraph; + bool bEnsureHeaderFooterWritten = (rSepInfo.pSectionFormat && rSepInfo.bIsFirstParagraph) || rSepInfo.isContinuous; const SwFrameFormat* pPdFormat = &pPd->GetMaster(); if ( rSepInfo.pSectionFormat ) { diff --git a/sw/source/filter/ww8/wrtww8.hxx b/sw/source/filter/ww8/wrtww8.hxx index 9356b87bd86f..43dce01a807c 100644 --- a/sw/source/filter/ww8/wrtww8.hxx +++ b/sw/source/filter/ww8/wrtww8.hxx @@ -181,13 +181,16 @@ struct WW8_SepInfo sal_uLong const nLnNumRestartNo; ::boost::optional<sal_uInt16> const oPgRestartNo; bool const bIsFirstParagraph; + bool isContinuous; WW8_SepInfo( const SwPageDesc* pPD, const SwSectionFormat* pFormat, sal_uLong nLnRestart, ::boost::optional<sal_uInt16> oPgRestart = boost::none, - const SwNode* pNd = nullptr, bool bIsFirstPara = false ) + const SwNode* pNd = nullptr, bool bIsFirstPara = false, + bool bIsContinuous = false) : pPageDesc( pPD ), pSectionFormat( pFormat ), pPDNd( pNd ), nLnNumRestartNo( nLnRestart ), oPgRestartNo( oPgRestart ), bIsFirstParagraph( bIsFirstPara ) + , isContinuous(bIsContinuous) {} bool IsProtected() const; @@ -216,11 +219,13 @@ public: void AppendSection( const SwPageDesc* pPd, const SwSectionFormat* pSectionFormat, sal_uLong nLnNumRestartNo, - bool bIsFirstParagraph = false ); + bool bIsFirstParagraph = false, + bool bIsContinuous = false); void AppendSection( const SwFormatPageDesc& rPd, const SwNode& rNd, const SwSectionFormat* pSectionFormat, - sal_uLong nLnNumRestartNo ); + sal_uLong nLnNumRestartNo, + bool bIsContinuous = false); /// Number of columns based on the most recent WW8_SepInfo. sal_uInt16 CurrentNumberOfColumns( const SwDoc &rDoc ) const; @@ -854,7 +859,8 @@ protected: virtual void PrepareNewPageDesc( const SfxItemSet* pSet, const SwNode& rNd, const SwFormatPageDesc* pNewPgDescFormat, - const SwPageDesc* pNewPgDesc ) = 0; + const SwPageDesc* pNewPgDesc, + bool bViaLayout ) = 0; /// Return value indicates if an inherited outline numbering is suppressed. virtual bool DisallowInheritingOutlineNumbering(const SwFormat &rFormat) = 0; @@ -1121,7 +1127,8 @@ public: virtual void PrepareNewPageDesc( const SfxItemSet* pSet, const SwNode& rNd, const SwFormatPageDesc* pNewPgDescFormat, - const SwPageDesc* pNewPgDesc ) override; + const SwPageDesc* pNewPgDesc, + bool bViaLayout ) override; static void Out_BorderLine(ww::bytes& rO, const ::editeng::SvxBorderLine* pLine, sal_uInt16 nDist, sal_uInt16 nSprmNo, sal_uInt16 nSprmNoVer9, diff --git a/sw/source/filter/ww8/ww8atr.cxx b/sw/source/filter/ww8/ww8atr.cxx index 0b2c6527c0ea..87d6545d3391 100644 --- a/sw/source/filter/ww8/ww8atr.cxx +++ b/sw/source/filter/ww8/ww8atr.cxx @@ -457,7 +457,9 @@ void MSWordExportBase::OutputSectionBreaks( const SfxItemSet *pSet, const SwNode //section. bool bBreakSet = false; - const SwPageDesc * pPageDesc = rNd.FindPageDesc(); + size_t idx(0); + const SwPageDesc * pPageDesc = rNd.FindPageDesc(&idx); + bool isViaLayout(idx == rNd.GetIndex()); // Even if pAktPageDesc != pPageDesc ,it might be because of the different header & footer types. if (m_pCurrentPageDesc != pPageDesc) @@ -524,6 +526,7 @@ void MSWordExportBase::OutputSectionBreaks( const SfxItemSet *pSet, const SwNode static_cast<const SwFormatPageDesc*>(pItem)->GetRegisteredIn() != nullptr) { bBreakSet = true; + assert(!isViaLayout); bNewPageDesc = true; pPgDesc = static_cast<const SwFormatPageDesc*>(pItem); m_pCurrentPageDesc = pPgDesc->GetPageDesc(); @@ -551,6 +554,7 @@ void MSWordExportBase::OutputSectionBreaks( const SfxItemSet *pSet, const SwNode } } bBreakSet = true; + isViaLayout = false; if ( !bRemoveHardBreakInsideTable ) { @@ -617,7 +621,7 @@ void MSWordExportBase::OutputSectionBreaks( const SfxItemSet *pSet, const SwNode if ( bNewPageDesc && m_pCurrentPageDesc ) { - PrepareNewPageDesc( pSet, rNd, pPgDesc, m_pCurrentPageDesc ); + PrepareNewPageDesc(pSet, rNd, pPgDesc, m_pCurrentPageDesc, isViaLayout); } m_bBreakBefore = false; m_bPrevTextNodeIsEmpty = isTextNodeEmpty ; @@ -632,7 +636,7 @@ bool MSWordExportBase::OutputFollowPageDesc( const SfxItemSet* pSet, const SwTex m_pCurrentPageDesc && m_pCurrentPageDesc != m_pCurrentPageDesc->GetFollow() ) { - PrepareNewPageDesc( pSet, *pNd, nullptr, m_pCurrentPageDesc->GetFollow() ); + PrepareNewPageDesc(pSet, *pNd, nullptr, m_pCurrentPageDesc->GetFollow(), true); bRet = true; } @@ -670,7 +674,8 @@ sal_uLong MSWordExportBase::GetSectionLineNo( const SfxItemSet* pSet, const SwNo void WW8Export::PrepareNewPageDesc( const SfxItemSet*pSet, const SwNode& rNd, const SwFormatPageDesc* pNewPgDescFormat, - const SwPageDesc* pNewPgDesc ) + const SwPageDesc* pNewPgDesc, + bool const ) { // The PageDescs will only be inserted in WW8Writer::pSepx with the corresponding // position by the occurrences of PageDesc attributes. The construction and |