[Libreoffice-commits] core.git: Branch 'distro/collabora/cp-6.2' - sw/qa sw/source

Miklos Vajna (via logerrit) logerrit at kemper.freedesktop.org
Fri Feb 7 11:22:59 UTC 2020


 sw/qa/extras/ooxmlexport/ooxmlexport13.cxx |    7 ++
 sw/source/filter/ww8/wrtw8sty.cxx          |   80 +++++++++++++++++++++++++++++
 2 files changed, 86 insertions(+), 1 deletion(-)

New commits:
commit 5c6c74310c1df73567ea736f633bdcce116bef90
Author:     Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Thu Feb 6 14:47:08 2020 +0100
Commit:     Miklos Vajna <vmiklos at collabora.com>
CommitDate: Fri Feb 7 12:22:30 2020 +0100

    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/qa/extras/ooxmlexport/ooxmlexport14.cxx
            sw/source/filter/ww8/wrtw8sty.cxx
    
    Change-Id: Ic2304a74919d18da3ba9cb4afe301e0247a50dc2
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/88167
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice at gmail.com>
    Reviewed-by: Miklos Vajna <vmiklos at collabora.com>

diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport13.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport13.cxx
index dcb0f4703cb6..769815485b48 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport13.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport13.cxx
@@ -367,7 +367,7 @@ DECLARE_OOXMLIMPORT_TEST(testTdf128207, "tdf128207.docx")
     CPPUNIT_ASSERT_EQUAL(sal_Int32(12), getProperty<sal_Int32>(getShape(1), "HoriOrientPosition"));
 }
 
-DECLARE_OOXMLIMPORT_TEST(testContSectBreakHeaderFooter, "cont-sect-break-header-footer.docx")
+DECLARE_OOXMLEXPORT_TEST(testContSectBreakHeaderFooter, "cont-sect-break-header-footer.docx")
 {
     // Load a document with a continuous section break on page 2.
     CPPUNIT_ASSERT_EQUAL(OUString("First page header, section 1"),
@@ -391,6 +391,11 @@ DECLARE_OOXMLIMPORT_TEST(testContSectBreakHeaderFooter, "cont-sect-break-header-
     // the own footer text.
     CPPUNIT_ASSERT_EQUAL(OUString("Footer, section 3"),
                          parseDump("/root/page[3]/footer/txt/text()"));
+
+    // Without the export fix in place, the import-export-import test would have failed with:
+    // - Expected: Header, section 2
+    // - Actual  : First page header, section 2
+    // i.e. both the header and the footer on page 3 was wrong.
 }
 
 CPPUNIT_TEST_FIXTURE(SwModelTestBase, testZeroLineSpacing)
diff --git a/sw/source/filter/ww8/wrtw8sty.cxx b/sw/source/filter/ww8/wrtw8sty.cxx
index 9aa5621ab3fc..4c2901c0c0c0 100644
--- a/sw/source/filter/ww8/wrtw8sty.cxx
+++ b/sw/source/filter/ww8/wrtw8sty.cxx
@@ -34,6 +34,7 @@
 #include <editeng/frmdiritem.hxx>
 #include <editeng/lrspitem.hxx>
 #include <editeng/ulspitem.hxx>
+#include <editeng/fhgtitem.hxx>
 #include <doc.hxx>
 #include "wrtww8.hxx"
 #include <docary.hxx>
@@ -59,6 +60,7 @@
 #include <swtable.hxx>
 #include <msfilter.hxx>
 #include <swmodule.hxx>
+#include <charatr.hxx>
 
 #include "sprmids.hxx"
 
@@ -1505,6 +1507,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<SwSectionFormat*>(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;
@@ -1756,6 +1828,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 );


More information about the Libreoffice-commits mailing list