sw/qa/extras/ooxmlexport/data/tdf121666_lostPage.docx |binary
 sw/qa/extras/ooxmlexport/ooxmlexport13.cxx            |   10 ++++++++++
 sw/source/filter/ww8/attributeoutputbase.hxx          |    2 +-
 sw/source/filter/ww8/docxattributeoutput.cxx          |   14 +++++++++++++-
 sw/source/filter/ww8/docxattributeoutput.hxx          |    2 +-
 sw/source/filter/ww8/docxexport.cxx                   |    4 ++--
 sw/source/filter/ww8/docxexport.hxx                   |    3 ++-
 sw/source/filter/ww8/rtfattributeoutput.cxx           |    2 +-
 sw/source/filter/ww8/rtfattributeoutput.hxx           |    4 ++--
 sw/source/filter/ww8/rtfexport.cxx                    |    5 +++--
 sw/source/filter/ww8/rtfexport.hxx                    |    4 ++--
 sw/source/filter/ww8/wrtww8.hxx                       |    6 ++++--
 sw/source/filter/ww8/ww8atr.cxx                       |   16 +++++++++++++---
 sw/source/filter/ww8/ww8attributeoutput.hxx           |    2 +-
 14 files changed, 55 insertions(+), 19 deletions(-)

New commits:
commit d58229d61b8bbf9eb0db841826e361940c7b2a4a
Author:     Attila Szűcs <[email protected]>
AuthorDate: Thu Feb 25 13:29:46 2021 +0100
Commit:     László Németh <[email protected]>
CommitDate: Sun Feb 28 12:47:34 2021 +0100

    tdf#121666 DOCX export: fix missing page break
    
    When an empty paragraph has both page break and section
    break, only the section break was exported to DOCX,
    the page break was not, while MSO needs that to show
    all page breaks.
    
    The DOC and RTF exports were not changed by this fix
    (not sure if the problem are present with them or not).
    
    Co-authored-by: Tibor Nagy (NISZ)
    
    Change-Id: I5deac0390666415e36a541c731dda4bc0a2ad6ad
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/111543
    Tested-by: László Németh <[email protected]>
    Reviewed-by: László Németh <[email protected]>

diff --git a/sw/qa/extras/ooxmlexport/data/tdf121666_lostPage.docx 
b/sw/qa/extras/ooxmlexport/data/tdf121666_lostPage.docx
new file mode 100644
index 000000000000..195f574d1c5d
Binary files /dev/null and 
b/sw/qa/extras/ooxmlexport/data/tdf121666_lostPage.docx differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport13.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport13.cxx
index 78c12d93a4ff..5ce06fdacb6c 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport13.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport13.cxx
@@ -86,6 +86,16 @@ DECLARE_OOXMLEXPORT_TEST(testTdf121374_sectionHF2, 
"tdf121374_sectionHF2.doc")
     CPPUNIT_ASSERT( xHeaderText->getString().startsWith("virkamatka-anomus") );
 }
 
+DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testTdf121666_lostPage, 
"tdf121666_lostPage.docx")
+{
+    xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml");
+    assertXPath(pXmlDoc, "/w:document/w:body/w:p[1]/w:r[2]/w:br", "type", 
"page");
+    // The second page break is exported too.
+    // Before this fix, if a node had both section break and page break, then 
only the section break was exported.
+    assertXPath(pXmlDoc, "/w:document/w:body/w:p[2]/w:r[2]/w:br", "type", 
"page");
+    assertXPath(pXmlDoc, "/w:document/w:body/w:p[2]/w:pPr/w:sectPr/w:type", 
"val", "nextPage");
+}
+
 DECLARE_OOXMLEXPORT_TEST(testTdf95848, "tdf95848.docx")
 {
     OUString listId;
diff --git a/sw/source/filter/ww8/attributeoutputbase.hxx 
b/sw/source/filter/ww8/attributeoutputbase.hxx
index 2a54795e05cc..e102b3f7012b 100644
--- a/sw/source/filter/ww8/attributeoutputbase.hxx
+++ b/sw/source/filter/ww8/attributeoutputbase.hxx
@@ -298,7 +298,7 @@ public:
     /// Write a section break
     /// msword::ColumnBreak or msword::PageBreak
     /// 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;
+    virtual void SectionBreak( sal_uInt8 nC, bool bBreakAfter, const 
WW8_SepInfo* pSectionInfo = nullptr, bool bExtraPageBreak = false ) = 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 7a9ddc9e79a5..457366ee2a6c 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -6521,7 +6521,7 @@ void DocxAttributeOutput::PageBreakBefore( bool bBreak )
                 FSNS( XML_w, XML_val ), "false" );
 }
 
