summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Stahl <Michael.Stahl@cib.de>2020-08-13 11:07:37 +0200
committerMichael Stahl <Michael.Stahl@cib.de>2020-10-16 11:09:31 +0200
commita10fe43af77b877cc2d4a9ce5a1787755f9ce870 (patch)
treea27954891b88eb67e36e86cb83b79e2c02706408
parentcff383a342ef5e520709dfcb0a61571ea305cd61 (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.odtbin24355 -> 24333 bytes
-rw-r--r--sw/source/filter/ww8/docxexport.cxx8
-rw-r--r--sw/source/filter/ww8/docxexport.hxx3
-rw-r--r--sw/source/filter/ww8/rtfexport.cxx2
-rw-r--r--sw/source/filter/ww8/rtfexport.hxx4
-rw-r--r--sw/source/filter/ww8/wrtw8nds.cxx2
-rw-r--r--sw/source/filter/ww8/wrtw8sty.cxx14
-rw-r--r--sw/source/filter/ww8/wrtww8.hxx17
-rw-r--r--sw/source/filter/ww8/ww8atr.cxx13
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
index d9aa0ae23541..ae9b2af14ee7 100644
--- a/sw/qa/extras/ooxmlexport/data/tdf113849_evenAndOddHeaders.odt
+++ b/sw/qa/extras/ooxmlexport/data/tdf113849_evenAndOddHeaders.odt
Binary files differ
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