summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJustin Luth <justin_luth@sil.org>2017-06-10 12:12:50 +0300
committerMiklos Vajna <vmiklos@collabora.co.uk>2017-08-17 14:13:11 +0200
commitbe6534dc47568dbf57057dec73ef260b63e198c0 (patch)
tree7be4dfe2624528329c2a93bb9599dc452d7afba8
parent91f4d01af4772fe5156e59ea4f4ef771de657a57 (diff)
tdf#55427 ww8export: treat document-end-footnotes as endnotes
MSWord has two choices for footnotes - at page-end or page-bottom. LO has different choices for footnotes - at document-end or page-bottom. Since document-end footnotes act like endnotes, convert those footnotes into endnotes during DOC/DOCX/RTF export. No matter what happens in this situation, some compromises have to be made. The main compromise now is that the anchor numbering for endnotes defaults to i,ii,iii while footnotes are 1,2,3. The conversion obviously will switch to endnote style. This is user adjustable of course and will be retained on following round-trips. Also the (footnote) paragraph style is retained, but future endnotes will use a potentially different endnote paragraph style. Remedying those perceived deficiency is left as an exercise for the motivated reader, who of course will take into account the possibility of both endnotes and chapter-end footnotes existing in the same document... The unit tests' primary purpose is to ensure that footnotes following down the endnote export path don't cause LO to crash. Change-Id: I219d499df7981a14f824a664b15051ad10ff6642 Reviewed-on: https://gerrit.libreoffice.org/38634 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Justin Luth <justin_luth@sil.org> Reviewed-by: Miklos Vajna <vmiklos@collabora.co.uk>
-rw-r--r--sw/CppunitTest_sw_ww8export2.mk1
-rw-r--r--sw/ooxmlexport_setup.mk1
-rw-r--r--sw/qa/extras/ooxmlexport/data/tdf55427_footnote2endnote.odtbin0 -> 13291 bytes
-rw-r--r--sw/qa/extras/ooxmlexport/ooxmlexport9.cxx57
-rw-r--r--sw/qa/extras/ww8export/data/tdf55427_footnote2endnote.odtbin0 -> 13291 bytes
-rw-r--r--sw/qa/extras/ww8export/ww8export2.cxx58
-rw-r--r--sw/source/filter/ww8/docxattributeoutput.cxx8
-rw-r--r--sw/source/filter/ww8/rtfattributeoutput.cxx3
-rw-r--r--sw/source/filter/ww8/ww8atr.cxx2
9 files changed, 125 insertions, 5 deletions
diff --git a/sw/CppunitTest_sw_ww8export2.mk b/sw/CppunitTest_sw_ww8export2.mk
index f5e37733c3ed..20f7df957a61 100644
--- a/sw/CppunitTest_sw_ww8export2.mk
+++ b/sw/CppunitTest_sw_ww8export2.mk
@@ -19,6 +19,7 @@ $(eval $(call gb_CppunitTest_use_libraries,sw_ww8export2, \
comphelper \
cppu \
cppuhelper \
+ editeng \
$(if $(filter WNT-TRUE,$(OS)-$(DISABLE_ATL)),,emboleobj) \
sal \
sfx \
diff --git a/sw/ooxmlexport_setup.mk b/sw/ooxmlexport_setup.mk
index b421d0e1ad4f..927873992c28 100644
--- a/sw/ooxmlexport_setup.mk
+++ b/sw/ooxmlexport_setup.mk
@@ -13,6 +13,7 @@ define sw_ooxmlexport_libraries
comphelper \
cppu \
cppuhelper \
+ editeng \
sal \
sfx \
sw \
diff --git a/sw/qa/extras/ooxmlexport/data/tdf55427_footnote2endnote.odt b/sw/qa/extras/ooxmlexport/data/tdf55427_footnote2endnote.odt
new file mode 100644
index 000000000000..7f77f6d39e02
--- /dev/null
+++ b/sw/qa/extras/ooxmlexport/data/tdf55427_footnote2endnote.odt
Binary files differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport9.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport9.cxx
index 6c7da90e2d96..caecccfa0681 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport9.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport9.cxx
@@ -28,6 +28,7 @@
#include <com/sun/star/style/LineSpacing.hpp>
#include <com/sun/star/style/LineSpacingMode.hpp>
+#include <ftninfo.hxx>
#include <sfx2/docfile.hxx>
#include <sfx2/docfilt.hxx>
@@ -583,6 +584,62 @@ DECLARE_OOXMLEXPORT_TEST(testTdf82173_endnoteStyle, "tdf82173_endnoteStyle.docx"
CPPUNIT_ASSERT_EQUAL( sal_Int32(0xFF00FF), getProperty< sal_Int32 >(xPageStyle, "CharColor") );
}
+DECLARE_OOXMLEXPORT_TEST(testTdf55427_footnote2endnote, "tdf55427_footnote2endnote.odt")
+{
+ uno::Reference<beans::XPropertySet> xPageStyle(getStyles("ParagraphStyles")->getByName("Footnote"), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE( "Footnote style is rose color", sal_Int32(0xFF007F), getProperty< sal_Int32 >(xPageStyle, "CharColor") );
+ xPageStyle.set(getStyles("ParagraphStyles")->getByName("Endnote"), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE( "Endnote style is cyan3 color", sal_Int32(0x2BD0D2), getProperty< sal_Int32 >(xPageStyle, "CharColor") );
+
+ SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
+ SwDoc* pDoc = pTextDoc->GetDocShell()->GetDoc();
+ // The footnote numbering type of ARABIC will not transfer over when those footnotes are converted to endnotes.
+ CPPUNIT_ASSERT_EQUAL_MESSAGE( "Footnote numbering type", SVX_NUM_ARABIC, pDoc->GetFootnoteInfo().aFormat.GetNumberingType() );
+ // The original document has a real endnote using ROMAN_LOWER numbering, so that setting MUST remain unchanged.
+ CPPUNIT_ASSERT_EQUAL_MESSAGE( "Endnote numbering type", SVX_NUM_ROMAN_LOWER, pDoc->GetEndNoteInfo().aFormat.GetNumberingType() );
+
+ uno::Reference<text::XFootnotesSupplier> xFootnotesSupplier(mxComponent, uno::UNO_QUERY);
+ uno::Reference<container::XIndexAccess> xFootnotes(xFootnotesSupplier->getFootnotes(), uno::UNO_QUERY);
+
+ uno::Reference<text::XEndnotesSupplier> xEndnotesSupplier(mxComponent, uno::UNO_QUERY);
+ uno::Reference<container::XIndexAccess> xEndnotes(xEndnotesSupplier->getEndnotes(), uno::UNO_QUERY);
+ uno::Reference<text::XFootnote> xEndnote;
+ xEndnotes->getByIndex(0) >>= xEndnote;
+ uno::Reference<text::XText> xEndnoteText;
+ xEndnotes->getByIndex(0) >>= xEndnoteText;
+
+ // ODT footnote-at-document-end's closest DOCX match is an endnote, so the two imports will not exactly match by design.
+ if (!mbExported)
+ {
+ CPPUNIT_ASSERT_EQUAL_MESSAGE( "original footnote count", sal_Int32(5), xFootnotes->getCount() );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE( "original endnote count", sal_Int32(1), xEndnotes->getCount() );
+
+ uno::Reference<text::XFootnote> xFootnote;
+ xFootnotes->getByIndex(0) >>= xFootnote;
+ CPPUNIT_ASSERT_EQUAL_MESSAGE( "original footnote's number", OUString("1"), xFootnote->getAnchor()->getString() );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE( "original endnote's number", OUString("i"), xEndnote->getAnchor()->getString() );
+
+ uno::Reference<text::XText> xFootnoteText;
+ xFootnotes->getByIndex(0) >>= xFootnoteText;
+ CPPUNIT_ASSERT_EQUAL_MESSAGE( "original footnote style", OUString("Footnote"), getProperty<OUString>(getParagraphOfText(1, xFootnoteText), "ParaStyleName") );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE( "original endnote style", OUString("Endnote"), getProperty<OUString>(getParagraphOfText(1, xEndnoteText), "ParaStyleName") );
+ }
+ else
+ {
+ // These asserted items are major differences in the conversion from footnote to endnote, NOT necessary conditions for a proper functioning document.
+ CPPUNIT_ASSERT_EQUAL_MESSAGE( "At-Document-End footnotes were converted into endnotes", sal_Int32(0), xFootnotes->getCount() );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE( "At-Document-End footnotes became endnotes", sal_Int32(6), xEndnotes->getCount() );
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE( "converted footnote's number", OUString("i"), xEndnote->getAnchor()->getString() );
+ xEndnotes->getByIndex(4) >>= xEndnote;
+ CPPUNIT_ASSERT_EQUAL_MESSAGE( "original endnote's new number", OUString("v"), xEndnote->getAnchor()->getString() );
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE( "retained footnote style", OUString("Footnote"), getProperty<OUString>(getParagraphOfText(1, xEndnoteText), "ParaStyleName") );
+ xEndnotes->getByIndex(4) >>= xEndnoteText;
+ CPPUNIT_ASSERT_EQUAL_MESSAGE( "original endnote style", OUString("Endnote"), getProperty<OUString>(getParagraphOfText(1, xEndnoteText), "ParaStyleName") );
+ }
+}
+
DECLARE_OOXMLEXPORT_TEST(testTdf104162, "tdf104162.docx")
{
// This crashed: the comment field contained a table with a <w:hideMark/>.
diff --git a/sw/qa/extras/ww8export/data/tdf55427_footnote2endnote.odt b/sw/qa/extras/ww8export/data/tdf55427_footnote2endnote.odt
new file mode 100644
index 000000000000..7f77f6d39e02
--- /dev/null
+++ b/sw/qa/extras/ww8export/data/tdf55427_footnote2endnote.odt
Binary files differ
diff --git a/sw/qa/extras/ww8export/ww8export2.cxx b/sw/qa/extras/ww8export/ww8export2.cxx
index 7ace54f52f61..cb6155cf444a 100644
--- a/sw/qa/extras/ww8export/ww8export2.cxx
+++ b/sw/qa/extras/ww8export/ww8export2.cxx
@@ -16,6 +16,8 @@
#include <com/sun/star/text/XTextTable.hpp>
#include <com/sun/star/text/XTextTablesSupplier.hpp>
#include <com/sun/star/text/XFootnote.hpp>
+
+#include <ftninfo.hxx>
#include <pagedesc.hxx>
class Test : public SwModelTestBase
@@ -50,6 +52,62 @@ DECLARE_WW8EXPORT_TEST(testTdf49102_mergedCellNumbering, "tdf49102_mergedCellNum
CPPUNIT_ASSERT_EQUAL( OUString("2."), parseDump("/root/page/body/tab/row[4]/cell/txt/Special[@nType='POR_NUMBER']", "rText") );
}
+DECLARE_WW8EXPORT_TEST(testTdf55427_footnote2endnote, "tdf55427_footnote2endnote.odt")
+{
+ uno::Reference<beans::XPropertySet> xPageStyle(getStyles("ParagraphStyles")->getByName("Footnote"), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE( "Footnote style is rose color", sal_Int32(0xFF007F), getProperty< sal_Int32 >(xPageStyle, "CharColor") );
+ xPageStyle.set(getStyles("ParagraphStyles")->getByName("Endnote"), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE( "Endnote style is cyan3 color", sal_Int32(0x2BD0D2), getProperty< sal_Int32 >(xPageStyle, "CharColor") );
+
+ SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
+ SwDoc* pDoc = pTextDoc->GetDocShell()->GetDoc();
+ // The footnote numbering type of ARABIC will not transfer over when those footnotes are converted to endnotes.
+ CPPUNIT_ASSERT_EQUAL_MESSAGE( "Footnote numbering type", SVX_NUM_ARABIC, pDoc->GetFootnoteInfo().aFormat.GetNumberingType() );
+ // The original document has a real endnote using ROMAN_LOWER numbering, so that setting MUST remain unchanged.
+ CPPUNIT_ASSERT_EQUAL_MESSAGE( "Endnote numbering type", SVX_NUM_ROMAN_LOWER, pDoc->GetEndNoteInfo().aFormat.GetNumberingType() );
+
+ uno::Reference<text::XFootnotesSupplier> xFootnotesSupplier(mxComponent, uno::UNO_QUERY);
+ uno::Reference<container::XIndexAccess> xFootnotes(xFootnotesSupplier->getFootnotes(), uno::UNO_QUERY);
+
+ uno::Reference<text::XEndnotesSupplier> xEndnotesSupplier(mxComponent, uno::UNO_QUERY);
+ uno::Reference<container::XIndexAccess> xEndnotes(xEndnotesSupplier->getEndnotes(), uno::UNO_QUERY);
+ uno::Reference<text::XFootnote> xEndnote;
+ xEndnotes->getByIndex(0) >>= xEndnote;
+ uno::Reference<text::XText> xEndnoteText;
+ xEndnotes->getByIndex(0) >>= xEndnoteText;
+
+ // ODT footnote-at-document-end's closest DOC match is an endnote, so the two imports will not exactly match by design.
+ if (!mbExported)
+ {
+ CPPUNIT_ASSERT_EQUAL_MESSAGE( "original footnote count", sal_Int32(5), xFootnotes->getCount() );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE( "original endnote count", sal_Int32(1), xEndnotes->getCount() );
+
+ uno::Reference<text::XFootnote> xFootnote;
+ xFootnotes->getByIndex(0) >>= xFootnote;
+ CPPUNIT_ASSERT_EQUAL_MESSAGE( "original footnote's number", OUString("1"), xFootnote->getAnchor()->getString() );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE( "original endnote's number", OUString("i"), xEndnote->getAnchor()->getString() );
+
+ uno::Reference<text::XText> xFootnoteText;
+ xFootnotes->getByIndex(0) >>= xFootnoteText;
+ CPPUNIT_ASSERT_EQUAL_MESSAGE( "original footnote style", OUString("Footnote"), getProperty<OUString>(getParagraphOfText(1, xFootnoteText), "ParaStyleName") );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE( "original endnote style", OUString("Endnote"), getProperty<OUString>(getParagraphOfText(1, xEndnoteText), "ParaStyleName") );
+ }
+ else
+ {
+ // These asserted items are major differences in the conversion from footnote to endnote, NOT necessary conditions for a proper functioning document.
+ CPPUNIT_ASSERT_EQUAL_MESSAGE( "At-Document-End footnotes were converted into endnotes", sal_Int32(0), xFootnotes->getCount() );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE( "At-Document-End footnotes became endnotes", sal_Int32(6), xEndnotes->getCount() );
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE( "converted footnote's number", OUString("i"), xEndnote->getAnchor()->getString() );
+ xEndnotes->getByIndex(4) >>= xEndnote;
+ CPPUNIT_ASSERT_EQUAL_MESSAGE( "original endnote's new number", OUString("v"), xEndnote->getAnchor()->getString() );
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE( "retained footnote style", OUString("Footnote"), getProperty<OUString>(getParagraphOfText(1, xEndnoteText), "ParaStyleName") );
+ xEndnotes->getByIndex(4) >>= xEndnoteText;
+ CPPUNIT_ASSERT_EQUAL_MESSAGE( "original endnote style", OUString("Endnote"), getProperty<OUString>(getParagraphOfText(1, xEndnoteText), "ParaStyleName") );
+ }
+}
+
DECLARE_WW8EXPORT_TEST(testTdf107931_KERN_DocEnabled_disabledDefStyle, "testTdf107931_KERN_DocEnabled_disabledDefStyle.doc")
{
// Paragraph 3: the default style has kerning disabled
diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx
index 5d7490223eda..93cd4daba349 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -6917,7 +6917,7 @@ void DocxAttributeOutput::TextFootnote_Impl( const SwFormatFootnote& rFootnote )
// remember the footnote/endnote to
// 1) write the footnoteReference/endnoteReference in EndRunProperties()
// 2) be able to dump them all to footnotes.xml/endnotes.xml
- if ( !rFootnote.IsEndNote() )
+ if ( !rFootnote.IsEndNote() && m_rExport.m_pDoc->GetFootnoteInfo().ePos != FTNPOS_CHAPTER )
m_pFootnotesList->add( rFootnote );
else
m_pEndnotesList->add( rFootnote );
@@ -6927,16 +6927,18 @@ void DocxAttributeOutput::FootnoteEndnoteReference()
{
sal_Int32 nId;
const SwFormatFootnote *pFootnote = m_pFootnotesList->getCurrent( nId );
+ sal_Int32 nToken = XML_footnoteReference;
// both cannot be set at the same time - if they are, it's a bug
if ( !pFootnote )
+ {
pFootnote = m_pEndnotesList->getCurrent( nId );
+ nToken = XML_endnoteReference;
+ }
if ( !pFootnote )
return;
- sal_Int32 nToken = pFootnote->IsEndNote()? XML_endnoteReference: XML_footnoteReference;
-
// write it
if ( pFootnote->GetNumStr().isEmpty() )
{
diff --git a/sw/source/filter/ww8/rtfattributeoutput.cxx b/sw/source/filter/ww8/rtfattributeoutput.cxx
index 90ac57e73142..96000d7c0c65 100644
--- a/sw/source/filter/ww8/rtfattributeoutput.cxx
+++ b/sw/source/filter/ww8/rtfattributeoutput.cxx
@@ -65,6 +65,7 @@
#include <fmtline.hxx>
#include <breakit.hxx>
#include <fmtanchr.hxx>
+#include <ftninfo.hxx>
#include <htmltbl.hxx>
#include <ndgrf.hxx>
#include <pagedesc.hxx>
@@ -2658,7 +2659,7 @@ void RtfAttributeOutput::TextFootnote_Impl(const SwFormatFootnote& rFootnote)
m_aRun->append("{" OOO_STRING_SVTOOLS_RTF_SUPER " ");
WriteTextFootnoteNumStr(rFootnote);
m_aRun->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FOOTNOTE);
- if (rFootnote.IsEndNote())
+ if ( rFootnote.IsEndNote() || m_rExport.m_pDoc->GetFootnoteInfo().ePos == FTNPOS_CHAPTER )
m_aRun->append(OOO_STRING_SVTOOLS_RTF_FTNALT);
m_aRun->append(' ');
WriteTextFootnoteNumStr(rFootnote);
diff --git a/sw/source/filter/ww8/ww8atr.cxx b/sw/source/filter/ww8/ww8atr.cxx
index f16506f2f8d1..bf689fcd10df 100644
--- a/sw/source/filter/ww8/ww8atr.cxx
+++ b/sw/source/filter/ww8/ww8atr.cxx
@@ -3132,7 +3132,7 @@ void AttributeOutputBase::TextFootnote( const SwFormatFootnote& rFootnote )
void WW8AttributeOutput::TextFootnote_Impl( const SwFormatFootnote& rFootnote )
{
WW8_WrPlcFootnoteEdn* pFootnoteEnd;
- if ( rFootnote.IsEndNote() )
+ if ( rFootnote.IsEndNote() || GetExport().m_pDoc->GetFootnoteInfo().ePos == FTNPOS_CHAPTER )
pFootnoteEnd = m_rWW8Export.pEdn;
else
pFootnoteEnd = m_rWW8Export.pFootnote;