-void DocxAttributeOutput::SectionBreak( sal_uInt8 nC, bool bBreakAfter, const 
WW8_SepInfo* pSectionInfo )
+void DocxAttributeOutput::SectionBreak( sal_uInt8 nC, bool bBreakAfter, const 
WW8_SepInfo* pSectionInfo, bool bExtraPageBreak)
 {
     switch ( nC )
     {
@@ -6572,10 +6572,22 @@ void DocxAttributeOutput::SectionBreak( sal_uInt8 nC, 
bool bBreakAfter, const WW
                     m_rExport.SectionProperties( *pSectionInfo );
 
                     m_pSerializer->endElementNS( XML_w, XML_pPr );
+                    if (bExtraPageBreak)
+                    {
+                        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);
+                    }
                     m_pSerializer->endElementNS( XML_w, XML_p );
                 }
                 else
                 {
+                    if (bExtraPageBreak && 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);
+                    }
                     // postpone the output of this; it has to be done inside 
the
                     // paragraph properties, so remember it until then
                     m_pSectionInfo.reset( new WW8_SepInfo( *pSectionInfo ));
diff --git a/sw/source/filter/ww8/docxattributeoutput.hxx 
b/sw/source/filter/ww8/docxattributeoutput.hxx
index dc8da0c0f5aa..423396196153 100644
--- a/sw/source/filter/ww8/docxattributeoutput.hxx
+++ b/sw/source/filter/ww8/docxattributeoutput.hxx
@@ -273,7 +273,7 @@ public:
     /// Write a section break
     /// msword::ColumnBreak or msword::PageBreak
     /// 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;
+    virtual void SectionBreak( sal_uInt8 nC, bool bBreakAfter, const 
WW8_SepInfo* pSectionInfo = nullptr, bool bExtraPageBreak = false ) override;
 
     // preserve DOCX page vertical alignment
     virtual void TextVerticalAdjustment( const 
css::drawing::TextVerticalAdjust ) override;
diff --git a/sw/source/filter/ww8/docxexport.cxx 
b/sw/source/filter/ww8/docxexport.cxx
index 4af84e1335b0..89fac4af6e0a 100644
--- a/sw/source/filter/ww8/docxexport.cxx
+++ b/sw/source/filter/ww8/docxexport.cxx
@@ -619,11 +619,11 @@ 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 bExtraPageBreak )
 {
     // tell the attribute output that we are ready to write the section
     // break [has to be output inside paragraph properties]
-    AttrOutput().SectionBreak( msword::PageBreak, false, 
m_pSections->CurrentSectionInfo() );
+    AttrOutput().SectionBreak( msword::PageBreak, false, 
m_pSections->CurrentSectionInfo(), bExtraPageBreak );
 
     const SwSectionFormat* pFormat = GetSectionFormat( rNd );
     const sal_uLong nLnNm = GetSectionLineNo( pSet, rNd );
diff --git a/sw/source/filter/ww8/docxexport.hxx 
b/sw/source/filter/ww8/docxexport.hxx
index e75d8e3e7613..f599764a45e6 100644
--- a/sw/source/filter/ww8/docxexport.hxx
+++ b/sw/source/filter/ww8/docxexport.hxx
@@ -216,7 +216,8 @@ protected:
     virtual void PrepareNewPageDesc( const SfxItemSet* pSet,
                                      const SwNode& rNd,
                                      const SwFormatPageDesc* pNewPgDescFormat,
-                                     const SwPageDesc* pNewPgDesc ) override;
+                                     const SwPageDesc* pNewPgDesc,
+                                     bool bExtraPageBreak = false) override;
 
 private:
     /// Setup pStyles and write styles.xml
