[Libreoffice-commits] core.git: Branch 'private/swe/libreoffice-5-2+backports' - 2 commits - sc/source sw/qa sw/source

Andreas Brandner Andreas.Brandner at cib.de
Thu Nov 9 11:39:58 UTC 2017


Rebased ref, commits from common ancestor:
commit 42327130ab4455eb4fc6f487873cbf83ce21223b
Author: Andreas Brandner <Andreas.Brandner at cib.de>
Date:   Sun Nov 5 20:41:31 2017 +0100

    tdf#66401 don't lose docx-combined-characters' font props on roundtrip
    
    - font-size will now get halfed, if exported within a combined-characters-field in docx
    - font-property will get exported for every run in a field, this redundancy is required by MS Word
    
    Change-Id: Idbdb5bf3066e2ed86b494255d72d66eebf72f755
    Reviewed-on: https://gerrit.libreoffice.org/44509
    Reviewed-by: Thorsten Behrens <Thorsten.Behrens at CIB.de>
    Tested-by: Thorsten Behrens <Thorsten.Behrens at CIB.de>

diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx
index 467177d013fa..e8cdfc86182c 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -1740,12 +1740,18 @@ void DocxAttributeOutput::DoWriteCmd( const OUString& rCmd )
 
 void DocxAttributeOutput::CmdField_Impl( const SwTextNode* pNode, sal_Int32 nPos, FieldInfos const & rInfos, bool bWriteRun )
 {
+    bool bWriteCombChars(false);
+
     // Write the Field instruction
     {
         if ( bWriteRun )
         {
             m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
-            DoWriteFieldRunProperties( pNode, nPos );
+
+            if (rInfos.eType == ww::eEQ)
+                bWriteCombChars = true;
+
+            DoWriteFieldRunProperties( pNode, nPos, bWriteCombChars );
         }
 
         sal_Int32 nNbToken = comphelper::string::getTokenCount(rInfos.sCmd, '\t');
@@ -1829,7 +1835,7 @@ void DocxAttributeOutput::CmdField_Impl( const SwTextNode* pNode, sal_Int32 nPos
 ///         <w:fldChar w:fldCharType="end" />
 ///     </w:r>
 /// See, tdf#38778
-void DocxAttributeOutput::DoWriteFieldRunProperties( const SwTextNode * pNode, sal_Int32 nPos )
+void DocxAttributeOutput::DoWriteFieldRunProperties( const SwTextNode * pNode, sal_Int32 nPos, bool bWriteCombChars)
 {
     if (! pNode)
     {
@@ -1859,7 +1865,17 @@ void DocxAttributeOutput::DoWriteFieldRunProperties( const SwTextNode * pNode, s
 
         // 3. output all other character properties
         SwWW8AttrIter aAttrIt( m_rExport, *pNode );
-        aAttrIt.OutAttr( nPos, false );
+        aAttrIt.OutAttr( nPos, false, bWriteCombChars );
+
+        // 4. explicitly write the font-properties, to ensure all runs in the field have them
+        // see tdf#66401
+        if ( m_pFontsAttrList.is() )
+        {
+            XFastAttributeListRef xAttrList( m_pFontsAttrList.get() );
+            m_pFontsAttrList.clear();
+
+            m_pSerializer->singleElementNS( XML_w, XML_rFonts, xAttrList );
+        }
 
         m_pSerializer->endElementNS( XML_w, XML_rPr );
 
diff --git a/sw/source/filter/ww8/docxattributeoutput.hxx b/sw/source/filter/ww8/docxattributeoutput.hxx
index 4c41f83d2f30..64fa4238e617 100644
--- a/sw/source/filter/ww8/docxattributeoutput.hxx
+++ b/sw/source/filter/ww8/docxattributeoutput.hxx
@@ -729,7 +729,7 @@ private:
     void DoWriteCmd( const OUString& rCmd );
     void CmdField_Impl( const SwTextNode* pNode, sal_Int32 nPos, FieldInfos const & rInfos, bool bWriteRun );
     void EndField_Impl( const SwTextNode* pNode, sal_Int32 nPos, FieldInfos& rInfos );
-    void DoWriteFieldRunProperties( const SwTextNode* pNode, sal_Int32 nPos );
+    void DoWriteFieldRunProperties( const SwTextNode* pNode, sal_Int32 nPos, bool bWriteCombChars = false );
     virtual void GenerateBookmarksForSequenceField(const SwTextNode& rNode, SwWW8AttrIter& rAttrIter) override;
 
     static void AddToAttrList( css::uno::Reference<sax_fastparser::FastAttributeList>& pAttrList, sal_Int32 nAttrName, const sal_Char* sAttrValue );
diff --git a/sw/source/filter/ww8/wrtw8nds.cxx b/sw/source/filter/ww8/wrtw8nds.cxx
index e9ba18f40d6f..33b67ea5e627 100644
--- a/sw/source/filter/ww8/wrtw8nds.cxx
+++ b/sw/source/filter/ww8/wrtw8nds.cxx
@@ -382,7 +382,7 @@ static bool lcl_isFontsizeItem( const SfxPoolItem& rItem )
             rItem.Which( ) == RES_CHRATR_CTL_FONTSIZE );
 }
 
-void SwWW8AttrIter::OutAttr( sal_Int32 nSwPos, bool bRuby )
+void SwWW8AttrIter::OutAttr( sal_Int32 nSwPos, bool bRuby , bool bWriteCombChars)
 {
     m_rExport.AttrOutput().RTLAndCJKState( IsCharRTL(), GetScript() );
 
@@ -488,7 +488,7 @@ void SwWW8AttrIter::OutAttr( sal_Int32 nSwPos, bool bRuby )
         // tdf#38778 Fix output of the font in DOC run for fields
         const SvxFontItem * pFontToOutput = ( rParentFont != *pFont )? pFont : nullptr;
 
-        m_rExport.ExportPoolItemsToCHP( aExportItems, GetScript(), pFontToOutput );
+        m_rExport.ExportPoolItemsToCHP( aExportItems, GetScript(), pFontToOutput, bWriteCombChars );
 
         // HasTextItem only allowed in the above range
         m_rExport.m_aCurrentCharPropStarts.pop();
diff --git a/sw/source/filter/ww8/wrtww8.hxx b/sw/source/filter/ww8/wrtww8.hxx
index dafffeaafd44..ff25dedd1c3e 100644
--- a/sw/source/filter/ww8/wrtww8.hxx
+++ b/sw/source/filter/ww8/wrtww8.hxx
@@ -584,7 +584,7 @@ public:
     void WriteSpecialText( sal_uLong nStart, sal_uLong nEnd, sal_uInt8 nTTyp );
 
     /// Export the pool items to attributes (through an attribute output class).
-    void ExportPoolItemsToCHP( ww8::PoolItems &rItems, sal_uInt16 nScript, const SvxFontItem *pFont );
+    void ExportPoolItemsToCHP( ww8::PoolItems &rItems, sal_uInt16 nScript, const SvxFontItem *pFont, bool bWriteCombChars = false );
 
     /// Return the numeric id of the numbering rule
     sal_uInt16 GetId( const SwNumRule& rNumRule );
@@ -1490,7 +1490,7 @@ public:
 
     void NextPos() { if ( nAktSwPos < SAL_MAX_INT32 ) nAktSwPos = SearchNext( nAktSwPos + 1 ); }
 
-    void OutAttr( sal_Int32 nSwPos, bool bRuby = false );
+    void OutAttr( sal_Int32 nSwPos, bool bRuby = false, bool bWriteCombinedChars = false );
     virtual const SfxPoolItem* HasTextItem( sal_uInt16 nWhich ) const override;
     virtual const SfxPoolItem& GetItem( sal_uInt16 nWhich ) const override;
     int OutAttrWithRange(const SwTextNode& rNode, sal_Int32 nPos);
diff --git a/sw/source/filter/ww8/ww8atr.cxx b/sw/source/filter/ww8/ww8atr.cxx
index fbb763a1459a..3250808165a8 100644
--- a/sw/source/filter/ww8/ww8atr.cxx
+++ b/sw/source/filter/ww8/ww8atr.cxx
@@ -204,7 +204,7 @@ bool WW8Export::CollapseScriptsforWordOk( sal_uInt16 nScript, sal_uInt16 nWhich
 
 //  Hilfsroutinen fuer Styles
 
-void MSWordExportBase::ExportPoolItemsToCHP( ww8::PoolItems &rItems, sal_uInt16 nScript, const SvxFontItem *pFont )
+void MSWordExportBase::ExportPoolItemsToCHP( ww8::PoolItems &rItems, sal_uInt16 nScript, const SvxFontItem *pFont, bool bWriteCombChars )
 {
     ww8::cPoolItemIter aEnd = rItems.end();
     for ( ww8::cPoolItemIter aI = rItems.begin(); aI != aEnd; ++aI )
@@ -228,7 +228,21 @@ void MSWordExportBase::ExportPoolItemsToCHP( ww8::PoolItems &rItems, sal_uInt16
                  AttrOutput().OutputItem( *pFont );
              }
 
-             AttrOutput().OutputItem( *pItem );
+             // tdf#66401 For Combined Characters in docx, MS Word uses half the normal font-size for the field's
+             // font-size, but only for <w:sz>. Therefore, we check if we are currently writing a field of type
+             // Combined Characters and if so, we half the font size.
+             if (bWriteCombChars &&
+                 nWhich == RES_CHRATR_FONTSIZE)
+             {
+                SvxFontHeightItem fontHeight(item_cast<SvxFontHeightItem>( *pItem ));
+                fontHeight.SetHeight( fontHeight.GetHeight() / 2 );
+
+                AttrOutput().OutputItem( fontHeight );
+             }
+             else
+             {
+                AttrOutput().OutputItem( *pItem );
+             }
         }
     }
 }
commit 56a1fdbb2b97a5b2f3adb3fc8628b9c12313a6b9
Author: Tamás Zolnai <tamas.zolnai at collabora.com>
Date:   Mon Nov 6 18:46:56 2017 +0100

    tdf#42346: DOCX export of cross-references to objects
    
    * Objects means tables, images, text frames and shapes
    * Implementation
    ** MSO uses simple bookmark references as cross-references to objects
    ** So generate bookmarks in export time if a caption is referenced
    ** In some cases we also need to split some of the runs
    ** Implemented all types of cross-references, except the chapter reference
    
    Reviewed-on: https://gerrit.libreoffice.org/44294
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Tamás Zolnai <tamas.zolnai at collabora.com>
    (cherry picked from commit 98bc7215935f1eb2e0dc6f1db826d8e729430c13)
    
    Change-Id: I3b17753123d94a04e4f28783ad5663831e7c6c84
    Reviewed-on: https://gerrit.libreoffice.org/44372
    Reviewed-by: Thorsten Behrens <Thorsten.Behrens at CIB.de>
    Tested-by: Thorsten Behrens <Thorsten.Behrens at CIB.de>

diff --git a/sc/source/ui/view/tabview.cxx b/sc/source/ui/view/tabview.cxx
index e5b1561abd2d..078ef88552fc 100644
--- a/sc/source/ui/view/tabview.cxx
+++ b/sc/source/ui/view/tabview.cxx
@@ -350,7 +350,7 @@ void ScTabView::DoResize( const Point& rOffset, const Size& rSize, bool bInner )
 
 
     Size aFontSize = rStyleSettings.GetTabFont().GetFontSize();
-    MapMode aPtMapMode(MapUnit::MapPoint);
+    MapMode aPtMapMode(MapUnit::MAP_POINT);
     aFontSize = pFrameWin->LogicToPixel(aFontSize, aPtMapMode);
     sal_Int32 nTabWidth = aFontSize.Height() + WIDTH_MARGIN;
 
diff --git a/sw/qa/extras/ooxmlexport/data/object_cross_reference.odt b/sw/qa/extras/ooxmlexport/data/object_cross_reference.odt
new file mode 100755
index 000000000000..18b02a38c2a9
Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/object_cross_reference.odt differ
diff --git a/sw/qa/extras/ooxmlexport/data/table_cross_reference.odt b/sw/qa/extras/ooxmlexport/data/table_cross_reference.odt
new file mode 100755
index 000000000000..bd9c84016157
Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/table_cross_reference.odt differ
diff --git a/sw/qa/extras/ooxmlexport/data/table_cross_reference_custom_format.odt b/sw/qa/extras/ooxmlexport/data/table_cross_reference_custom_format.odt
new file mode 100755
index 000000000000..cbf03d34ed9f
Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/table_cross_reference_custom_format.odt differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport7.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport7.cxx
index b82b39e7c34c..51e3089d9647 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport7.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport7.cxx
@@ -9,8 +9,6 @@
 
 #include <swmodeltestbase.hxx>
 
-#if !defined(_WIN32)
-
 #include <com/sun/star/drawing/EnhancedCustomShapeParameterPair.hpp>
 #include <com/sun/star/drawing/EnhancedCustomShapeSegment.hpp>
 #include <com/sun/star/drawing/EnhancedCustomShapeSegmentCommand.hpp>
@@ -45,6 +43,8 @@ protected:
     }
 };
 
+#if !defined(_WIN32)
+
 DECLARE_OOXMLEXPORT_TEST( testChildNodesOfCubicBezierTo, "FDO74774.docx")
 {
     /* Number of children required by cubicBexTo is 3 of type "pt".
@@ -1245,6 +1245,577 @@ DECLARE_OOXMLEXPORT_TEST(testTdf107111, "tdf107111.docx")
 
 #endif
 
+DECLARE_OOXMLEXPORT_TEST( testTableCrossReference, "table_cross_reference.odt" )
+{
+    // tdf#42346: Cross references to tables were not saved
+    // MSO uses simple bookmarks for referencing table caption, so we do the same by export
+    if (!mbExported)
+        return;
+
+    // Check whether we have all the neccessary bookmarks exported and imported back
+    uno::Reference<text::XBookmarksSupplier> xBookmarksSupplier(mxComponent, uno::UNO_QUERY);
+    uno::Reference<container::XIndexAccess> xBookmarksByIdx(xBookmarksSupplier->getBookmarks(), uno::UNO_QUERY);
+    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(4), xBookmarksByIdx->getCount());
+    uno::Reference<container::XNameAccess> xBookmarksByName(xBookmarksSupplier->getBookmarks(), uno::UNO_QUERY);
+    CPPUNIT_ASSERT(xBookmarksByName->hasByName("Ref_Table0_full"));
+    CPPUNIT_ASSERT(xBookmarksByName->hasByName("Ref_Table0_label_and_number"));
+    CPPUNIT_ASSERT(xBookmarksByName->hasByName("Ref_Table0_caption_only"));
+    CPPUNIT_ASSERT(xBookmarksByName->hasByName("Ref_Table0_number_only"));
+
+    // Check bookmark text ranges
+    {
+        uno::Reference<text::XTextContent> xContent(xBookmarksByName->getByName("Ref_Table0_full"), uno::UNO_QUERY);
+        uno::Reference<text::XTextRange> xRange(xContent->getAnchor(), uno::UNO_QUERY);
+        CPPUNIT_ASSERT_EQUAL(OUString("Table 1: Table caption"), xRange->getString());
+    }
+    {
+        uno::Reference<text::XTextContent> xContent(xBookmarksByName->getByName("Ref_Table0_label_and_number"), uno::UNO_QUERY);
+        uno::Reference<text::XTextRange> xRange(xContent->getAnchor(), uno::UNO_QUERY);
+        CPPUNIT_ASSERT_EQUAL(OUString("Table 1"), xRange->getString());
+    }
+    {
+        uno::Reference<text::XTextContent> xContent(xBookmarksByName->getByName("Ref_Table0_caption_only"), uno::UNO_QUERY);
+        uno::Reference<text::XTextRange> xRange(xContent->getAnchor(), uno::UNO_QUERY);
+        CPPUNIT_ASSERT_EQUAL(OUString("Table caption"), xRange->getString());
+    }
+    {
+        uno::Reference<text::XTextContent> xContent(xBookmarksByName->getByName("Ref_Table0_number_only"), uno::UNO_QUERY);
+        uno::Reference<text::XTextRange> xRange(xContent->getAnchor(), uno::UNO_QUERY);
+        CPPUNIT_ASSERT_EQUAL(OUString("1"), xRange->getString());
+    }
+
+    // Check reference fields
+    uno::Reference<text::XTextFieldsSupplier> xTextFieldsSupplier(mxComponent, uno::UNO_QUERY);
+    uno::Reference<container::XEnumerationAccess> xFieldsAccess(xTextFieldsSupplier->getTextFields());
+    uno::Reference<container::XEnumeration> xFields(xFieldsAccess->createEnumeration());
+    CPPUNIT_ASSERT(xFields->hasMoreElements());
+
+    sal_uInt16 nIndex = 0;
+    while (xFields->hasMoreElements())
+    {
+        uno::Reference<lang::XServiceInfo> xServiceInfo(xFields->nextElement(), uno::UNO_QUERY);
+        uno::Reference<beans::XPropertySet> xPropertySet(xServiceInfo, uno::UNO_QUERY);
+        switch (nIndex)
+        {
+            // Full reference to table caption
+            case 0:
+            {
+                CPPUNIT_ASSERT(xServiceInfo->supportsService("com.sun.star.text.TextField.GetReference"));
+                OUString sValue;
+                sal_Int16 nValue;
+                xPropertySet->getPropertyValue("CurrentPresentation") >>= sValue;
+                CPPUNIT_ASSERT_EQUAL(OUString("Table 1: Table caption"), sValue);
+                xPropertySet->getPropertyValue("SourceName") >>= sValue;
+                CPPUNIT_ASSERT_EQUAL(OUString("Ref_Table0_full"), sValue);
+                xPropertySet->getPropertyValue("SequenceNumber") >>= nValue;
+                CPPUNIT_ASSERT_EQUAL(sal_Int16(0), nValue);
+                break;
+            }
+            // Page style reference / exported as simple page reference
+            case 1:
+            {
+                CPPUNIT_ASSERT(xServiceInfo->supportsService("com.sun.star.text.TextField.GetReference"));
+                OUString sValue;
+                sal_Int16 nValue;
+                xPropertySet->getPropertyValue("CurrentPresentation") >>= sValue;
+                CPPUNIT_ASSERT_EQUAL(OUString("1"), sValue);
+                xPropertySet->getPropertyValue("SourceName") >>= sValue;
+                CPPUNIT_ASSERT_EQUAL(OUString("Ref_Table0_full"), sValue);
+                xPropertySet->getPropertyValue("SequenceNumber") >>= nValue;
+                CPPUNIT_ASSERT_EQUAL(sal_Int16(0), nValue);
+                break;
+            }
+            // Reference to table number
+            case 2:
+            {
+                CPPUNIT_ASSERT(xServiceInfo->supportsService("com.sun.star.text.TextField.GetReference"));
+                OUString sValue;
+                sal_Int16 nValue;
+                xPropertySet->getPropertyValue("CurrentPresentation") >>= sValue;
+                CPPUNIT_ASSERT_EQUAL(OUString("1"), sValue);
+                xPropertySet->getPropertyValue("SourceName") >>= sValue;
+                CPPUNIT_ASSERT_EQUAL(OUString("Ref_Table0_number_only"), sValue);
+                xPropertySet->getPropertyValue("SequenceNumber") >>= nValue;
+                CPPUNIT_ASSERT_EQUAL(sal_Int16(0), nValue);
+                break;
+            }
+            // Reference to caption only
+            case 3:
+            {
+                CPPUNIT_ASSERT(xServiceInfo->supportsService("com.sun.star.text.TextField.GetReference"));
+                OUString sValue;
+                sal_Int16 nValue;
+                xPropertySet->getPropertyValue("CurrentPresentation") >>= sValue;
+                CPPUNIT_ASSERT_EQUAL(OUString("Table caption"), sValue);
+                xPropertySet->getPropertyValue("SourceName") >>= sValue;
+                CPPUNIT_ASSERT_EQUAL(OUString("Ref_Table0_caption_only"), sValue);
+                xPropertySet->getPropertyValue("SequenceNumber") >>= nValue;
+                CPPUNIT_ASSERT_EQUAL(sal_Int16(0), nValue);
+                break;
+            }
+            // Reference to category and number
+            case 4:
+            {
+                CPPUNIT_ASSERT(xServiceInfo->supportsService("com.sun.star.text.TextField.GetReference"));
+                OUString sValue;
+                sal_Int16 nValue;
+                xPropertySet->getPropertyValue("CurrentPresentation") >>= sValue;
+                CPPUNIT_ASSERT_EQUAL(OUString("Table 1"), sValue);
+                xPropertySet->getPropertyValue("SourceName") >>= sValue;
+                CPPUNIT_ASSERT_EQUAL(OUString("Ref_Table0_label_and_number"), sValue);
+                xPropertySet->getPropertyValue("SequenceNumber") >>= nValue;
+                CPPUNIT_ASSERT_EQUAL(sal_Int16(0), nValue);
+                break;
+            }
+            // Reference to page of the table
+            case 5:
+            {
+                CPPUNIT_ASSERT(xServiceInfo->supportsService("com.sun.star.text.TextField.GetReference"));
+                OUString sValue;
+                sal_Int16 nValue;
+                xPropertySet->getPropertyValue("CurrentPresentation") >>= sValue;
+                CPPUNIT_ASSERT_EQUAL(OUString("1"), sValue);
+                xPropertySet->getPropertyValue("SourceName") >>= sValue;
+                CPPUNIT_ASSERT_EQUAL(OUString("Ref_Table0_full"), sValue);
+                xPropertySet->getPropertyValue("SequenceNumber") >>= nValue;
+                CPPUNIT_ASSERT_EQUAL(sal_Int16(0), nValue);
+                break;
+            }
+            // Above / bellow reference
+            case 6:
+            {
+                CPPUNIT_ASSERT(xServiceInfo->supportsService("com.sun.star.text.TextField.GetReference"));
+                OUString sValue;
+                sal_Int16 nValue;
+                xPropertySet->getPropertyValue("CurrentPresentation") >>= sValue;
+                CPPUNIT_ASSERT_EQUAL(OUString("above"), sValue);
+                xPropertySet->getPropertyValue("SourceName") >>= sValue;
+                CPPUNIT_ASSERT_EQUAL(OUString("Ref_Table0_full"), sValue);
+                xPropertySet->getPropertyValue("SequenceNumber") >>= nValue;
+                CPPUNIT_ASSERT_EQUAL(sal_Int16(0), nValue);
+                break;
+            }
+            default:
+                break;
+        }
+        ++nIndex;
+    }
+}
+
+DECLARE_OOXMLEXPORT_TEST( testTableCrossReferenceCustomFormat, "table_cross_reference_custom_format.odt" )
+{
+    // tdf#42346: Cross references to tables were not saved
+    // Check also captions with custom formatting
+    if (!mbExported)
+        return;
+
+    // Check whether we have all the neccessary bookmarks exported and imported back
+    uno::Reference<text::XBookmarksSupplier> xBookmarksSupplier(mxComponent, uno::UNO_QUERY);
+    uno::Reference<container::XIndexAccess> xBookmarksByIdx(xBookmarksSupplier->getBookmarks(), uno::UNO_QUERY);
+    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(16), xBookmarksByIdx->getCount());
+    uno::Reference<container::XNameAccess> xBookmarksByName(xBookmarksSupplier->getBookmarks(), uno::UNO_QUERY);
+    CPPUNIT_ASSERT(xBookmarksByName->hasByName("Ref_Table0_full"));
+    CPPUNIT_ASSERT(xBookmarksByName->hasByName("Ref_Table0_label_and_number"));
+    CPPUNIT_ASSERT(xBookmarksByName->hasByName("Ref_Table0_caption_only"));
+    CPPUNIT_ASSERT(xBookmarksByName->hasByName("Ref_Table0_number_only"));
+    CPPUNIT_ASSERT(xBookmarksByName->hasByName("Ref_Table1_full"));
+    CPPUNIT_ASSERT(xBookmarksByName->hasByName("Ref_Table1_label_and_number"));
+    CPPUNIT_ASSERT(xBookmarksByName->hasByName("Ref_Table1_caption_only"));
+    CPPUNIT_ASSERT(xBookmarksByName->hasByName("Ref_Table1_number_only"));
+    CPPUNIT_ASSERT(xBookmarksByName->hasByName("Ref_Table2_full"));
+    CPPUNIT_ASSERT(xBookmarksByName->hasByName("Ref_Table2_label_and_number"));
+    CPPUNIT_ASSERT(xBookmarksByName->hasByName("Ref_Table2_caption_only"));
+    CPPUNIT_ASSERT(xBookmarksByName->hasByName("Ref_Table2_number_only"));
+    CPPUNIT_ASSERT(xBookmarksByName->hasByName("Ref_Table3_full"));
+    CPPUNIT_ASSERT(xBookmarksByName->hasByName("Ref_Table3_label_and_number"));
+    CPPUNIT_ASSERT(xBookmarksByName->hasByName("Ref_Table3_caption_only"));
+    CPPUNIT_ASSERT(xBookmarksByName->hasByName("Ref_Table3_number_only"));
+
+    // Check bookmark text ranges
+    // First table's caption
+    {
+        uno::Reference<text::XTextContent> xContent(xBookmarksByName->getByName("Ref_Table0_full"), uno::UNO_QUERY);
+        uno::Reference<text::XTextRange> xRange(xContent->getAnchor(), uno::UNO_QUERY);
+        CPPUNIT_ASSERT_EQUAL(OUString("1. Table: Table caption"), xRange->getString());
+    }
+    {
+        uno::Reference<text::XTextContent> xContent(xBookmarksByName->getByName("Ref_Table0_label_and_number"), uno::UNO_QUERY);
+        uno::Reference<text::XTextRange> xRange(xContent->getAnchor(), uno::UNO_QUERY);
+        CPPUNIT_ASSERT_EQUAL(OUString("1. Table"), xRange->getString());
+    }
+    {
+        uno::Reference<text::XTextContent> xContent(xBookmarksByName->getByName("Ref_Table0_caption_only"), uno::UNO_QUERY);
+        uno::Reference<text::XTextRange> xRange(xContent->getAnchor(), uno::UNO_QUERY);
+        CPPUNIT_ASSERT_EQUAL(OUString("Table caption"), xRange->getString());
+    }
+    {
+        uno::Reference<text::XTextContent> xContent(xBookmarksByName->getByName("Ref_Table0_number_only"), uno::UNO_QUERY);
+        uno::Reference<text::XTextRange> xRange(xContent->getAnchor(), uno::UNO_QUERY);
+        CPPUNIT_ASSERT_EQUAL(OUString("1"), xRange->getString());
+    }
+    // Second table's caption
+    {
+        uno::Reference<text::XTextContent> xContent(xBookmarksByName->getByName("Ref_Table1_full"), uno::UNO_QUERY);
+        uno::Reference<text::XTextRange> xRange(xContent->getAnchor(), uno::UNO_QUERY);
+        CPPUNIT_ASSERT_EQUAL(OUString("2. TableTable caption"), xRange->getString());
+    }
+    {
+        uno::Reference<text::XTextContent> xContent(xBookmarksByName->getByName("Ref_Table1_label_and_number"), uno::UNO_QUERY);
+        uno::Reference<text::XTextRange> xRange(xContent->getAnchor(), uno::UNO_QUERY);
+        CPPUNIT_ASSERT_EQUAL(OUString("2. Table"), xRange->getString());
+    }
+    {
+        uno::Reference<text::XTextContent> xContent(xBookmarksByName->getByName("Ref_Table1_caption_only"), uno::UNO_QUERY);
+        uno::Reference<text::XTextRange> xRange(xContent->getAnchor(), uno::UNO_QUERY);
+        CPPUNIT_ASSERT_EQUAL(OUString("Table caption"), xRange->getString());
+    }
+    {
+        uno::Reference<text::XTextContent> xContent(xBookmarksByName->getByName("Ref_Table1_number_only"), uno::UNO_QUERY);
+        uno::Reference<text::XTextRange> xRange(xContent->getAnchor(), uno::UNO_QUERY);
+        CPPUNIT_ASSERT_EQUAL(OUString("2"), xRange->getString());
+    }
+    // Third table's caption
+    {
+        uno::Reference<text::XTextContent> xContent(xBookmarksByName->getByName("Ref_Table2_full"), uno::UNO_QUERY);
+        uno::Reference<text::XTextRange> xRange(xContent->getAnchor(), uno::UNO_QUERY);
+        CPPUNIT_ASSERT_EQUAL(OUString("3) Table Table caption"), xRange->getString());
+    }
+    {
+        uno::Reference<text::XTextContent> xContent(xBookmarksByName->getByName("Ref_Table2_label_and_number"), uno::UNO_QUERY);
+        uno::Reference<text::XTextRange> xRange(xContent->getAnchor(), uno::UNO_QUERY);
+        CPPUNIT_ASSERT_EQUAL(OUString("3) Table"), xRange->getString());
+    }
+    {
+        uno::Reference<text::XTextContent> xContent(xBookmarksByName->getByName("Ref_Table2_caption_only"), uno::UNO_QUERY);
+        uno::Reference<text::XTextRange> xRange(xContent->getAnchor(), uno::UNO_QUERY);
+        CPPUNIT_ASSERT_EQUAL(OUString("Table caption"), xRange->getString());
+    }
+    {
+        uno::Reference<text::XTextContent> xContent(xBookmarksByName->getByName("Ref_Table2_number_only"), uno::UNO_QUERY);
+        uno::Reference<text::XTextRange> xRange(xContent->getAnchor(), uno::UNO_QUERY);
+        CPPUNIT_ASSERT_EQUAL(OUString("3"), xRange->getString());
+    }
+    // Fourth table's caption
+    {
+        uno::Reference<text::XTextContent> xContent(xBookmarksByName->getByName("Ref_Table3_full"), uno::UNO_QUERY);
+        uno::Reference<text::XTextRange> xRange(xContent->getAnchor(), uno::UNO_QUERY);
+        CPPUNIT_ASSERT_EQUAL(OUString("Table 4- Table caption"), xRange->getString());
+    }
+    {
+        uno::Reference<text::XTextContent> xContent(xBookmarksByName->getByName("Ref_Table3_label_and_number"), uno::UNO_QUERY);
+        uno::Reference<text::XTextRange> xRange(xContent->getAnchor(), uno::UNO_QUERY);
+        CPPUNIT_ASSERT_EQUAL(OUString("Table 4"), xRange->getString());
+    }
+    {
+        uno::Reference<text::XTextContent> xContent(xBookmarksByName->getByName("Ref_Table3_caption_only"), uno::UNO_QUERY);
+        uno::Reference<text::XTextRange> xRange(xContent->getAnchor(), uno::UNO_QUERY);
+        CPPUNIT_ASSERT_EQUAL(OUString("Table caption"), xRange->getString());
+    }
+    {
+        uno::Reference<text::XTextContent> xContent(xBookmarksByName->getByName("Ref_Table3_number_only"), uno::UNO_QUERY);
+        uno::Reference<text::XTextRange> xRange(xContent->getAnchor(), uno::UNO_QUERY);
+        CPPUNIT_ASSERT_EQUAL(OUString("4"), xRange->getString());
+    }
+}
+
+DECLARE_OOXMLEXPORT_TEST( testObjectCrossReference, "object_cross_reference.odt" )
+{
+    // tdf#42346: Cross references to objects were not saved
+    // MSO uses simple bookmarks for referencing table caption, so we do the same by export
+    if (!mbExported)
+        return;
+
+    // Check whether we have all the neccessary bookmarks exported and imported back
+    uno::Reference<text::XBookmarksSupplier> xBookmarksSupplier(mxComponent, uno::UNO_QUERY);
+    uno::Reference<container::XIndexAccess> xBookmarksByIdx(xBookmarksSupplier->getBookmarks(), uno::UNO_QUERY);
+    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(15), xBookmarksByIdx->getCount());
+    uno::Reference<container::XNameAccess> xBookmarksByName(xBookmarksSupplier->getBookmarks(), uno::UNO_QUERY);
+    CPPUNIT_ASSERT(xBookmarksByName->hasByName("Ref_Drawing0_full"));
+    CPPUNIT_ASSERT(xBookmarksByName->hasByName("Ref_Drawing0_label_and_number"));
+    CPPUNIT_ASSERT(xBookmarksByName->hasByName("Ref_Drawing0_caption_only"));
+    CPPUNIT_ASSERT(xBookmarksByName->hasByName("Ref_Drawing0_number_only"));
+    CPPUNIT_ASSERT(xBookmarksByName->hasByName("Ref_Drawing1_full"));
+
+    CPPUNIT_ASSERT(xBookmarksByName->hasByName("Ref_Illustration0_full"));
+    CPPUNIT_ASSERT(xBookmarksByName->hasByName("Ref_Illustration0_label_and_number"));
+    CPPUNIT_ASSERT(xBookmarksByName->hasByName("Ref_Illustration0_caption_only"));
+    CPPUNIT_ASSERT(xBookmarksByName->hasByName("Ref_Illustration0_number_only"));
+    CPPUNIT_ASSERT(xBookmarksByName->hasByName("Ref_Illustration1_caption_only"));
+
+    CPPUNIT_ASSERT(xBookmarksByName->hasByName("Ref_Text0_full"));
+    CPPUNIT_ASSERT(xBookmarksByName->hasByName("Ref_Text0_label_and_number"));
+    CPPUNIT_ASSERT(xBookmarksByName->hasByName("Ref_Text0_caption_only"));
+    CPPUNIT_ASSERT(xBookmarksByName->hasByName("Ref_Text0_number_only"));
+    CPPUNIT_ASSERT(xBookmarksByName->hasByName("Ref_Text1_label_and_number"));
+
+    // Check bookmark text ranges
+    // Cross references to shapes
+    {
+        uno::Reference<text::XTextContent> xContent(xBookmarksByName->getByName("Ref_Drawing0_full"), uno::UNO_QUERY);
+        uno::Reference<text::XTextRange> xRange(xContent->getAnchor(), uno::UNO_QUERY);
+        CPPUNIT_ASSERT_EQUAL(OUString("Drawing 1: A rectangle"), xRange->getString());
+    }
+    {
+        uno::Reference<text::XTextContent> xContent(xBookmarksByName->getByName("Ref_Drawing0_label_and_number"), uno::UNO_QUERY);
+        uno::Reference<text::XTextRange> xRange(xContent->getAnchor(), uno::UNO_QUERY);
+        CPPUNIT_ASSERT_EQUAL(OUString("Drawing 1"), xRange->getString());
+    }
+    {
+        uno::Reference<text::XTextContent> xContent(xBookmarksByName->getByName("Ref_Drawing0_caption_only"), uno::UNO_QUERY);
+        uno::Reference<text::XTextRange> xRange(xContent->getAnchor(), uno::UNO_QUERY);
+        CPPUNIT_ASSERT_EQUAL(OUString("A rectangle"), xRange->getString());
+    }
+    {
+        uno::Reference<text::XTextContent> xContent(xBookmarksByName->getByName("Ref_Drawing0_number_only"), uno::UNO_QUERY);
+        uno::Reference<text::XTextRange> xRange(xContent->getAnchor(), uno::UNO_QUERY);
+        CPPUNIT_ASSERT_EQUAL(OUString("1"), xRange->getString());
+    }
+    {
+        uno::Reference<text::XTextContent> xContent(xBookmarksByName->getByName("Ref_Drawing1_full"), uno::UNO_QUERY);
+        uno::Reference<text::XTextRange> xRange(xContent->getAnchor(), uno::UNO_QUERY);
+        CPPUNIT_ASSERT_EQUAL(OUString("Drawing 2: a circle"), xRange->getString());
+    }
+
+    // Cross references to pictures
+    {
+        uno::Reference<text::XTextContent> xContent(xBookmarksByName->getByName("Ref_Illustration0_full"), uno::UNO_QUERY);
+        uno::Reference<text::XTextRange> xRange(xContent->getAnchor(), uno::UNO_QUERY);
+        CPPUNIT_ASSERT_EQUAL(OUString("Illustration 1: A picture"), xRange->getString());
+    }
+    {
+        uno::Reference<text::XTextContent> xContent(xBookmarksByName->getByName("Ref_Illustration0_label_and_number"), uno::UNO_QUERY);
+        uno::Reference<text::XTextRange> xRange(xContent->getAnchor(), uno::UNO_QUERY);
+        CPPUNIT_ASSERT_EQUAL(OUString("Illustration 1"), xRange->getString());
+    }
+    {
+        uno::Reference<text::XTextContent> xContent(xBookmarksByName->getByName("Ref_Illustration0_caption_only"), uno::UNO_QUERY);
+        uno::Reference<text::XTextRange> xRange(xContent->getAnchor(), uno::UNO_QUERY);
+        CPPUNIT_ASSERT_EQUAL(OUString("A picture"), xRange->getString());
+    }
+    {
+        uno::Reference<text::XTextContent> xContent(xBookmarksByName->getByName("Ref_Illustration0_number_only"), uno::UNO_QUERY);
+        uno::Reference<text::XTextRange> xRange(xContent->getAnchor(), uno::UNO_QUERY);
+        CPPUNIT_ASSERT_EQUAL(OUString("1"), xRange->getString());
+    }
+    {
+        uno::Reference<text::XTextContent> xContent(xBookmarksByName->getByName("Ref_Illustration1_caption_only"), uno::UNO_QUERY);
+        uno::Reference<text::XTextRange> xRange(xContent->getAnchor(), uno::UNO_QUERY);
+        CPPUNIT_ASSERT_EQUAL(OUString("an other image"), xRange->getString());
+    }
+
+    // Cross references to text frames
+    {
+        uno::Reference<text::XTextContent> xContent(xBookmarksByName->getByName("Ref_Text0_full"), uno::UNO_QUERY);
+        uno::Reference<text::XTextRange> xRange(xContent->getAnchor(), uno::UNO_QUERY);
+        CPPUNIT_ASSERT_EQUAL(OUString("Text 1: A frame"), xRange->getString());
+    }
+    {
+        uno::Reference<text::XTextContent> xContent(xBookmarksByName->getByName("Ref_Text0_label_and_number"), uno::UNO_QUERY);
+        uno::Reference<text::XTextRange> xRange(xContent->getAnchor(), uno::UNO_QUERY);
+        CPPUNIT_ASSERT_EQUAL(OUString("Text 1"), xRange->getString());
+    }
+    {
+        uno::Reference<text::XTextContent> xContent(xBookmarksByName->getByName("Ref_Text0_caption_only"), uno::UNO_QUERY);
+        uno::Reference<text::XTextRange> xRange(xContent->getAnchor(), uno::UNO_QUERY);
+        CPPUNIT_ASSERT_EQUAL(OUString("A frame"), xRange->getString());
+    }
+    {
+        uno::Reference<text::XTextContent> xContent(xBookmarksByName->getByName("Ref_Text0_number_only"), uno::UNO_QUERY);
+        uno::Reference<text::XTextRange> xRange(xContent->getAnchor(), uno::UNO_QUERY);
+        CPPUNIT_ASSERT_EQUAL(OUString("1"), xRange->getString());
+    }
+    {
+        uno::Reference<text::XTextContent> xContent(xBookmarksByName->getByName("Ref_Text1_label_and_number"), uno::UNO_QUERY);
+        uno::Reference<text::XTextRange> xRange(xContent->getAnchor(), uno::UNO_QUERY);
+        CPPUNIT_ASSERT_EQUAL(OUString("Text 2"), xRange->getString());
+    }
+
+    // Check reference fields
+    uno::Reference<text::XTextFieldsSupplier> xTextFieldsSupplier(mxComponent, uno::UNO_QUERY);
+    uno::Reference<container::XEnumerationAccess> xFieldsAccess(xTextFieldsSupplier->getTextFields());
+    uno::Reference<container::XEnumeration> xFields(xFieldsAccess->createEnumeration());
+    CPPUNIT_ASSERT(xFields->hasMoreElements());
+
+    sal_uInt16 nIndex = 0;
+    while (xFields->hasMoreElements())
+    {
+        uno::Reference<lang::XServiceInfo> xServiceInfo(xFields->nextElement(), uno::UNO_QUERY);
+        uno::Reference<beans::XPropertySet> xPropertySet(xServiceInfo, uno::UNO_QUERY);
+        switch (nIndex)
+        {
+            // Reference to image number
+            case 0:
+            {
+                CPPUNIT_ASSERT(xServiceInfo->supportsService("com.sun.star.text.TextField.GetReference"));
+                OUString sValue;
+                xPropertySet->getPropertyValue("CurrentPresentation") >>= sValue;
+                CPPUNIT_ASSERT_EQUAL(OUString("1"), sValue);
+                xPropertySet->getPropertyValue("SourceName") >>= sValue;
+                CPPUNIT_ASSERT_EQUAL(OUString("Ref_Illustration0_number_only"), sValue);
+                break;
+            }
+            // Full reference to the circle shape
+            case 1:
+            {
+                CPPUNIT_ASSERT(xServiceInfo->supportsService("com.sun.star.text.TextField.GetReference"));
+                OUString sValue;
+                xPropertySet->getPropertyValue("CurrentPresentation") >>= sValue;
+                CPPUNIT_ASSERT_EQUAL(OUString("Drawing 2: a circle"), sValue);
+                xPropertySet->getPropertyValue("SourceName") >>= sValue;
+                CPPUNIT_ASSERT_EQUAL(OUString("Ref_Drawing1_full"), sValue);
+                break;
+            }
+            // Caption only reference to the second picture
+            case 2:
+            {
+                CPPUNIT_ASSERT(xServiceInfo->supportsService("com.sun.star.text.TextField.GetReference"));
+                OUString sValue;
+                xPropertySet->getPropertyValue("CurrentPresentation") >>= sValue;
+                CPPUNIT_ASSERT_EQUAL(OUString("an other image"), sValue);
+                xPropertySet->getPropertyValue("SourceName") >>= sValue;
+                CPPUNIT_ASSERT_EQUAL(OUString("Ref_Illustration1_caption_only"), sValue);
+                break;
+            }
+            // Category and number reference to second text frame
+            case 3:
+            {
+                CPPUNIT_ASSERT(xServiceInfo->supportsService("com.sun.star.text.TextField.GetReference"));
+                OUString sValue;
+                xPropertySet->getPropertyValue("CurrentPresentation") >>= sValue;
+                CPPUNIT_ASSERT_EQUAL(OUString("Text 2"), sValue);
+                xPropertySet->getPropertyValue("SourceName") >>= sValue;
+                CPPUNIT_ASSERT_EQUAL(OUString("Ref_Text1_label_and_number"), sValue);
+                break;
+            }
+            // Full reference to rectangle shape
+            case 4:
+            {
+                CPPUNIT_ASSERT(xServiceInfo->supportsService("com.sun.star.text.TextField.GetReference"));
+                OUString sValue;
+                xPropertySet->getPropertyValue("CurrentPresentation") >>= sValue;
+                CPPUNIT_ASSERT_EQUAL(OUString("Drawing 1: A rectangle"), sValue);
+                xPropertySet->getPropertyValue("SourceName") >>= sValue;
+                CPPUNIT_ASSERT_EQUAL(OUString("Ref_Drawing0_full"), sValue);
+                break;
+            }
+            // Caption only reference to rectangle shape
+            case 5:
+            {
+                CPPUNIT_ASSERT(xServiceInfo->supportsService("com.sun.star.text.TextField.GetReference"));
+                OUString sValue;
+                xPropertySet->getPropertyValue("CurrentPresentation") >>= sValue;
+                CPPUNIT_ASSERT_EQUAL(OUString("A rectangle"), sValue);
+                xPropertySet->getPropertyValue("SourceName") >>= sValue;
+                CPPUNIT_ASSERT_EQUAL(OUString("Ref_Drawing0_caption_only"), sValue);
+                break;
+            }
+            // Category and number reference to rectangle shape
+            case 6:
+            {
+                CPPUNIT_ASSERT(xServiceInfo->supportsService("com.sun.star.text.TextField.GetReference"));
+                OUString sValue;
+                xPropertySet->getPropertyValue("CurrentPresentation") >>= sValue;
+                CPPUNIT_ASSERT_EQUAL(OUString("Drawing 1"), sValue);
+                xPropertySet->getPropertyValue("SourceName") >>= sValue;
+                CPPUNIT_ASSERT_EQUAL(OUString("Ref_Drawing0_label_and_number"), sValue);
+                break;
+            }
+            // Reference to rectangle shape's number
+            case 7:
+            {
+                CPPUNIT_ASSERT(xServiceInfo->supportsService("com.sun.star.text.TextField.GetReference"));
+                OUString sValue;
+                xPropertySet->getPropertyValue("CurrentPresentation") >>= sValue;
+                CPPUNIT_ASSERT_EQUAL(OUString("1"), sValue);
+                xPropertySet->getPropertyValue("SourceName") >>= sValue;
+                CPPUNIT_ASSERT_EQUAL(OUString("Ref_Drawing0_number_only"), sValue);
+                break;
+            }
+            // Full reference to first text frame
+            case 8:
+            {
+                CPPUNIT_ASSERT(xServiceInfo->supportsService("com.sun.star.text.TextField.GetReference"));
+                OUString sValue;
+                xPropertySet->getPropertyValue("CurrentPresentation") >>= sValue;
+                CPPUNIT_ASSERT_EQUAL(OUString("Text 1: A frame"), sValue);
+                xPropertySet->getPropertyValue("SourceName") >>= sValue;
+                CPPUNIT_ASSERT_EQUAL(OUString("Ref_Text0_full"), sValue);
+                break;
+            }
+            // Caption only reference to first text frame
+            case 9:
+            {
+                CPPUNIT_ASSERT(xServiceInfo->supportsService("com.sun.star.text.TextField.GetReference"));
+                OUString sValue;
+                xPropertySet->getPropertyValue("CurrentPresentation") >>= sValue;
+                CPPUNIT_ASSERT_EQUAL(OUString("A frame"), sValue);
+                xPropertySet->getPropertyValue("SourceName") >>= sValue;
+                CPPUNIT_ASSERT_EQUAL(OUString("Ref_Text0_caption_only"), sValue);
+                break;
+            }
+            // Category and number reference to first text frame
+            case 10:
+            {
+                CPPUNIT_ASSERT(xServiceInfo->supportsService("com.sun.star.text.TextField.GetReference"));
+                OUString sValue;
+                xPropertySet->getPropertyValue("CurrentPresentation") >>= sValue;
+                CPPUNIT_ASSERT_EQUAL(OUString("Text 1"), sValue);
+                xPropertySet->getPropertyValue("SourceName") >>= sValue;
+                CPPUNIT_ASSERT_EQUAL(OUString("Ref_Text0_label_and_number"), sValue);
+                break;
+            }
+            // Number only reference to first text frame
+            case 11:
+            {
+                CPPUNIT_ASSERT(xServiceInfo->supportsService("com.sun.star.text.TextField.GetReference"));
+                OUString sValue;
+                xPropertySet->getPropertyValue("CurrentPresentation") >>= sValue;
+                CPPUNIT_ASSERT_EQUAL(OUString("1"), sValue);
+                xPropertySet->getPropertyValue("SourceName") >>= sValue;
+                CPPUNIT_ASSERT_EQUAL(OUString("Ref_Text0_number_only"), sValue);
+                break;
+            }
+            // Full reference to first picture
+            case 12:
+            {
+                CPPUNIT_ASSERT(xServiceInfo->supportsService("com.sun.star.text.TextField.GetReference"));
+                OUString sValue;
+                xPropertySet->getPropertyValue("CurrentPresentation") >>= sValue;
+                CPPUNIT_ASSERT_EQUAL(OUString("Illustration 1: A picture"), sValue.trim()); // failes on MAC without trim
+                xPropertySet->getPropertyValue("SourceName") >>= sValue;
+                CPPUNIT_ASSERT_EQUAL(OUString("Ref_Illustration0_full"), sValue);
+                break;
+            }
+            // Reference to first picture' caption
+            case 13:
+            {
+                CPPUNIT_ASSERT(xServiceInfo->supportsService("com.sun.star.text.TextField.GetReference"));
+                OUString sValue;
+                xPropertySet->getPropertyValue("CurrentPresentation") >>= sValue;
+                CPPUNIT_ASSERT_EQUAL(OUString("A picture"), sValue);
+                xPropertySet->getPropertyValue("SourceName") >>= sValue;
+                CPPUNIT_ASSERT_EQUAL(OUString("Ref_Illustration0_caption_only"), sValue);
+                break;
+            }
+            // Category and number reference to first picture
+            case 14:
+            {
+                CPPUNIT_ASSERT(xServiceInfo->supportsService("com.sun.star.text.TextField.GetReference"));
+                OUString sValue;
+                xPropertySet->getPropertyValue("CurrentPresentation") >>= sValue;
+                CPPUNIT_ASSERT_EQUAL(OUString("Illustration 1"), sValue);
+                xPropertySet->getPropertyValue("SourceName") >>= sValue;
+                CPPUNIT_ASSERT_EQUAL(OUString("Ref_Illustration0_label_and_number"), sValue);
+                break;
+            }
+            default:
+                break;
+        }
+        ++nIndex;
+    }
+}
+
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/filter/ww8/attributeoutputbase.hxx b/sw/source/filter/ww8/attributeoutputbase.hxx
index 6e8c0ca0bb26..dc32dd36d8fe 100644
--- a/sw/source/filter/ww8/attributeoutputbase.hxx
+++ b/sw/source/filter/ww8/attributeoutputbase.hxx
@@ -209,6 +209,8 @@ public:
 
     virtual void FieldVanish( const OUString& rText, ww::eField eType ) = 0;
 
+    virtual void GenerateBookmarksForSequenceField(const SwTextNode& rNode, SwWW8AttrIter& rAttrIter) = 0;
+
     void StartTOX( const SwSection& rSect );
 
     void EndTOX( const SwSection& rSect,bool bCareEnd=true );
diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx
index 45c5ed84cbd3..467177d013fa 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -117,6 +117,8 @@
 #include <IDocumentSettingAccess.hxx>
 #include <IDocumentStylePoolAccess.hxx>
 #include <IDocumentRedlineAccess.hxx>
+#include <IDocumentFieldsAccess.hxx>
+#include <reffld.hxx>
 
 #include <osl/file.hxx>
 #include <vcl/embeddedfontshelper.hxx>
@@ -601,6 +603,10 @@ void DocxAttributeOutput::EndParagraph( ww8::WW8TableNodeInfoInner::Pointer_t pT
     if( !m_rExport.SdrExporter().IsDMLAndVMLDrawingOpen() )
         m_bParagraphOpened = false;
 
+    // Clear gererated bookmarks
+    m_aBookmarksWithPosStart.clear();
+    m_aBookmarksWithPosEnd.clear();
+
 }
 
 void DocxAttributeOutput::WriteSdtBlock( sal_Int32& nSdtPrToken,
@@ -1267,6 +1273,8 @@ void DocxAttributeOutput::EndRun(const SwTextNode* pNode, sal_Int32 nPos)
         m_endPageRef = true;
     }
 
+    DoWriteBookmarkStartIfExist(nPos);
+
     m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
     if(GetExport().m_bTabInTOC && m_pHyperlinkAttrList.is())
     {
@@ -1364,6 +1372,8 @@ void DocxAttributeOutput::EndRun(const SwTextNode* pNode, sal_Int32 nPos)
         }
         m_nFieldsInHyperlink = 0;
     }
+
+    DoWriteBookmarkEndIfExist(nPos);
 }
 
 void DocxAttributeOutput::DoWriteBookmarkTagStart(const OUString & bookmarkName)
@@ -1391,6 +1401,34 @@ void DocxAttributeOutput::DoWriteBookmarkTagEnd(const OUString & bookmarkName)
     }
 }
 
+void DocxAttributeOutput::DoWriteBookmarkStartIfExist(sal_Int32 nPos)
+{
+    auto aRange = m_aBookmarksWithPosStart.equal_range(nPos);
+    for( auto aIter = aRange.first; aIter != aRange.second; ++aIter)
+    {
+        DoWriteBookmarkTagStart(aIter->second);
+        m_rOpenedBookmarksIds[aIter->second] = m_nNextBookmarkId;
+        m_sLastOpenedBookmark = OUStringToOString(BookmarkToWord(aIter->second), RTL_TEXTENCODING_UTF8).getStr();
+        m_nNextBookmarkId++;
+    }
+}
+
+void DocxAttributeOutput::DoWriteBookmarkEndIfExist(sal_Int32 nPos)
+{
+    auto aRange = m_aBookmarksWithPosEnd.equal_range(nPos);
+    for( auto aIter = aRange.first; aIter != aRange.second; ++aIter)
+    {
+        // Get the id of the bookmark
+        auto pPos = m_rOpenedBookmarksIds.find(aIter->second);
+        if (pPos != m_rOpenedBookmarksIds.end())
+        {
+            // Output the bookmark
+            DoWriteBookmarkTagEnd(aIter->second);
+            m_rOpenedBookmarksIds.erase(aIter->second);
+        }
+    }
+}
+
 /// Write the start bookmarks
 void DocxAttributeOutput::DoWriteBookmarksStart()
 {
@@ -1655,7 +1693,7 @@ void DocxAttributeOutput::StartField_Impl( const SwTextNode* pNode, sal_Int32 nP
         else
         {
             // Write the field start
-            if ( rInfos.pField && rInfos.pField->GetSubType() & FIXEDFLD )
+            if ( rInfos.pField && (rInfos.pField->Which() == RES_DATETIMEFLD) && rInfos.pField->GetSubType() & FIXEDFLD )
             {
                 m_pSerializer->startElementNS( XML_w, XML_fldChar,
                     FSNS( XML_w, XML_fldCharType ), "begin",
@@ -6509,7 +6547,7 @@ void DocxAttributeOutput::CharFont( const SvxFontItem& rFont)
     const OString sFontNameUtf8 = OUStringToOString(sFontName, RTL_TEXTENCODING_UTF8);
     if (!sFontNameUtf8.isEmpty())
     {
-        if (m_pFontsAttrList &&
+        if (m_pFontsAttrList.is() &&
             (   m_pFontsAttrList->hasAttribute(FSNS( XML_w, XML_ascii )) ||
                 m_pFontsAttrList->hasAttribute(FSNS( XML_w, XML_hAnsi ))    )
             )
@@ -6934,6 +6972,176 @@ bool DocxAttributeOutput::PlaceholderField( const SwField* pField )
     return false; // do not expand
 }
 
+void DocxAttributeOutput::GenerateBookmarksForSequenceField(const SwTextNode& rNode, SwWW8AttrIter& rAttrIter)
+{
+    if (const SwpHints* pTextAttrs = rNode.GetpSwpHints())
+    {
+        for( size_t i = 0; i < pTextAttrs->Count(); ++i )
+        {
+            const SwTextAttr* pHt = pTextAttrs->Get(i);
+            if (pHt->GetAttr().Which() == RES_TXTATR_FIELD)
+            {
+                const SwFormatField& rField = static_cast<const SwFormatField&>(pHt->GetAttr());
+                const SwField* pField = rField.GetField();
+                // Need to have bookmarks only for sequence fields
+                if (pField && pField->GetTyp()->Which() == RES_SETEXPFLD && pField->GetSubType() == nsSwGetSetExpType::GSE_SEQ)
+                {
+                    const sal_uInt16 nSeqFieldNumber = static_cast<const SwSetExpField*>(pField)->GetSeqNumber();
+                    const OUString sObjectName = static_cast<const SwSetExpFieldType*>(pField->GetTyp())->GetName();
+                    const SwFieldTypes* pFieldTypes = m_rExport.m_pDoc->getIDocumentFieldsAccess().GetFieldTypes();
+                    bool bHaveFullBkm = false;
+                    bool bHaveLabelAndNumberBkm = false;
+                    bool bHaveCaptionOnlyBkm = false;
+                    bool bHaveNumberOnlyBkm = false;
+                    bool bRunSplittedAtSep = false;
+                    for( auto pFieldType : *pFieldTypes )
+                    {
+                        if( RES_GETREFFLD == pFieldType->Which() )
+                        {
+                            SwIterator<SwFormatField,SwFieldType> aIter( *pFieldType );
+                            for( SwFormatField* pFormatField = aIter.First(); pFormatField; pFormatField = aIter.Next() )
+                            {
+                                SwGetRefField* pRefField = static_cast<SwGetRefField*>(pFormatField->GetField());
+                                // If we have a reference to the current sequence field
+                                if(pRefField->GetSeqNo() == nSeqFieldNumber && pRefField->GetSetRefName() == sObjectName)
+                                {
+                                    // Need to create a seperate run for separator character
+                                    SwWW8AttrIter aLocalAttrIter( m_rExport, rNode );
+                                    const OUString aText = rNode.GetText();
+                                    const sal_Int32 nCategoryStart = aText.indexOf(pRefField->GetSetRefName());
+                                    const sal_Int32 nPosBeforeSeparator = std::max(nCategoryStart, pHt->GetStart());
+                                    bool bCategoryFirst = nCategoryStart < pHt->GetStart();
+                                    sal_Int32 nSeparatorPos = 0;
+                                    if (bCategoryFirst)
+                                    {
+                                        nSeparatorPos = aLocalAttrIter.WhereNext();
+                                        while (nSeparatorPos <= nPosBeforeSeparator)
+                                        {
+                                            aLocalAttrIter.NextPos();
+                                            nSeparatorPos = aLocalAttrIter.WhereNext();
+                                        }
+                                    }
+                                    else
+                                    {
+                                        nSeparatorPos = nCategoryStart + pRefField->GetSetRefName().getLength();
+                                    }
+                                    sal_Int32 nRefTextPos = 0;
+                                    if(nSeparatorPos < aText.getLength())
+                                    {
+                                        nRefTextPos = SwGetExpField::GetReferenceTextPos(pHt->GetFormatField(), *m_rExport.m_pDoc, nSeparatorPos);
+                                        if(nRefTextPos != nSeparatorPos)
+                                        {
+                                            if(!bRunSplittedAtSep)
+                                            {
+                                                if(!bCategoryFirst)
+                                                    rAttrIter.SplitRun(nSeparatorPos);
+                                                rAttrIter.SplitRun(nRefTextPos);
+                                                bRunSplittedAtSep = true;
+                                            }
+                                            if(!bCategoryFirst)
+                                                aLocalAttrIter.SplitRun(nSeparatorPos);
+                                            aLocalAttrIter.SplitRun(nRefTextPos);
+                                        }
+                                        else if (bCategoryFirst)
+                                        {
+                                            if(!bRunSplittedAtSep)
+                                            {
+                                                rAttrIter.SplitRun(nSeparatorPos);
+                                                bRunSplittedAtSep = true;
+                                            }
+                                            aLocalAttrIter.SplitRun(nSeparatorPos);
+                                        }
+                                    }
+                                    // Generate bookmarks on the right position
+                                    OUString sName("Ref_" + pRefField->GetSetRefName());
+                                    sName += OUString::number(pRefField->GetSeqNo());
+                                    switch (pRefField->GetFormat())
+                                    {
+                                        case REF_PAGE:
+                                        case REF_PAGE_PGDESC:
+                                        case REF_CONTENT:
+                                        case REF_UPDOWN:
+                                            sName += "_full";
+                                            if(!bHaveFullBkm)
+                                            {
+                                                sal_Int32 nLastAttrStart = 0;
+                                                sal_Int32 nActAttr = aLocalAttrIter.WhereNext();
+                                                while (nActAttr < rNode.GetText().getLength())
+                                                {
+                                                    nLastAttrStart = nActAttr;
+                                                    aLocalAttrIter.NextPos();
+                                                    nActAttr = aLocalAttrIter.WhereNext();
+                                                }
+                                                WriteBookmarks_Impl( sName, std::min(nCategoryStart, pHt->GetStart()), nLastAttrStart );
+                                                bHaveFullBkm = true;
+                                            }
+                                            break;
+                                        case REF_ONLYNUMBER:
+                                        {
+                                            sName += "_label_and_number";
+                                            if(!bHaveLabelAndNumberBkm)
+                                            {
+                                                if(bCategoryFirst)
+                                                    WriteBookmarks_Impl( sName, std::min(nCategoryStart, pHt->GetStart()), std::max(nCategoryStart, pHt->GetStart()) );
+                                                else
+                                                {
+                                                    // Find the last run which contains category text
+                                                    SwWW8AttrIter aLocalAttrIter2( m_rExport, rNode );
+                                                    sal_Int32 nCatLastRun = 0;
+                                                    sal_Int32 nNextAttr = aLocalAttrIter2.WhereNext();
+                                                    while (nNextAttr < nSeparatorPos)
+                                                    {
+                                                        nCatLastRun = nNextAttr;
+                                                        aLocalAttrIter2.NextPos();
+                                                        nNextAttr = aLocalAttrIter2.WhereNext();
+                                                    }
+                                                    WriteBookmarks_Impl( sName, pHt->GetStart(), nCatLastRun );
+                                                }
+                                                bHaveLabelAndNumberBkm = true;
+                                            }
+                                            break;
+                                        }
+                                        case REF_ONLYCAPTION:
+                                        {
+                                            sName += "_caption_only";
+                                            if(!bHaveCaptionOnlyBkm)
+                                            {
+                                                // Find last run
+                                                sal_Int32 nLastAttrStart = 0;
+                                                sal_Int32 nActAttr = aLocalAttrIter.WhereNext();
+                                                while (nActAttr < rNode.GetText().getLength())
+                                                {
+                                                    nLastAttrStart = nActAttr;
+                                                    aLocalAttrIter.NextPos();
+                                                    nActAttr = aLocalAttrIter.WhereNext();
+                                                }
+                                                WriteBookmarks_Impl( sName, nRefTextPos, nLastAttrStart );
+                                                bHaveCaptionOnlyBkm = true;
+                                            }
+                                            break;
+                                        }
+                                        case REF_ONLYSEQNO:
+                                        {
+                                            sName += "_number_only";
+                                            if(!bHaveNumberOnlyBkm)
+                                            {
+                                                WriteBookmarks_Impl( sName, pHt->GetStart(), pHt->GetStart() );
+                                                bHaveNumberOnlyBkm = true;
+                                            }
+                                            break;
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                    return;
+                }
+            }
+        }
+    }
+}
+
 void DocxAttributeOutput::WritePendingPlaceholder()
 {
     if( pendingPlaceholder == nullptr )
@@ -7040,6 +7248,12 @@ void DocxAttributeOutput::WriteBookmarks_Impl( std::vector< OUString >& rStarts,
     rEnds.clear();
 }
 
+void DocxAttributeOutput::WriteBookmarks_Impl( const OUString& rName, sal_Int32 nWithStartPos, sal_Int32 nWithEndPos )
+{
+    m_aBookmarksWithPosStart.insert(std::pair<sal_Int32, OUString>(nWithStartPos, rName));
+    m_aBookmarksWithPosEnd.insert(std::pair<sal_Int32, OUString>(nWithEndPos, rName));
+}
+
 void DocxAttributeOutput::WriteAnnotationMarks_Impl( std::vector< OUString >& rStarts,
         std::vector< OUString >& rEnds )
 {
diff --git a/sw/source/filter/ww8/docxattributeoutput.hxx b/sw/source/filter/ww8/docxattributeoutput.hxx
index 2456fffac0a6..4c41f83d2f30 100644
--- a/sw/source/filter/ww8/docxattributeoutput.hxx
+++ b/sw/source/filter/ww8/docxattributeoutput.hxx
@@ -370,6 +370,7 @@ public:
     void WriteFormData_Impl( const ::sw::mark::IFieldmark& rFieldmark );
 
     void WriteBookmarks_Impl( std::vector< OUString >& rStarts, std::vector< OUString >& rEnds );
+    void WriteBookmarks_Impl( const OUString& rName, sal_Int32 nWithStartPos, sal_Int32 nWithEndPos );
     void WriteAnnotationMarks_Impl( std::vector< OUString >& rStarts, std::vector< OUString >& rEnds );
     void PushRelIdCache();
     void PopRelIdCache();
@@ -696,6 +697,8 @@ private:
     void DoWriteBookmarkTagEnd(const OUString & bookmarkName);
     void DoWriteBookmarksStart();
     void DoWriteBookmarksEnd();
+    void DoWriteBookmarkStartIfExist(sal_Int32 nPos);
+    void DoWriteBookmarkEndIfExist(sal_Int32 nPos);
 
     void DoWritePermissionTagStart(const OUString & permission);
     void DoWritePermissionTagEnd(const OUString & permission);
@@ -727,6 +730,7 @@ private:
     void CmdField_Impl( const SwTextNode* pNode, sal_Int32 nPos, FieldInfos const & rInfos, bool bWriteRun );
     void EndField_Impl( const SwTextNode* pNode, sal_Int32 nPos, FieldInfos& rInfos );
     void DoWriteFieldRunProperties( const SwTextNode* pNode, sal_Int32 nPos );
+    virtual void GenerateBookmarksForSequenceField(const SwTextNode& rNode, SwWW8AttrIter& rAttrIter) override;
 
     static void AddToAttrList( css::uno::Reference<sax_fastparser::FastAttributeList>& pAttrList, sal_Int32 nAttrName, const sal_Char* sAttrValue );
     static void AddToAttrList( css::uno::Reference<sax_fastparser::FastAttributeList>& pAttrList, sal_Int32 nArgs, ... );
@@ -784,6 +788,10 @@ private:
     std::vector<OUString> m_rBookmarksStart;
     std::vector<OUString> m_rBookmarksEnd;
 
+    /// Bookmarks with position to output
+    std::multimap<sal_Int32, OUString> m_aBookmarksWithPosStart;
+    std::multimap<sal_Int32, OUString> m_aBookmarksWithPosEnd;
+
     /// Permissions to output
     std::vector<OUString> m_rPermissionsStart;
     std::vector<OUString> m_rPermissionsEnd;
diff --git a/sw/source/filter/ww8/docxexport.hxx b/sw/source/filter/ww8/docxexport.hxx
index 047b497dcce5..2cfd53a866d2 100644
--- a/sw/source/filter/ww8/docxexport.hxx
+++ b/sw/source/filter/ww8/docxexport.hxx
@@ -177,6 +177,8 @@ public:
 
     void WriteOutliner(const OutlinerParaObject& rOutliner, sal_uInt8 nTyp);
 
+    virtual ExportFormat GetExportFormat() const override { return ExportFormat::DOCX; }
+
 protected:
     /// Format-dependent part of the actual export.
     virtual void ExportDocument_Impl() override;
diff --git a/sw/source/filter/ww8/rtfattributeoutput.hxx b/sw/source/filter/ww8/rtfattributeoutput.hxx
index e465dbbe8a8f..82e2817e1a03 100644
--- a/sw/source/filter/ww8/rtfattributeoutput.hxx
+++ b/sw/source/filter/ww8/rtfattributeoutput.hxx
@@ -217,6 +217,7 @@ public:
     void WriteBookmarks_Impl(std::vector< OUString >& rStarts, std::vector< OUString >& rEnds);
     void WriteAnnotationMarks_Impl(std::vector< OUString >& rStarts, std::vector< OUString >& rEnds);
     void WriteHeaderFooter_Impl(const SwFrameFormat& rFormat, bool bHeader, const sal_Char* pStr, bool bTitlepg);
+    void GenerateBookmarksForSequenceField(const SwTextNode& /*rNode*/, SwWW8AttrIter& /*rAttrIter*/) override {};
 
 protected:
     /// Output frames - the implementation.
diff --git a/sw/source/filter/ww8/rtfexport.hxx b/sw/source/filter/ww8/rtfexport.hxx
index ecef9ee60217..1c1f4d62c161 100644
--- a/sw/source/filter/ww8/rtfexport.hxx
+++ b/sw/source/filter/ww8/rtfexport.hxx
@@ -124,6 +124,8 @@ public:
 
     virtual sal_uLong ReplaceCr(sal_uInt8 nChar) override;
 
+    ExportFormat GetExportFormat() const override { return ExportFormat::RTF; }
+
 protected:
     /// Format-dependent part of the actual export.
     virtual void ExportDocument_Impl() override;
diff --git a/sw/source/filter/ww8/wrtw8nds.cxx b/sw/source/filter/ww8/wrtw8nds.cxx
index d04facf6af8c..e9ba18f40d6f 100644
--- a/sw/source/filter/ww8/wrtw8nds.cxx
+++ b/sw/source/filter/ww8/wrtw8nds.cxx
@@ -1156,6 +1156,25 @@ void SwWW8AttrIter::OutSwFormatRefMark(const SwFormatRefMark& rAttr, bool)
                                             &rAttr.GetRefName(), 0 ));
 }
 
