diff options
author | Miklos Vajna <vmiklos@collabora.com> | 2020-05-11 21:08:35 +0200 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.com> | 2020-05-12 09:02:43 +0200 |
commit | 51534ac2b9747975945acb6a1e1ba5cc6d73f5c2 (patch) | |
tree | b39fb0577bac479321027ae08640c11f3d2d0bc2 | |
parent | 23d9966751566028c50ca95ca203d20f36c64f30 (diff) |
tdf#127778 DOCX import: fix unexpected heading on non-first page ...
... when the first page has a heading
Regression from commit 17e51f427b3f0cec74ac8e0a1b3f51189006ae6f (DOCX
import: first page header should always set default headers as well,
2014-11-21), the problem is around how to split a first + follow page
style on import, and then do the opposite on export.
This is described using a single section in OOXML, but Writer has 2 page
styles for this (unlike in case of the DOC filter). This means the
header margin has to be taken from one of these page styles. The above
commit tweaked the import, so the follow page style has the wanted
header margin, but this leads to incorrect layout.
Fix the problem by tweaking the export instead: it has random access to
the doc model, so it can take the header margin from the first page
style if needed, and then the import side can be reverted, leading to
correct layout.
Also remove some leftover debug code in test/, which was added in commit
5352d45dd4a04f8f02cf7f6ad4169126d3b3586a (convert AnimationImport to
fast-parser APIs, 2020-02-18).
Change-Id: I4bbf7271f3a437e8432399bd1e32e9d24190a501
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/94013
Tested-by: Jenkins
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
-rw-r--r-- | sw/qa/extras/ooxmlexport/ooxmlexport6.cxx | 4 | ||||
-rw-r--r-- | sw/qa/extras/ooxmlimport/data/tdf127778.docx | bin | 0 -> 23220 bytes | |||
-rw-r--r-- | sw/qa/extras/ooxmlimport/ooxmlimport2.cxx | 12 | ||||
-rw-r--r-- | sw/source/filter/ww8/docxattributeoutput.cxx | 11 | ||||
-rw-r--r-- | sw/source/filter/ww8/wrtw8sty.cxx | 12 | ||||
-rw-r--r-- | sw/source/filter/ww8/wrtww8.hxx | 1 | ||||
-rw-r--r-- | test/source/xmltesttools.cxx | 2 | ||||
-rw-r--r-- | writerfilter/source/dmapper/PropertyMap.cxx | 9 |
8 files changed, 38 insertions, 13 deletions
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport6.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport6.cxx index 4bfa75ed28eb..7e9e9dcae0c6 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport6.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport6.cxx @@ -500,7 +500,7 @@ DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testVMLData, "TestVMLData.docx") { // The problem was exporter was exporting vml data for shape in w:rPr element. // vml data should not come under w:rPr element. - xmlDocUniquePtr pXmlDoc = parseExport("word/header2.xml"); + xmlDocUniquePtr pXmlDoc = parseExport("word/header1.xml"); CPPUNIT_ASSERT(getXPath(pXmlDoc, "/w:hdr/w:p/w:r/mc:AlternateContent/mc:Fallback/w:pict/v:shape", "stroked").match("f")); } @@ -508,7 +508,7 @@ DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testImageData, "image_data.docx") { // The problem was exporter was exporting v:imagedata data for shape in w:pict as v:fill w element. - xmlDocUniquePtr pXmlDoc = parseExport("word/header2.xml"); + xmlDocUniquePtr pXmlDoc = parseExport("word/header1.xml"); CPPUNIT_ASSERT(getXPath(pXmlDoc, "/w:hdr/w:p/w:r/mc:AlternateContent/mc:Fallback/w:pict/v:shape/v:imagedata", "detectmouseclick").match("t")); } diff --git a/sw/qa/extras/ooxmlimport/data/tdf127778.docx b/sw/qa/extras/ooxmlimport/data/tdf127778.docx Binary files differnew file mode 100644 index 000000000000..a706d575763f --- /dev/null +++ b/sw/qa/extras/ooxmlimport/data/tdf127778.docx diff --git a/sw/qa/extras/ooxmlimport/ooxmlimport2.cxx b/sw/qa/extras/ooxmlimport/ooxmlimport2.cxx index b8c2202922d7..6047a97f7c8c 100644 --- a/sw/qa/extras/ooxmlimport/ooxmlimport2.cxx +++ b/sw/qa/extras/ooxmlimport/ooxmlimport2.cxx @@ -280,6 +280,18 @@ DECLARE_OOXMLIMPORT_TEST(testTdf43017, "tdf43017.docx") getProperty<sal_Int32>(xText, "CharColor")); } +CPPUNIT_TEST_FIXTURE(Test, testTdf127778) +{ + load(mpTestDocumentPath, "tdf127778.docx"); + xmlDocUniquePtr pLayout = parseLayoutDump(); + // Without the accompanying fix in place, this test would have failed with: + // equality assertion failed + // - Expected: 0 + // - Actual : 1 + // i.e. the 2nd page had an unexpected header. + assertXPath(pLayout, "//page[2]/header", 0); +} + // related tdf#43017 DECLARE_OOXMLIMPORT_TEST(testTdf124754, "tdf124754.docx") { diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx index 7c576e26538e..a5aa741447af 100644 --- a/sw/source/filter/ww8/docxattributeoutput.cxx +++ b/sw/source/filter/ww8/docxattributeoutput.cxx @@ -8380,6 +8380,17 @@ void DocxAttributeOutput::FormatULSpace( const SvxULSpaceItem& rULSpace ) sal_Int32 nHeader = 0; if ( aDistances.HasHeader() ) nHeader = sal_Int32( aDistances.dyaHdrTop ); + else if (m_rExport.m_pFirstPageFormat) + { + HdFtDistanceGlue aFirstPageDistances(m_rExport.m_pFirstPageFormat->GetAttrSet()); + if (aFirstPageDistances.HasHeader()) + { + // The follow page style has no header, but the first page style has. In Word terms, + // this means that the header margin of "the" section is coming from the first page + // style. + nHeader = sal_Int32(aFirstPageDistances.dyaHdrTop); + } + } // Page top m_pageMargins.nTop = aDistances.dyaTop; diff --git a/sw/source/filter/ww8/wrtw8sty.cxx b/sw/source/filter/ww8/wrtw8sty.cxx index ddf0347ab3b9..653078824a6c 100644 --- a/sw/source/filter/ww8/wrtw8sty.cxx +++ b/sw/source/filter/ww8/wrtw8sty.cxx @@ -1783,7 +1783,19 @@ void MSWordExportBase::SectionProperties( const WW8_SepInfo& rSepInfo, WW8_PdAtt m_pISet = &pPdFormat->GetAttrSet(); if (!bOutputStyleItemSet) + { + if (titlePage) + { + m_pFirstPageFormat = pPdFirstPgFormat; + } + AttrOutput().OutputStyleItemSet( pPdFormat->GetAttrSet(), false ); + + if (titlePage) + { + m_pFirstPageFormat = nullptr; + } + } AttrOutput().SectionPageBorders( pPdFormat, pPdFirstPgFormat ); m_pISet = pOldI; diff --git a/sw/source/filter/ww8/wrtww8.hxx b/sw/source/filter/ww8/wrtww8.hxx index 00da29d78ce7..99063ef12a20 100644 --- a/sw/source/filter/ww8/wrtww8.hxx +++ b/sw/source/filter/ww8/wrtww8.hxx @@ -450,6 +450,7 @@ public: OUString m_aMainStg; std::vector<const SwTOXType*> m_aTOXArr; const SfxItemSet* m_pISet; // for double attributes + const SwFrameFormat* m_pFirstPageFormat = nullptr; WW8_WrPct* m_pPiece; // Pointer to Piece-Table std::unique_ptr<SwNumRuleTable> m_pUsedNumTable; // all used NumRules /// overriding numdef index -> (existing numdef index, abstractnumdef index) diff --git a/test/source/xmltesttools.cxx b/test/source/xmltesttools.cxx index fc739ab479a8..27833af1e90d 100644 --- a/test/source/xmltesttools.cxx +++ b/test/source/xmltesttools.cxx @@ -184,8 +184,6 @@ void XmlTestTools::assertXPath(const xmlDocUniquePtr& pXmlDoc, const OString& rX { xmlXPathObjectPtr pXmlObj = getXPathNode(pXmlDoc, rXPath); xmlNodeSetPtr pXmlNodes = pXmlObj->nodesetval; - if (nNumberOfNodes != xmlXPathNodeSetGetLength(pXmlNodes)) - CPPUNIT_ASSERT_EQUAL(1, 2); CPPUNIT_ASSERT_EQUAL_MESSAGE(OString(OStringLiteral("In <") + pXmlDoc->name + ">, XPath '" + rXPath + "' number of nodes is incorrect").getStr(), nNumberOfNodes, xmlXPathNodeSetGetLength(pXmlNodes)); xmlXPathFreeObject(pXmlObj); diff --git a/writerfilter/source/dmapper/PropertyMap.cxx b/writerfilter/source/dmapper/PropertyMap.cxx index 44127d0d7f86..9d268919f41b 100644 --- a/writerfilter/source/dmapper/PropertyMap.cxx +++ b/writerfilter/source/dmapper/PropertyMap.cxx @@ -948,15 +948,6 @@ void SectionPropertyMap::CopyLastHeaderFooter( bool bFirstPage, DomainMapper_Imp void SectionPropertyMap::PrepareHeaderFooterProperties( bool bFirstPage ) { bool bCopyFirstToFollow = bFirstPage && m_bTitlePage && m_aFollowPageStyle.is(); - if (bCopyFirstToFollow) - { - // This is a first page and has a follow style, then enable the - // header/footer there as well to be consistent. - if (HasHeader(/*bFirstPage=*/true)) - m_aFollowPageStyle->setPropertyValue("HeaderIsOn", uno::makeAny(true)); - if (HasFooter(/*bFirstPage=*/true)) - m_aFollowPageStyle->setPropertyValue("FooterIsOn", uno::makeAny(true)); - } sal_Int32 nTopMargin = m_nTopMargin; sal_Int32 nHeaderTop = m_nHeaderTop; |