[Libreoffice-commits] core.git: sw/CppunitTest_sw_ww8export2.mk sw/ooxmlexport_setup.mk sw/qa sw/source

Justin Luth justin_luth at sil.org
Thu Aug 17 12:14:58 UTC 2017


 sw/CppunitTest_sw_ww8export2.mk                             |    1 
 sw/ooxmlexport_setup.mk                                     |    1 
 sw/qa/extras/ooxmlexport/data/tdf55427_footnote2endnote.odt |binary
 sw/qa/extras/ooxmlexport/ooxmlexport9.cxx                   |   57 +++++++++++
 sw/qa/extras/ww8export/data/tdf55427_footnote2endnote.odt   |binary
 sw/qa/extras/ww8export/ww8export2.cxx                       |   58 ++++++++++++
 sw/source/filter/ww8/docxattributeoutput.cxx                |    8 +
 sw/source/filter/ww8/rtfattributeoutput.cxx                 |    3 
 sw/source/filter/ww8/ww8atr.cxx                             |    2 
 9 files changed, 125 insertions(+), 5 deletions(-)

New commits:
commit be6534dc47568dbf57057dec73ef260b63e198c0
Author: Justin Luth <justin_luth at sil.org>
Date:   Sat Jun 10 12:12:50 2017 +0300

    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 at libreoffice.org>
    Reviewed-by: Justin Luth <justin_luth at sil.org>
    Reviewed-by: Miklos Vajna <vmiklos at collabora.co.uk>

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
Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/tdf55427_footnote2endnote.odt 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
Binary files /dev/null and b/sw/qa/extras/ww8export/data/tdf55427_footnote2endnote.odt 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;


More information about the Libreoffice-commits mailing list