+void SwWW8AttrIter::SplitRun( sal_Int32 nSplitEndPos )
+{
+    for(auto aIter = maCharRuns.begin(); aIter != maCharRuns.end(); ++aIter)
+    {
+        if(aIter->mnEndPos == nSplitEndPos)
+            return;
+        else if (aIter->mnEndPos > nSplitEndPos)
+        {
+            CharRunEntry aNewEntry = *aIter;
+            aIter->mnEndPos = nSplitEndPos;
+            maCharRuns.insert( ++aIter, aNewEntry);
+            maCharRunIter = maCharRuns.begin();
+            IterToCurrent();
+            nAktSwPos = SearchNext(1);
+            break;
+        }
+    }
+}
+
 void WW8AttributeOutput::FieldVanish( const OUString& rText, ww::eField /*eType*/ )
 {
     ww::bytes aItems;
@@ -2146,6 +2165,10 @@ void MSWordExportBase::OutputTextNode( const SwTextNode& rNode )
         AppendWordBookmark( sBkmkName );
     }
 
+    // Call this before write out fields and runs
+    if(GetExportFormat() == ExportFormat::DOCX)
+        AttrOutput().GenerateBookmarksForSequenceField(rNode, aAttrIter);
+
     const OUString& aStr( rNode.GetText() );
 
     sal_Int32 nAktPos = 0;