diff --git a/sw/source/filter/ww8/rtfattributeoutput.cxx 
b/sw/source/filter/ww8/rtfattributeoutput.cxx
index 79f88ab22ba0..a319dcd76f47 100644
--- a/sw/source/filter/ww8/rtfattributeoutput.cxx
+++ b/sw/source/filter/ww8/rtfattributeoutput.cxx
@@ -1211,7 +1211,7 @@ void RtfAttributeOutput::PageBreakBefore(bool bBreak)
 }
 
 void RtfAttributeOutput::SectionBreak(sal_uInt8 nC, bool /*bBreakAfter*/,
-                                      const WW8_SepInfo* pSectionInfo)
+                                      const WW8_SepInfo* pSectionInfo, bool 
/*bExtraPageBreak*/)
 {
     switch (nC)
     {
diff --git a/sw/source/filter/ww8/rtfattributeoutput.hxx 
b/sw/source/filter/ww8/rtfattributeoutput.hxx
index a7f95813c2c0..c262749a9638 100644
--- a/sw/source/filter/ww8/rtfattributeoutput.hxx
+++ b/sw/source/filter/ww8/rtfattributeoutput.hxx
@@ -165,8 +165,8 @@ public:
 
     /// Write a section break
     /// msword::ColumnBreak or msword::PageBreak
-    void SectionBreak(sal_uInt8 nC, bool bBreakAfter,
-                      const WW8_SepInfo* pSectionInfo = nullptr) override;
+    void SectionBreak(sal_uInt8 nC, bool bBreakAfter, const WW8_SepInfo* 
pSectionInfo = nullptr,
+                      bool bExtraPageBreak = false) 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 616f28ab0aa7..f3bc81771ad1 100644
--- a/sw/source/filter/ww8/rtfexport.cxx
+++ b/sw/source/filter/ww8/rtfexport.cxx
@@ -953,7 +953,7 @@ ErrCode RtfExport::ExportDocument_Impl()
 
 void RtfExport::PrepareNewPageDesc(const SfxItemSet* pSet, const SwNode& rNd,
                                    const SwFormatPageDesc* pNewPgDescFormat,
-                                   const SwPageDesc* pNewPgDesc)
+                                   const SwPageDesc* pNewPgDesc, bool 
bExtraPageBreak)
 {
     const SwSectionFormat* pFormat = GetSectionFormat(rNd);
     const sal_uLong nLnNm = GetSectionLineNo(pSet, rNd);
@@ -968,7 +968,8 @@ 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, false, 
m_pSections->CurrentSectionInfo());
+        AttrOutput().SectionBreak(msword::PageBreak, false, 
m_pSections->CurrentSectionInfo(),
+                                  bExtraPageBreak);
 }
 
 bool RtfExport::DisallowInheritingOutlineNumbering(const SwFormat& rFormat)
diff --git a/sw/source/filter/ww8/rtfexport.hxx 
b/sw/source/filter/ww8/rtfexport.hxx
index f95e75c5dbfb..83b9a34a9e76 100644
--- a/sw/source/filter/ww8/rtfexport.hxx
+++ b/sw/source/filter/ww8/rtfexport.hxx
@@ -123,8 +123,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 bExtraPageBreak = false) override;
 
     /// Return value indicates if an inherited outline numbering is suppressed.
     bool DisallowInheritingOutlineNumbering(const SwFormat& rFormat) override;
diff --git a/sw/source/filter/ww8/wrtww8.hxx b/sw/source/filter/ww8/wrtww8.hxx
index fdee9d097f31..9778044a8a35 100644
--- a/sw/source/filter/ww8/wrtww8.hxx
+++ b/sw/source/filter/ww8/wrtww8.hxx
@@ -843,7 +843,8 @@ protected:
     virtual void PrepareNewPageDesc( const SfxItemSet* pSet,
                                      const SwNode& rNd,
                                      const SwFormatPageDesc* pNewPgDescFormat,
-                                     const SwPageDesc* pNewPgDesc ) = 0;
+                                     const SwPageDesc* pNewPgDesc,
+                                     bool bExtraPageBreak = false ) = 0;
 
     /// Return value indicates if an inherited outline numbering is suppressed.
     virtual bool DisallowInheritingOutlineNumbering(const SwFormat &rFormat) = 
