summaryrefslogtreecommitdiff
path: root/sw
diff options
context:
space:
mode:
authorJustin Luth <jluth@mail.com>2024-07-10 14:57:44 -0400
committerAndras Timar <andras.timar@collabora.com>2024-08-23 11:17:10 +0200
commit5cd2dba6c613d0b4799a0c2ffe0cd72bc7cce3c2 (patch)
tree145481f494b0309767b1e9c9ed60eff9a61dad82 /sw
parent43c46151a74264ee2424f766c1c809760b6a4871 (diff)
tdf#160976 rtfexport: export first header as well as default header
LO has never handled exporting "different first header" ever since it was introduced in LO 4.0-ish. In 24.2, quikee change the RTF import to default to putting headers into "different first header" instead of "First Page Style" with commit 4b0fa253a4540f5461397815d290586f9ddabe61, so this existing problem has become more pronounced. Unhandled still is any attempt to handle different even/odd pages. This patch also reduces the number of \titlepg duplicates. make CppunitTest_sw_rtfexport8 \ CPPUNIT_TEST_NAME=testTdf160976_headerFooter make CppunitTest_sw_rtfexport8 \ CPPUNIT_TEST_NAME=testTdf160976_headerFooter2 make CppunitTest_sw_rtfexport8 \ CPPUNIT_TEST_NAME=testTdf160976_headerFooter3 Change-Id: Idc12c57b69ff83cbdcbac3f6a469fadd8f26fe2f Reviewed-on: https://gerrit.libreoffice.org/c/core/+/170326 Reviewed-by: Tomaž Vajngerl <quikee@gmail.com> Reviewed-by: Justin Luth <jluth@mail.com> Tested-by: Jenkins (cherry picked from commit 0abe0f62b9913ceb77c7ac067f1074ce0395ab93) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/170352 Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org> Signed-off-by: Xisco Fauli <xiscofauli@libreoffice.org> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/170486
Diffstat (limited to 'sw')
-rw-r--r--sw/qa/extras/rtfexport/data/tdf160976_headerFooter.odtbin0 -> 11991 bytes
-rw-r--r--sw/qa/extras/rtfexport/data/tdf160976_headerFooter2.odtbin0 -> 12352 bytes
-rw-r--r--sw/qa/extras/rtfexport/data/tdf160976_headerFooter3.odtbin0 -> 12451 bytes
-rw-r--r--sw/qa/extras/rtfexport/rtfexport8.cxx55
-rw-r--r--sw/source/filter/ww8/rtfexport.cxx53
-rw-r--r--sw/source/filter/ww8/rtfexport.hxx3
6 files changed, 92 insertions, 19 deletions
diff --git a/sw/qa/extras/rtfexport/data/tdf160976_headerFooter.odt b/sw/qa/extras/rtfexport/data/tdf160976_headerFooter.odt
new file mode 100644
index 000000000000..d2b692613684
--- /dev/null
+++ b/sw/qa/extras/rtfexport/data/tdf160976_headerFooter.odt
Binary files differ
diff --git a/sw/qa/extras/rtfexport/data/tdf160976_headerFooter2.odt b/sw/qa/extras/rtfexport/data/tdf160976_headerFooter2.odt
new file mode 100644
index 000000000000..eb6fd0f1be8a
--- /dev/null
+++ b/sw/qa/extras/rtfexport/data/tdf160976_headerFooter2.odt
Binary files differ
diff --git a/sw/qa/extras/rtfexport/data/tdf160976_headerFooter3.odt b/sw/qa/extras/rtfexport/data/tdf160976_headerFooter3.odt
new file mode 100644
index 000000000000..43077a273fe0
--- /dev/null
+++ b/sw/qa/extras/rtfexport/data/tdf160976_headerFooter3.odt
Binary files differ
diff --git a/sw/qa/extras/rtfexport/rtfexport8.cxx b/sw/qa/extras/rtfexport/rtfexport8.cxx
index 7b303f3fd3da..743d652ce31c 100644
--- a/sw/qa/extras/rtfexport/rtfexport8.cxx
+++ b/sw/qa/extras/rtfexport/rtfexport8.cxx
@@ -349,6 +349,61 @@ DECLARE_RTFEXPORT_TEST(testTdf158982, "tdf158982.rtf")
getProperty<sal_Int32>(xPara, "ParaLeftMargin"));
}
+CPPUNIT_TEST_FIXTURE(Test, testTdf160976_headerFooter)
+{
+ // given a nasty ODT with first-even-odd page styles, emulate using RTF's abilities
+ auto verify = [this](bool bIsExported = false) {
+ // Sanity check - always good to test when dealing with page styles and breaks.
+ CPPUNIT_ASSERT_EQUAL(3, getPages());
+
+ CPPUNIT_ASSERT_EQUAL(u"First page first footer"_ustr,
+ parseDump("/root/page[1]/footer/txt"_ostr));
+ CPPUNIT_ASSERT_EQUAL(u"First Left"_ustr, parseDump("/root/page[2]/footer/txt"_ostr));
+ if (!bIsExported)
+ CPPUNIT_ASSERT_EQUAL(u"First Right"_ustr, parseDump("/root/page[3]/footer/txt"_ostr));
+ };
+ createSwDoc("tdf160976_headerFooter.odt");
+ verify();
+ saveAndReload(mpFilter);
+ verify(/*IsExported*/ true);
+ // note: an unexpected header surfaces on page 3.
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testTdf160976_headerFooter2)
+{
+ // given a typical ODT with first-follow page styles, emulate using RTF's abilities
+ auto verify = [this]() {
+ // Sanity check - always good to test when dealing with page styles and breaks.
+ CPPUNIT_ASSERT_EQUAL(3, getPages());
+
+ CPPUNIT_ASSERT_EQUAL(u"First page first footer"_ustr,
+ parseDump("/root/page[1]/footer/txt"_ostr));
+ CPPUNIT_ASSERT_EQUAL(u"First page footer"_ustr, parseDump("/root/page[2]/footer/txt"_ostr));
+ CPPUNIT_ASSERT_EQUAL(u"Default footer"_ustr, parseDump("/root/page[3]/footer/txt"_ostr));
+ };
+ createSwDoc("tdf160976_headerFooter2.odt");
+ verify();
+ saveAndReload(mpFilter);
+ verify();
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testTdf160976_headerFooter3)
+{
+ // given a simple ODT with typical "different first" on the default page style
+ auto verify = [this]() {
+ // Sanity check - always good to test when dealing with page styles and breaks.
+ CPPUNIT_ASSERT_EQUAL(3, getPages());
+
+ CPPUNIT_ASSERT_EQUAL(u"First page footer"_ustr, parseDump("/root/page[1]/footer/txt"_ostr));
+ CPPUNIT_ASSERT_EQUAL(u"Default footer"_ustr, parseDump("/root/page[2]/footer/txt"_ostr));
+ CPPUNIT_ASSERT_EQUAL(u"Default footer"_ustr, parseDump("/root/page[3]/footer/txt"_ostr));
+ };
+ createSwDoc("tdf160976_headerFooter3.odt");
+ verify();
+ saveAndReload(mpFilter);
+ verify();
+}
+
} // end of anonymous namespace
CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sw/source/filter/ww8/rtfexport.cxx b/sw/source/filter/ww8/rtfexport.cxx
index 87a8a2e8e262..15c004793970 100644
--- a/sw/source/filter/ww8/rtfexport.cxx
+++ b/sw/source/filter/ww8/rtfexport.cxx
@@ -1425,26 +1425,29 @@ void RtfExport::OutPageDescription(const SwPageDesc& rPgDsc, bool bCheckForFirst
m_pFirstPageItemSet = nullptr;
m_bOutPageDescs = false;
+ const bool bFakeFirst = m_pCurrentPageDesc != &rPgDsc;
+ if (bFakeFirst || !m_pCurrentPageDesc->IsFirstShared())
+ Strm().WriteOString(OOO_STRING_SVTOOLS_RTF_TITLEPG);
+
// normal header / footer (without a style)
const SfxPoolItem* pItem;
if (m_pCurrentPageDesc->GetLeft().GetAttrSet().GetItemState(RES_HEADER, false, &pItem)
== SfxItemState::SET)
- WriteHeaderFooter(*pItem, true);
+ WriteHeaderFooter(*pItem, /*Header*/ true, /*AsTitlePg*/ false, /*WriteFirst*/ !bFakeFirst);
if (m_pCurrentPageDesc->GetLeft().GetAttrSet().GetItemState(RES_FOOTER, false, &pItem)
== SfxItemState::SET)
- WriteHeaderFooter(*pItem, false);
+ WriteHeaderFooter(*pItem, false, /*AsTitlePg*/ false, /*WriteFirst*/ !bFakeFirst);
// title page
- if (m_pCurrentPageDesc != &rPgDsc)
+ if (bFakeFirst)
{
- Strm().WriteOString(OOO_STRING_SVTOOLS_RTF_TITLEPG);
m_pCurrentPageDesc = &rPgDsc;
if (m_pCurrentPageDesc->GetMaster().GetAttrSet().GetItemState(RES_HEADER, false, &pItem)
== SfxItemState::SET)
- WriteHeaderFooter(*pItem, true);
+ WriteHeaderFooter(*pItem, /*Header*/ true, /*AsTitlePg*/ true, /*WriteFirst*/ false);
if (m_pCurrentPageDesc->GetMaster().GetAttrSet().GetItemState(RES_FOOTER, false, &pItem)
== SfxItemState::SET)
- WriteHeaderFooter(*pItem, false);
+ WriteHeaderFooter(*pItem, /*Header*/ false, /*AsTitlePg*/ true, /*WriteFirst*/ false);
}
// numbering type
@@ -1455,8 +1458,18 @@ void RtfExport::OutPageDescription(const SwPageDesc& rPgDsc, bool bCheckForFirst
SAL_INFO("sw.rtf", __func__ << " end");
}
-void RtfExport::WriteHeaderFooter(const SfxPoolItem& rItem, bool bHeader)
+/** WriteHeaderFooter: used to write the initial header and footers
+ * @param bHeader: true for a header, false for a footer.
+ * @param bAsTitlePg: used to emulate a first-follow page style linking.
+ * Set to true to only write this header as if it were a "first header".
+ * @param bWriteFirst: used to determine whether to write a non-shared first header as the header.
+ * Set to false if bAsTitlePg will be used to define the "first header".
+ */
+void RtfExport::WriteHeaderFooter(const SfxPoolItem& rItem, bool bHeader, bool bAsTitlePg,
+ bool bWriteFirst)
{
+ assert(!bAsTitlePg || !bWriteFirst);
+
if (bHeader)
{
const auto& rHeader = static_cast<const SwFormatHeader&>(rItem);
@@ -1472,21 +1485,25 @@ void RtfExport::WriteHeaderFooter(const SfxPoolItem& rItem, bool bHeader)
SAL_INFO("sw.rtf", __func__ << " start");
- const char* pStr = (bHeader ? OOO_STRING_SVTOOLS_RTF_HEADER : OOO_STRING_SVTOOLS_RTF_FOOTER);
/* is this a title page? */
- if ((m_pCurrentPageDesc->GetFollow() && m_pCurrentPageDesc->GetFollow() != m_pCurrentPageDesc)
- || !m_pCurrentPageDesc->IsFirstShared())
+ if (bAsTitlePg || (bWriteFirst && !m_pCurrentPageDesc->IsFirstShared()))
{
- Strm().WriteOString(OOO_STRING_SVTOOLS_RTF_TITLEPG);
- pStr = (bHeader ? OOO_STRING_SVTOOLS_RTF_HEADERF : OOO_STRING_SVTOOLS_RTF_FOOTERF);
+ auto pStr = bHeader ? OOO_STRING_SVTOOLS_RTF_HEADERF : OOO_STRING_SVTOOLS_RTF_FOOTERF;
+ Strm().WriteChar('{').WriteOString(pStr);
+ WriteHeaderFooterText(m_pCurrentPageDesc->IsFirstShared()
+ ? m_pCurrentPageDesc->GetMaster()
+ : m_pCurrentPageDesc->GetFirstMaster(),
+ bHeader);
+ Strm().WriteChar('}');
}
- Strm().WriteChar('{').WriteOString(pStr);
- WriteHeaderFooterText(m_pCurrentPageDesc->IsFirstShared()
- ? m_pCurrentPageDesc->GetMaster()
- : m_pCurrentPageDesc->GetFirstMaster(),
- bHeader);
- Strm().WriteChar('}');
+ if (!bAsTitlePg)
+ {
+ auto pStr = bHeader ? OOO_STRING_SVTOOLS_RTF_HEADER : OOO_STRING_SVTOOLS_RTF_FOOTER;
+ Strm().WriteChar('{').WriteOString(pStr);
+ WriteHeaderFooterText(m_pCurrentPageDesc->GetMaster(), bHeader);
+ Strm().WriteChar('}');
+ }
SAL_INFO("sw.rtf", __func__ << " end");
}
diff --git a/sw/source/filter/ww8/rtfexport.hxx b/sw/source/filter/ww8/rtfexport.hxx
index 11f3f0471f23..faf6aeab36bf 100644
--- a/sw/source/filter/ww8/rtfexport.hxx
+++ b/sw/source/filter/ww8/rtfexport.hxx
@@ -218,7 +218,8 @@ private:
void WriteDocVars();
/// This is necessary to have the numbering table ready before the main text is being processed.
void BuildNumbering();
- void WriteHeaderFooter(const SfxPoolItem& rItem, bool bHeader);
+ void WriteHeaderFooter(const SfxPoolItem& rItem, bool bHeader, bool bAsTitlePg,
+ bool bWriteFirst);
void WriteHeaderFooter(const SwFrameFormat& rFormat, bool bHeader, const char* pStr,
bool bTitlepg = false);