diff --git a/sw/source/filter/ww8/wrtww8.hxx b/sw/source/filter/ww8/wrtww8.hxx
index 9ee2645f2d38..dafffeaafd44 100644
--- a/sw/source/filter/ww8/wrtww8.hxx
+++ b/sw/source/filter/ww8/wrtww8.hxx
@@ -779,6 +779,9 @@ public:
     /// Returns the index of a picture bullet, used in numberings.
     int GetGrfIndex(const SvxBrushItem& rBrush);
 
+    enum ExportFormat { DOC = 0, RTF = 1, DOCX = 2};
+    virtual ExportFormat GetExportFormat() const = 0;
+
 protected:
     /// Format-dependent part of the actual export.
     virtual void ExportDocument_Impl() = 0;
@@ -1141,6 +1144,8 @@ public:
             const SwFrameFormat& rFormat, const SwFrameFormat& rLeftFormat, const SwFrameFormat& rFirstPageFormat,
         sal_uInt8 nBreakCode) override;
 
+    virtual ExportFormat GetExportFormat() const override { return ExportFormat::DOC; }
+
 protected:
     /// Output SwGrfNode
     virtual void OutputGrfNode( const SwGrfNode& ) override;
@@ -1504,6 +1509,8 @@ public:
 
     bool IsWatermarkFrame();
     bool IsAnchorLinkedToThisNode( sal_uLong nNodePos );
