diff options
author | Serge Krot <Serge.Krot@cib.de> | 2018-06-27 11:18:41 +0200 |
---|---|---|
committer | Thorsten Behrens <Thorsten.Behrens@CIB.de> | 2018-09-19 10:50:05 +0200 |
commit | fa8b2c533265a6d74e16ffae55673d6aa0fbf6a5 (patch) | |
tree | 950f239d1375f48a17a8bdfc308e70e8928b7623 | |
parent | 0bc059f2a893d812e29d6a72d4f988428b5ea346 (diff) |
tdf#118393: FILESAVE: DOCX Export loses header/footer
Change-Id: If47a2e4953e4b98f41c9115779522a755eea8192
Reviewed-on: https://gerrit.libreoffice.org/56522
Tested-by: Jenkins
Reviewed-by: Thorsten Behrens <Thorsten.Behrens@CIB.de>
-rwxr-xr-x | sw/qa/extras/odfexport/data/tdf118393.odt | bin | 0 -> 14208 bytes | |||
-rw-r--r-- | sw/qa/extras/odfexport/odfexport.cxx | 47 | ||||
-rw-r--r-- | sw/qa/extras/ooxmlexport/data/tdf118393.odt | bin | 0 -> 14208 bytes | |||
-rw-r--r-- | sw/qa/extras/ooxmlexport/ooxmlexport.cxx | 51 | ||||
-rw-r--r-- | sw/source/filter/ww8/wrtw8sty.cxx | 7 | ||||
-rw-r--r-- | sw/source/filter/ww8/wrtww8.cxx | 1 | ||||
-rw-r--r-- | sw/source/filter/ww8/wrtww8.hxx | 1 | ||||
-rw-r--r-- | sw/source/filter/ww8/ww8atr.cxx | 29 |
8 files changed, 135 insertions, 1 deletions
diff --git a/sw/qa/extras/odfexport/data/tdf118393.odt b/sw/qa/extras/odfexport/data/tdf118393.odt Binary files differnew file mode 100755 index 000000000000..ff8d5400950b --- /dev/null +++ b/sw/qa/extras/odfexport/data/tdf118393.odt diff --git a/sw/qa/extras/odfexport/odfexport.cxx b/sw/qa/extras/odfexport/odfexport.cxx index 6bc124027511..4727f2266750 100644 --- a/sw/qa/extras/odfexport/odfexport.cxx +++ b/sw/qa/extras/odfexport/odfexport.cxx @@ -1399,6 +1399,53 @@ DECLARE_ODFEXPORT_TEST(testFdo86963, "fdo86963.odt") CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xDrawPage->getCount()); } +// Check for correct header/footer with special first page with TOC inside: +// - DECLARE_ODFEXPORT_TEST(testTdf118393, "tdf118393.odt") +// - DECLARE_OOXMLEXPORT_TEST(testTdf118393, "tdf118393.odt") +DECLARE_ODFEXPORT_TEST(testTdf118393, "tdf118393.odt") +{ + CPPUNIT_ASSERT_EQUAL( 7, getPages() ); + + // First page has no header/footer + { + xmlDocPtr pXmlDoc = parseLayoutDump(); + + // check first page + xmlXPathObjectPtr pXmlPage1Header = getXPathNode(pXmlDoc, "/root/page[1]/header"); + CPPUNIT_ASSERT_EQUAL(0, xmlXPathNodeSetGetLength(pXmlPage1Header->nodesetval)); + + xmlXPathObjectPtr pXmlPage1Footer = getXPathNode(pXmlDoc, "/root/page[1]/footer"); + CPPUNIT_ASSERT_EQUAL(0, xmlXPathNodeSetGetLength(pXmlPage1Footer->nodesetval)); + + // check second page in the same way + xmlXPathObjectPtr pXmlPage2Header = getXPathNode(pXmlDoc, "/root/page[2]/header"); + CPPUNIT_ASSERT_EQUAL(1, xmlXPathNodeSetGetLength(pXmlPage2Header->nodesetval)); + + xmlXPathObjectPtr pXmlPage2Footer = getXPathNode(pXmlDoc, "/root/page[2]/footer"); + CPPUNIT_ASSERT_EQUAL(1, xmlXPathNodeSetGetLength(pXmlPage2Footer->nodesetval)); + } + + // All other pages should have header/footer + + CPPUNIT_ASSERT_EQUAL(OUString("Seite * von *"), parseDump("/root/page[2]/header/txt/text()")); + CPPUNIT_ASSERT_EQUAL(OUString("Seite * von *"), parseDump("/root/page[2]/footer/txt/text()")); + + CPPUNIT_ASSERT_EQUAL(OUString("Seite * von *"), parseDump("/root/page[3]/header/txt/text()")); + CPPUNIT_ASSERT_EQUAL(OUString("Seite * von *"), parseDump("/root/page[3]/footer/txt/text()")); + + CPPUNIT_ASSERT_EQUAL(OUString("Seite * von *"), parseDump("/root/page[4]/header/txt/text()")); + CPPUNIT_ASSERT_EQUAL(OUString("Seite * von *"), parseDump("/root/page[4]/footer/txt/text()")); + + CPPUNIT_ASSERT_EQUAL(OUString("Seite * von *"), parseDump("/root/page[5]/header/txt/text()")); + CPPUNIT_ASSERT_EQUAL(OUString("Seite * von *"), parseDump("/root/page[5]/footer/txt/text()")); + + CPPUNIT_ASSERT_EQUAL(OUString("Seite * von *"), parseDump("/root/page[6]/header/txt/text()")); + CPPUNIT_ASSERT_EQUAL(OUString("Seite * von *"), parseDump("/root/page[6]/footer/txt/text()")); + + CPPUNIT_ASSERT_EQUAL(OUString("Seite * von *"), parseDump("/root/page[7]/header/txt/text()")); + CPPUNIT_ASSERT_EQUAL(OUString("Seite * von *"), parseDump("/root/page[7]/footer/txt/text()")); +} + DECLARE_ODFEXPORT_TEST(testGerrit13858, "gerrit13858.odt") { // Just make sure the output is valid. diff --git a/sw/qa/extras/ooxmlexport/data/tdf118393.odt b/sw/qa/extras/ooxmlexport/data/tdf118393.odt Binary files differnew file mode 100644 index 000000000000..ff8d5400950b --- /dev/null +++ b/sw/qa/extras/ooxmlexport/data/tdf118393.odt diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx index a1e2a5194904..c5d6b88db4b2 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx @@ -90,6 +90,53 @@ DECLARE_OOXMLEXPORT_TEST(testFooterBodyDistance, "footer-body-distance.docx") assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:r/w:br", 1); } +// Check for correct header/footer with special first page with TOC inside: +// - DECLARE_ODFEXPORT_TEST(testTdf118393, "tdf118393.odt") +// - DECLARE_OOXMLEXPORT_TEST(testTdf118393, "tdf118393.odt") +DECLARE_OOXMLEXPORT_TEST(testTdf118393, "tdf118393.odt") +{ + CPPUNIT_ASSERT_EQUAL( 7, getPages() ); + + // First page has no header/footer + { + xmlDocPtr pXmlDoc = parseLayoutDump(); + + // check first page + xmlXPathObjectPtr pXmlPage1Header = getXPathNode(pXmlDoc, "/root/page[1]/header"); + CPPUNIT_ASSERT_EQUAL(0, xmlXPathNodeSetGetLength(pXmlPage1Header->nodesetval)); + + xmlXPathObjectPtr pXmlPage1Footer = getXPathNode(pXmlDoc, "/root/page[1]/footer"); + CPPUNIT_ASSERT_EQUAL(0, xmlXPathNodeSetGetLength(pXmlPage1Footer->nodesetval)); + + // check second page in the same way + xmlXPathObjectPtr pXmlPage2Header = getXPathNode(pXmlDoc, "/root/page[2]/header"); + CPPUNIT_ASSERT_EQUAL(1, xmlXPathNodeSetGetLength(pXmlPage2Header->nodesetval)); + + xmlXPathObjectPtr pXmlPage2Footer = getXPathNode(pXmlDoc, "/root/page[2]/footer"); + CPPUNIT_ASSERT_EQUAL(1, xmlXPathNodeSetGetLength(pXmlPage2Footer->nodesetval)); + } + + // All other pages should have header/footer + + CPPUNIT_ASSERT_EQUAL(OUString("Seite * von *"), parseDump("/root/page[2]/header/txt/text()")); + CPPUNIT_ASSERT_EQUAL(OUString("Seite * von *"), parseDump("/root/page[2]/footer/txt/text()")); + + CPPUNIT_ASSERT_EQUAL(OUString("Seite * von *"), parseDump("/root/page[3]/header/txt/text()")); + CPPUNIT_ASSERT_EQUAL(OUString("Seite * von *"), parseDump("/root/page[3]/footer/txt/text()")); + + CPPUNIT_ASSERT_EQUAL(OUString("Seite * von *"), parseDump("/root/page[4]/header/txt/text()")); + CPPUNIT_ASSERT_EQUAL(OUString("Seite * von *"), parseDump("/root/page[4]/footer/txt/text()")); + + CPPUNIT_ASSERT_EQUAL(OUString("Seite * von *"), parseDump("/root/page[5]/header/txt/text()")); + CPPUNIT_ASSERT_EQUAL(OUString("Seite * von *"), parseDump("/root/page[5]/footer/txt/text()")); + + CPPUNIT_ASSERT_EQUAL(OUString("Seite * von *"), parseDump("/root/page[6]/header/txt/text()")); + CPPUNIT_ASSERT_EQUAL(OUString("Seite * von *"), parseDump("/root/page[6]/footer/txt/text()")); + + CPPUNIT_ASSERT_EQUAL(OUString("Seite * von *"), parseDump("/root/page[7]/header/txt/text()")); + CPPUNIT_ASSERT_EQUAL(OUString("Seite * von *"), parseDump("/root/page[7]/footer/txt/text()")); +} + DECLARE_OOXMLEXPORT_TEST(testfdo81031, "fdo81031.docx") { // vml image was not rendered @@ -110,6 +157,8 @@ DECLARE_OOXMLEXPORT_TEST(testPlausableBorder, "plausable-border.docx") if (xmlDocPtr pXmlDoc = parseExport()) // Page break was exported as section break, this was 0 assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:r/w:br", 1); + + CPPUNIT_ASSERT_EQUAL( 2, getPages() ); } DECLARE_OOXMLEXPORT_TEST(testUnwantedSectionBreak, "unwanted-section-break.docx") @@ -157,6 +206,8 @@ DECLARE_OOXMLEXPORT_TEST(testFirstHeaderFooter, "first-header-footer.docx") // Test import and export of a section's headerf/footerf properties. // (copied from a ww8export test, with doc converted to docx using Word) + CPPUNIT_ASSERT_EQUAL( 6, getPages() ); + // The document has 6 pages. Note that we don't test if 4 or just 2 page // styles are created, the point is that layout should be correct. CPPUNIT_ASSERT_EQUAL(OUString("First page header"), parseDump("/root/page[1]/header/txt/text()")); diff --git a/sw/source/filter/ww8/wrtw8sty.cxx b/sw/source/filter/ww8/wrtw8sty.cxx index 5d9e55758b93..c92a5f9b1957 100644 --- a/sw/source/filter/ww8/wrtw8sty.cxx +++ b/sw/source/filter/ww8/wrtw8sty.cxx @@ -976,7 +976,7 @@ MSWordSections::MSWordSections( MSWordExportBase& rExport ) sal_uLong nRstLnNum = pSet ? pSet->Get( RES_LINENUMBER ).GetStartValue() : 0; const SwTableNode* pTableNd = rExport.m_pCurPam->GetNode().FindTableNode(); - const SwSectionNode* pSectNd; + const SwSectionNode* pSectNd = nullptr; if ( pTableNd ) { pSet = &pTableNd->GetTable().GetFrameFormat()->GetAttrSet(); @@ -1000,6 +1000,11 @@ MSWordSections::MSWordSections( MSWordExportBase& rExport ) pFormat = pSectNd->GetSection().GetFormat(); } + // tdf#118393: FILESAVE: DOCX Export loses header/footer + rExport.m_bFirstTOCNodeWithSection = pSectNd && + ( TOX_HEADER_SECTION == pSectNd->GetSection().GetType() || + TOX_CONTENT_SECTION == pSectNd->GetSection().GetType() ); + // Try to get page descriptor of the first node if ( pSet && SfxItemState::SET == pSet->GetItemState( RES_PAGEDESC, true, &pI ) && diff --git a/sw/source/filter/ww8/wrtww8.cxx b/sw/source/filter/ww8/wrtww8.cxx index 67d1fdf2eeed..b14a76d0c957 100644 --- a/sw/source/filter/ww8/wrtww8.cxx +++ b/sw/source/filter/ww8/wrtww8.cxx @@ -3585,6 +3585,7 @@ MSWordExportBase::MSWordExportBase( SwDoc *pDocument, SwPaM *pCurrentPam, SwPaM , m_nOrigRedlineFlags(RedlineFlags::NONE) , m_pCurrentPageDesc(nullptr) , m_bPrevTextNodeIsEmpty(false) + , m_bFirstTOCNodeWithSection(false) , m_pPapPlc(nullptr) , m_pChpPlc(nullptr) , m_pChpIter(nullptr) diff --git a/sw/source/filter/ww8/wrtww8.hxx b/sw/source/filter/ww8/wrtww8.hxx index 778446e79c36..da01f2a01069 100644 --- a/sw/source/filter/ww8/wrtww8.hxx +++ b/sw/source/filter/ww8/wrtww8.hxx @@ -485,6 +485,7 @@ public: ww8::Frames m_aFrames; // The floating frames in this document const SwPageDesc *m_pCurrentPageDesc; bool m_bPrevTextNodeIsEmpty; + bool m_bFirstTOCNodeWithSection; WW8_WrPlcPn* m_pPapPlc; WW8_WrPlcPn* m_pChpPlc; MSWordAttrIter* m_pChpIter; diff --git a/sw/source/filter/ww8/ww8atr.cxx b/sw/source/filter/ww8/ww8atr.cxx index e5c423bd86ed..8da786e78ccc 100644 --- a/sw/source/filter/ww8/ww8atr.cxx +++ b/sw/source/filter/ww8/ww8atr.cxx @@ -444,6 +444,35 @@ void MSWordExportBase::OutputSectionBreaks( const SfxItemSet *pSet, const SwNode */ if ( isCellOpen && ( m_pCurrentPageDesc->GetName() != pPageDesc->GetName() ) ) pSet = nullptr; + + // tdf#118393: FILESAVE: DOCX Export loses header/footer + { + bool bPlausableSingleWordSection = sw::util::IsPlausableSingleWordSection(m_pCurrentPageDesc->GetFirstMaster(), pPageDesc->GetMaster()); + + { + const SwFrameFormat& rTitleFormat = m_pCurrentPageDesc->GetFirstMaster(); + const SwFrameFormat& rFollowFormat = pPageDesc->GetMaster(); + + auto pHeaderFormat1 = rTitleFormat.GetHeader().GetHeaderFormat(); + auto pHeaderFormat2 = rFollowFormat.GetHeader().GetHeaderFormat(); + + if (pHeaderFormat1 != pHeaderFormat2) + bPlausableSingleWordSection = false; + + auto pFooterFormat1 = rTitleFormat.GetFooter().GetFooterFormat(); + auto pFooterFormat2 = rFollowFormat.GetFooter().GetFooterFormat(); + + if (pFooterFormat1 != pFooterFormat2) + bPlausableSingleWordSection = false; + } + + if ( !bPlausableSingleWordSection && m_bFirstTOCNodeWithSection ) + { + bBreakSet = false; + bNewPageDesc = true; + m_pCurrentPageDesc = pPageDesc; + } + } } else if (!sw::util::IsPlausableSingleWordSection(m_pCurrentPageDesc->GetFirstMaster(), pPageDesc->GetMaster())) { |