0;
@@ -1106,7 +1107,8 @@ public:
     virtual void PrepareNewPageDesc( const SfxItemSet* pSet,
                                      const SwNode& rNd,
                                      const SwFormatPageDesc* pNewPgDescFormat,
-                                     const SwPageDesc* pNewPgDesc ) override;
+                                     const SwPageDesc* pNewPgDesc,
+                                     bool bExtraPageBreak = false ) 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 7d9a00391858..f8c0ee826c60 100644
--- a/sw/source/filter/ww8/ww8atr.cxx
+++ b/sw/source/filter/ww8/ww8atr.cxx
@@ -470,6 +470,7 @@ void MSWordExportBase::OutputSectionBreaks( const 
SfxItemSet *pSet, const SwNode
     bool bNewPageDesc = false;
     const SfxPoolItem* pItem=nullptr;
     const SwFormatPageDesc *pPgDesc=nullptr;
+    bool bExtraPageBreakBeforeSectionBreak = false;
 
     //Output a sectionbreak if there's a new pagedescriptor. Otherwise output a
     //pagebreak if there is a pagebreak here, unless the new page (follow
@@ -507,6 +508,14 @@ void MSWordExportBase::OutputSectionBreaks( const 
SfxItemSet *pSet, const SwNode
             bNewPageDesc = true;
             pPgDesc = static_cast<const SwFormatPageDesc*>(pItem);
             m_pCurrentPageDesc = pPgDesc->GetPageDesc();
+
+            // tdf#121666: nodes that have pagebreak + sectionbreak may need 
to export both breaks
+            // tested / implemented with docx format only.
+            // If other formats (rtf /doc) need similar fix, then that may can 
be done similar way.
+            if (SfxItemState::SET == pSet->GetItemState(RES_BREAK, false, 
&pItem))
+            {
+                bExtraPageBreakBeforeSectionBreak = true;
+            }
         }
         else if ( SfxItemState::SET == pSet->GetItemState( RES_BREAK, false, 
&pItem ) )
         {
@@ -595,7 +604,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, 
bExtraPageBreakBeforeSectionBreak );
     }
     m_bBreakBefore = false;
 }
@@ -647,7 +656,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 /*bExtraPageBreak*/ )
 {
     // The PageDescs will only be inserted in WW8Writer::pSepx with the 
corresponding
     // position by the occurrences of PageDesc attributes. The construction and
@@ -3931,7 +3941,7 @@ void AttributeOutputBase::FormatBreak( const 
SvxFormatBreakItem& rBreak )
     }
 }
 
-void WW8AttributeOutput::SectionBreak( sal_uInt8 nC, bool /*bBreakAfter*/, 
const WW8_SepInfo* /*pSectionInfo*/ )
+void WW8AttributeOutput::SectionBreak( sal_uInt8 nC, bool /*bBreakAfter*/, 
const WW8_SepInfo* /*pSectionInfo*/, bool /*bExtraPageBreak*/ )
 {
     m_rWW8Export.ReplaceCr( nC );
 }
diff --git a/sw/source/filter/ww8/ww8attributeoutput.hxx 
b/sw/source/filter/ww8/ww8attributeoutput.hxx
index ac4e931ecf0d..7bd1dd1d1e00 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, bool bBreakAfter, const 
WW8_SepInfo* pSectionInfo = nullptr ) override;
+    virtual void SectionBreak( sal_uInt8 nC, bool bBreakAfter, const 
WW8_SepInfo* pSectionInfo = nullptr, bool bExtraPageBreak = false ) override;
 
     // preserve DOC page vertical alignment
     virtual void TextVerticalAdjustment( const 
css::drawing::TextVerticalAdjust ) override;
_______________________________________________
Libreoffice-commits mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to