summaryrefslogtreecommitdiff
path: root/sw
diff options
context:
space:
mode:
authorMike Kaganski <mike.kaganski@collabora.com>2019-11-19 22:41:52 +0300
committerMike Kaganski <mike.kaganski@collabora.com>2019-11-19 22:18:27 +0100
commitb0e7e494b6bc69d3833c0a6c256ff8106a4a24cb (patch)
treeab7509c5ef73fc450498e252c6bcb7f2aaac39b9 /sw
parent03fe7f500f2ccfa5e6a41ad1c9b6b1d7d4403887 (diff)
tdf#128889: don't write "page break after" into w:pPr
This produced invalid OOXML, which Word considers as "page before", and LibreOffice ignores when re-importing. Make sure to write it as *trailing* w:r with w:br, as Word also does when imports ODT with this atribute, and saves as DOCX. Change-Id: Ifc4f45d65d4455ecb5cd62aed1ef6a03375c8aa4 Reviewed-on: https://gerrit.libreoffice.org/83232 Tested-by: Jenkins Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
Diffstat (limited to 'sw')
-rw-r--r--sw/qa/extras/ooxmlexport/data/tdf128889.fodt15
-rw-r--r--sw/qa/extras/ooxmlexport/ooxmlexport14.cxx11
-rw-r--r--sw/source/filter/ww8/attributeoutputbase.hxx3
-rw-r--r--sw/source/filter/ww8/docxattributeoutput.cxx21
-rw-r--r--sw/source/filter/ww8/docxattributeoutput.hxx6
-rw-r--r--sw/source/filter/ww8/docxexport.cxx4
-rw-r--r--sw/source/filter/ww8/rtfattributeoutput.cxx3
-rw-r--r--sw/source/filter/ww8/rtfattributeoutput.hxx3
-rw-r--r--sw/source/filter/ww8/rtfexport.cxx4
-rw-r--r--sw/source/filter/ww8/ww8atr.cxx8
-rw-r--r--sw/source/filter/ww8/ww8attributeoutput.hxx2
11 files changed, 63 insertions, 17 deletions
diff --git a/sw/qa/extras/ooxmlexport/data/tdf128889.fodt b/sw/qa/extras/ooxmlexport/data/tdf128889.fodt
new file mode 100644
index 000000000000..6dc1c4202696
--- /dev/null
+++ b/sw/qa/extras/ooxmlexport/data/tdf128889.fodt
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<office:document xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" office:version="1.2" office:mimetype="application/vnd.oasis.opendocument.text">
+ <office:automatic-styles>
+ <style:style style:name="P1" style:family="paragraph" style:parent-style-name="Standard">
+ <style:paragraph-properties fo:break-after="page"/>
+ </style:style>
+ </office:automatic-styles>
+ <office:body>
+ <office:text>
+ <text:p text:style-name="P1">para1</text:p>
+ <text:p>para2</text:p>
+ </office:text>
+ </office:body>
+</office:document> \ No newline at end of file
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport14.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport14.cxx
index 8996ba0edad7..3bafcab32d6b 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport14.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport14.cxx
@@ -168,6 +168,17 @@ DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testTdf128820, "tdf128820.fodt")
"a:graphic/a:graphicData/wpg:wgp/wps:wsp");
}
+DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testTdf128889, "tdf128889.fodt")
+{
+ xmlDocPtr pXml = parseExport("word/document.xml");
+ CPPUNIT_ASSERT(pXml);
+ // There was an w:r (with w:br) as an invalid child of first paragraph's w:pPr
+ assertXPath(pXml, "/w:document/w:body/w:p[1]/w:pPr/w:r", 0);
+ assertXPath(pXml, "/w:document/w:body/w:p[1]/w:r", 2);
+ // Check that the break is in proper - last - position
+ assertXPath(pXml, "/w:document/w:body/w:p[1]/w:r[2]/w:br", "type", "page");
+}
+
CPPUNIT_PLUGIN_IMPLEMENT();
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/filter/ww8/attributeoutputbase.hxx b/sw/source/filter/ww8/attributeoutputbase.hxx
index 74084f625590..70509ed47806 100644
--- a/sw/source/filter/ww8/attributeoutputbase.hxx
+++ b/sw/source/filter/ww8/attributeoutputbase.hxx
@@ -299,7 +299,8 @@ public:
/// Write a section break
/// msword::ColumnBreak or msword::PageBreak
- virtual void SectionBreak( sal_uInt8 nC, const WW8_SepInfo* pSectionInfo = nullptr ) = 0;
+ /// bBreakAfter: the break must be scheduled for insertion in the end of current paragraph
+ virtual void SectionBreak( sal_uInt8 nC, bool bBreakAfter, const WW8_SepInfo* pSectionInfo = nullptr ) = 0;
// preserve page vertical alignment
virtual void TextVerticalAdjustment( const css::drawing::TextVerticalAdjust) {};
diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx
index 3c2c614bf096..4f18582b0d7f 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -745,6 +745,13 @@ void DocxAttributeOutput::EndParagraph( ww8::WW8TableNodeInfoInner::Pointer_t pT
m_bStartedCharSdt = false;
}
+ if (m_bPageBreakAfter)
+ {
+ // tdf#128889 Trailing page break
+ SectionBreak(msword::PageBreak, false);
+ m_bPageBreakAfter = false;
+ }
+
m_pSerializer->endElementNS( XML_w, XML_p );
// on export sdt blocks are never nested ATM
if( !m_bAnchorLinkedToNode && !m_bStartedParaSdt )
@@ -5981,7 +5988,7 @@ void DocxAttributeOutput::PageBreakBefore( bool bBreak )
FSNS( XML_w, XML_val ), "false" );
}
-void DocxAttributeOutput::SectionBreak( sal_uInt8 nC, const WW8_SepInfo* pSectionInfo )
+void DocxAttributeOutput::SectionBreak( sal_uInt8 nC, bool bBreakAfter, const WW8_SepInfo* pSectionInfo )
{
switch ( nC )
{
@@ -6043,9 +6050,15 @@ void DocxAttributeOutput::SectionBreak( sal_uInt8 nC, const WW8_SepInfo* pSectio
}
else if ( m_bParagraphOpened )
{
- m_pSerializer->startElementNS(XML_w, XML_r);
- m_pSerializer->singleElementNS(XML_w, XML_br, FSNS(XML_w, XML_type), "page");
- m_pSerializer->endElementNS( XML_w, XML_r );
+ if (bBreakAfter)
+ // tdf#128889
+ m_bPageBreakAfter = true;
+ else
+ {
+ m_pSerializer->startElementNS(XML_w, XML_r);
+ m_pSerializer->singleElementNS(XML_w, XML_br, FSNS(XML_w, XML_type), "page");
+ m_pSerializer->endElementNS(XML_w, XML_r);
+ }
}
else
m_bPostponedPageBreak = true;
diff --git a/sw/source/filter/ww8/docxattributeoutput.hxx b/sw/source/filter/ww8/docxattributeoutput.hxx
index 2a8a43a76a79..67561087ceb3 100644
--- a/sw/source/filter/ww8/docxattributeoutput.hxx
+++ b/sw/source/filter/ww8/docxattributeoutput.hxx
@@ -270,7 +270,8 @@ public:
/// Write a section break
/// msword::ColumnBreak or msword::PageBreak
- virtual void SectionBreak( sal_uInt8 nC, const WW8_SepInfo* pSectionInfo = nullptr ) override;
+ /// bBreakAfter: the break must be scheduled for insertion in the end of current paragraph
+ virtual void SectionBreak( sal_uInt8 nC, bool bBreakAfter, const WW8_SepInfo* pSectionInfo = nullptr ) override;
// preserve DOCX page vertical alignment
virtual void TextVerticalAdjustment( const css::drawing::TextVerticalAdjust ) override;
@@ -841,6 +842,9 @@ private:
// beginning of the next paragraph
bool m_bPostponedPageBreak;
+ // This paragraph must end with page break
+ bool m_bPageBreakAfter = false;
+
std::vector<ww8::Frame> m_aFramesOfParagraph;
std::set<const SwFrameFormat*> m_aFloatingTablesOfParagraph;
sal_Int32 m_nTextFrameLevel;
diff --git a/sw/source/filter/ww8/docxexport.cxx b/sw/source/filter/ww8/docxexport.cxx
index c6226fd130ab..3e9c4bc5fd1b 100644
--- a/sw/source/filter/ww8/docxexport.cxx
+++ b/sw/source/filter/ww8/docxexport.cxx
@@ -547,7 +547,7 @@ ErrCode DocxExport::ExportDocument_Impl()
void DocxExport::AppendSection( const SwPageDesc *pPageDesc, const SwSectionFormat* pFormat, sal_uLong nLnNum )
{
- AttrOutput().SectionBreak( msword::PageBreak, m_pSections->CurrentSectionInfo() );
+ AttrOutput().SectionBreak( msword::PageBreak, false, m_pSections->CurrentSectionInfo() );
m_pSections->AppendSection( pPageDesc, pFormat, nLnNum, m_pAttrOutput->IsFirstParagraph() );
}
@@ -622,7 +622,7 @@ void DocxExport::PrepareNewPageDesc( const SfxItemSet* pSet,
{
// tell the attribute output that we are ready to write the section
// break [has to be output inside paragraph properties]
- AttrOutput().SectionBreak( msword::PageBreak, m_pSections->CurrentSectionInfo() );
+ AttrOutput().SectionBreak( msword::PageBreak, false, m_pSections->CurrentSectionInfo() );
const SwSectionFormat* pFormat = GetSectionFormat( rNd );
const sal_uLong nLnNm = GetSectionLineNo( pSet, rNd );
diff --git a/sw/source/filter/ww8/rtfattributeoutput.cxx b/sw/source/filter/ww8/rtfattributeoutput.cxx
index 67622810d0db..6a04e707a706 100644
--- a/sw/source/filter/ww8/rtfattributeoutput.cxx
+++ b/sw/source/filter/ww8/rtfattributeoutput.cxx
@@ -1200,7 +1200,8 @@ void RtfAttributeOutput::PageBreakBefore(bool bBreak)
}
}
-void RtfAttributeOutput::SectionBreak(sal_uInt8 nC, const WW8_SepInfo* pSectionInfo)
+void RtfAttributeOutput::SectionBreak(sal_uInt8 nC, bool /*bBreakAfter*/,
+ const WW8_SepInfo* pSectionInfo)
{
switch (nC)
{
diff --git a/sw/source/filter/ww8/rtfattributeoutput.hxx b/sw/source/filter/ww8/rtfattributeoutput.hxx
index fe0d093ae0a3..4ea8b3845bcd 100644
--- a/sw/source/filter/ww8/rtfattributeoutput.hxx
+++ b/sw/source/filter/ww8/rtfattributeoutput.hxx
@@ -165,7 +165,8 @@ public:
/// Write a section break
/// msword::ColumnBreak or msword::PageBreak
- void SectionBreak(sal_uInt8 nC, const WW8_SepInfo* pSectionInfo = nullptr) override;
+ void SectionBreak(sal_uInt8 nC, bool bBreakAfter,
+ const WW8_SepInfo* pSectionInfo = nullptr) override;
/// Start of the section properties.
void StartSection() override;
diff --git a/sw/source/filter/ww8/rtfexport.cxx b/sw/source/filter/ww8/rtfexport.cxx
index 787833bbac71..f29268032ed0 100644
--- a/sw/source/filter/ww8/rtfexport.cxx
+++ b/sw/source/filter/ww8/rtfexport.cxx
@@ -970,7 +970,7 @@ void RtfExport::PrepareNewPageDesc(const SfxItemSet* pSet, const SwNode& rNd,
// Don't insert a page break, when we're changing page style just because the next page has to be a different one.
if (!m_pAttrOutput->GetPrevPageDesc()
|| m_pAttrOutput->GetPrevPageDesc()->GetFollow() != pNewPgDesc)
- AttrOutput().SectionBreak(msword::PageBreak, m_pSections->CurrentSectionInfo());
+ AttrOutput().SectionBreak(msword::PageBreak, false, m_pSections->CurrentSectionInfo());
}
bool RtfExport::DisallowInheritingOutlineNumbering(const SwFormat& rFormat)
@@ -1026,7 +1026,7 @@ void RtfExport::AppendSection(const SwPageDesc* pPageDesc, const SwSectionFormat
sal_uLong nLnNum)
{
m_pSections->AppendSection(pPageDesc, pFormat, nLnNum);
- AttrOutput().SectionBreak(msword::PageBreak, m_pSections->CurrentSectionInfo());
+ AttrOutput().SectionBreak(msword::PageBreak, false, m_pSections->CurrentSectionInfo());
}
RtfExport::RtfExport(RtfExportFilter* pFilter, SwDoc* pDocument,
diff --git a/sw/source/filter/ww8/ww8atr.cxx b/sw/source/filter/ww8/ww8atr.cxx
index b72a0246bf21..f4525e09b663 100644
--- a/sw/source/filter/ww8/ww8atr.cxx
+++ b/sw/source/filter/ww8/ww8atr.cxx
@@ -2191,7 +2191,7 @@ void AttributeOutputBase::StartTOX( const SwSection& rSect )
SwSection *pParent = rSect.GetParent();
WW8_SepInfo rInfo(&GetExport( ).m_pDoc->GetPageDesc(0),
pParent ? pParent->GetFormat() : nullptr, 0/*nRstLnNum*/);
- GetExport( ).AttrOutput().SectionBreak( msword::PageBreak, &rInfo );
+ GetExport( ).AttrOutput().SectionBreak( msword::PageBreak, false, &rInfo );
}
sStr += "\\c \"" + OUString::number( nCol ) + "\"";
@@ -2499,7 +2499,7 @@ void AttributeOutputBase::EndTOX( const SwSection& rSect,bool bCareEnd )
if ( 0 < nCol )
{
WW8_SepInfo rInfo( &GetExport( ).m_pDoc->GetPageDesc( 0 ), rSect.GetFormat(), 0/*nRstLnNum*/ );
- GetExport( ).AttrOutput().SectionBreak( msword::PageBreak, &rInfo );
+ GetExport( ).AttrOutput().SectionBreak( msword::PageBreak, false, &rInfo );
}
}
}
@@ -3880,13 +3880,13 @@ void AttributeOutputBase::FormatBreak( const SvxFormatBreakItem& rBreak )
}
if ( !bFollowPageDescWritten )
{
- SectionBreak( nC );
+ SectionBreak(nC, !bBefore);
}
}
}
}
-void WW8AttributeOutput::SectionBreak( sal_uInt8 nC, const WW8_SepInfo* /*pSectionInfo*/ )
+void WW8AttributeOutput::SectionBreak( sal_uInt8 nC, bool /*bBreakAfter*/, const WW8_SepInfo* /*pSectionInfo*/ )
{
m_rWW8Export.ReplaceCr( nC );
}
diff --git a/sw/source/filter/ww8/ww8attributeoutput.hxx b/sw/source/filter/ww8/ww8attributeoutput.hxx
index 35d8db7dfa5e..7e3f2a31ff20 100644
--- a/sw/source/filter/ww8/ww8attributeoutput.hxx
+++ b/sw/source/filter/ww8/ww8attributeoutput.hxx
@@ -147,7 +147,7 @@ public:
/// Write a section break
/// msword::ColumnBreak or msword::PageBreak
- virtual void SectionBreak( sal_uInt8 nC, const WW8_SepInfo* pSectionInfo = nullptr ) override;
+ virtual void SectionBreak( sal_uInt8 nC, bool bBreakAfter, const WW8_SepInfo* pSectionInfo = nullptr ) override;
// preserve DOC page vertical alignment
virtual void TextVerticalAdjustment( const css::drawing::TextVerticalAdjust ) override;