+
+    void SplitRun( sal_Int32 nSplitEndPos );
 };
 
 /// Class to collect and output the styles table.
diff --git a/sw/source/filter/ww8/ww8atr.cxx b/sw/source/filter/ww8/ww8atr.cxx
index db888c475a20..fbb763a1459a 100644
--- a/sw/source/filter/ww8/ww8atr.cxx
+++ b/sw/source/filter/ww8/ww8atr.cxx
@@ -902,7 +902,12 @@ OUString MSWordExportBase::GetBookmarkName( sal_uInt16 nTyp, const OUString* pNa
             }
             break;
         case REF_SEQUENCEFLD:
-            break;      // ???
+        {
+            assert(pName);
+            sRet += "Ref_";
+            sRet += *pName;
+            break;
+        }
         case REF_BOOKMARK:
             if ( pName )
                 sRet = *pName;
@@ -2784,6 +2789,63 @@ void AttributeOutputBase::TextField( const SwFormatField& rField )
                             break;
                     }
                     break;
+                case REF_SEQUENCEFLD:
+                {
+                    // Have this only for DOCX format by now
+                    if(!(GetExport().GetExportFormat() == MSWordExportBase::ExportFormat::DOCX))
+                        break;
+
+                    switch (pField->GetFormat())
+                    {
+                        case REF_PAGE:
+                        case REF_PAGE_PGDESC:
+                            eField = ww::ePAGEREF;
+                            break;
+                        default:
+                            eField = ww::eREF;
+                            break;
+                    }
+                    // Generate a unique bookmark name
+                    {
+                        OUString sName(rRField.GetSetRefName());
+                        sName += OUString::number(rRField.GetSeqNo());
+                        switch (pField->GetFormat())
+                        {
+                            case REF_PAGE:
+                            case REF_PAGE_PGDESC:
+                            case REF_CONTENT:
+                            case REF_UPDOWN:
+                                    sName += "_full";
+                                    break;
+                            case REF_ONLYNUMBER:
+                                    sName += "_label_and_number";
+                                    break;
+                            case REF_ONLYCAPTION:
+                                    sName += "_caption_only";
+                                    break;
+                            case REF_ONLYSEQNO:
+                                    sName += "_number_only";
+                                    break;
+                            default: // Ingore other types of reference fields
+                                    eField = ww::eNONE;
+                                    break;
+                        }
+                        sStr = FieldString(eField) + MSWordExportBase::GetBookmarkName(nSubType, &sName, 0);
+                    }
+                    switch (pField->GetFormat())
+                    {
+                        case REF_NUMBER:
+                            sStr += " \\r";
+                            break;
+                        case REF_NUMBER_NO_CONTEXT:
+                            sStr += " \\n";
+                            break;
+                        case REF_NUMBER_FULL_CONTEXT:
+                            sStr += " \\w";
+                            break;
+                    }
+                    break;
+                }
                 case REF_FOOTNOTE:
                 case REF_ENDNOTE:
                     switch (pField->GetFormat())
diff --git a/sw/source/filter/ww8/ww8attributeoutput.hxx b/sw/source/filter/ww8/ww8attributeoutput.hxx
index 0d41f0e33fb4..e2a978fcb4ac 100644
--- a/sw/source/filter/ww8/ww8attributeoutput.hxx
+++ b/sw/source/filter/ww8/ww8attributeoutput.hxx
@@ -84,6 +84,8 @@ public:
 
     virtual void FieldVanish( const OUString& rText, ww::eField eType ) override;
 
+    virtual void GenerateBookmarksForSequenceField(const SwTextNode& /*rNode*/, SwWW8AttrIter& /*rAttrIter*/) override {};
+
     /// Output redlining.
     virtual void Redline( const SwRedlineData* pRedline ) override;
 


More information about the Libreoffice-commits mailing list