[Libreoffice-commits] core.git: sw/inc sw/source

Oliver-Rainer Wittmann orw at apache.org
Wed Oct 23 05:32:44 PDT 2013


 sw/inc/tox.hxx                               |   13 
 sw/source/core/doc/doctxm.cxx                |    7 
 sw/source/core/tox/tox.cxx                   |   26 -
 sw/source/filter/ww8/attributeoutputbase.hxx |    4 
 sw/source/filter/ww8/writerwordglue.cxx      |    4 
 sw/source/filter/ww8/wrtw8nds.cxx            |    8 
 sw/source/filter/ww8/wrtww8.cxx              |  269 ++++++++--------
 sw/source/filter/ww8/wrtww8.hxx              |    2 
 sw/source/filter/ww8/ww8atr.cxx              |  434 +++++++++++++--------------
 sw/source/filter/ww8/ww8attributeoutput.hxx  |    6 
 sw/source/filter/ww8/ww8par.cxx              |   94 +++--
 sw/source/filter/ww8/ww8par.hxx              |   11 
 sw/source/filter/ww8/ww8par5.cxx             |  243 +++++++++------
 sw/source/filter/ww8/ww8par6.cxx             |    9 
 sw/source/filter/ww8/ww8scan.cxx             |   14 
 sw/source/filter/ww8/ww8scan.hxx             |    2 
 sw/source/ui/index/toxmgr.cxx                |    2 
 17 files changed, 653 insertions(+), 495 deletions(-)

New commits:
commit c4498251cb7181a9f272b0720f398597c0daef09
Author: Oliver-Rainer Wittmann <orw at apache.org>
Date:   Mon Sep 17 11:46:16 2012 +0000

    Resolves: #i119963#, #i120877# import and export actual TOC content
    
    Patch by: zhengfan, Oliver
    Review by: Oliver
    
    reintegrate from branch writer001
    
    (cherry picked from commit 8f2a21eac4a904db3cc4c448179e2d2cf5878ef4)
    
    Conflicts:
    	sw/inc/tox.hxx
    	sw/source/core/tox/tox.cxx
    	sw/source/filter/ww8/dump/ww8scan.cxx
    	sw/source/filter/ww8/wrtw8nds.cxx
    	sw/source/filter/ww8/wrtww8.cxx
    	sw/source/filter/ww8/ww8atr.cxx
    	sw/source/filter/ww8/ww8par.cxx
    	sw/source/filter/ww8/ww8par.hxx
    	sw/source/filter/ww8/ww8par5.cxx
    	sw/source/filter/ww8/ww8par6.cxx
    
    Change-Id: I75b2971f23754afa0bcb0b549bfb820dd5924b3b

diff --git a/sw/inc/tox.hxx b/sw/inc/tox.hxx
index 8e5a3b7..93c6200 100644
--- a/sw/inc/tox.hxx
+++ b/sw/inc/tox.hxx
@@ -463,6 +463,13 @@ class SW_DLLPUBLIC SwTOXBase : public SwClient
     sal_Bool        bFromObjectNames : 1;   // create a table or object index
                                     // from the names rather than the caption
     sal_Bool        bLevelFromChapter : 1; // User index: get the level from the source chapter
+
+protected:
+    // Add a data member, for record the TOC field expression of MS Word binary format
+    // For keeping fedality and may giving a better exporting performance
+    OUString maMSTOCExpression;
+    sal_Bool mbKeepExpression;
+
 public:
     SwTOXBase( const SwTOXType* pTyp, const SwForm& rForm,
                sal_uInt16 nCreaType, const OUString& rTitle );
@@ -482,6 +489,12 @@ public:
     OUString            GetTOXName() const {return aName;}
     void                SetTOXName(const OUString& rSet) {aName = rSet;}
 
+    // for record the TOC field expression of MS Word binary format
+    const OUString&     GetMSTOCExpression() const{return maMSTOCExpression;}
+    void                SetMSTOCExpression(const OUString& rExp) {maMSTOCExpression = rExp;}
+    void                EnableKeepExpression() {mbKeepExpression = sal_True;}
+    void                DisableKeepExpression() {mbKeepExpression = sal_False;}
+
     OUString            GetTitle() const;           // Title
     OUString            GetTypeName() const;        // Name
     const SwForm&       GetTOXForm() const;         // description of the lines
diff --git a/sw/source/core/doc/doctxm.cxx b/sw/source/core/doc/doctxm.cxx
index a5919b1..94a2f8a 100644
--- a/sw/source/core/doc/doctxm.cxx
+++ b/sw/source/core/doc/doctxm.cxx
@@ -752,7 +752,14 @@ void SwTOXBaseSection::Update(const SfxItemSet* pAttr,
         !GetFmt() || 0 == (pSectNd = GetFmt()->GetSectionNode() ) ||
         !pSectNd->GetNodes().IsDocNodes() ||
         IsHiddenFlag() )
+    {
         return;
+    }
+
+    if ( !mbKeepExpression )
+    {
+        maMSTOCExpression = OUString();
+    }
 
     SwDoc* pDoc = (SwDoc*)pSectNd->GetDoc();
 
diff --git a/sw/source/core/tox/tox.cxx b/sw/source/core/tox/tox.cxx
index c7e177f..d94ec5d 100644
--- a/sw/source/core/tox/tox.cxx
+++ b/sw/source/core/tox/tox.cxx
@@ -506,17 +506,19 @@ OUString SwForm::GetFormAuth()        {return OUString("<A>");}
 
 SwTOXBase::SwTOXBase(const SwTOXType* pTyp, const SwForm& rForm,
                      sal_uInt16 nCreaType, const OUString& rTitle )
-    : SwClient((SwModify*)pTyp),
-    aForm(rForm),
-    aTitle(rTitle),
-    eLanguage(::GetAppLanguage()),
-    nCreateType(nCreaType),
-    nOLEOptions(0),
-    eCaptionDisplay(CAPTION_COMPLETE),
-    bProtected( sal_True ),
-    bFromChapter(sal_False),
-    bFromObjectNames(sal_False),
-    bLevelFromChapter(sal_False)
+    : SwClient((SwModify*)pTyp)
+    , aForm(rForm)
+    , aTitle(rTitle)
+    , eLanguage((LanguageType)::GetAppLanguage())
+    , nCreateType(nCreaType)
+    , nOLEOptions(0)
+    , eCaptionDisplay(CAPTION_COMPLETE)
+    , bProtected( sal_True )
+    , bFromChapter(sal_False)
+    , bFromObjectNames(sal_False)
+    , bLevelFromChapter(sal_False)
+    , maMSTOCExpression()
+    , mbKeepExpression(sal_True)
 {
     aData.nOptions = 0;
 }
@@ -524,6 +526,7 @@ SwTOXBase::SwTOXBase(const SwTOXType* pTyp, const SwForm& rForm,
 
 SwTOXBase::SwTOXBase( const SwTOXBase& rSource, SwDoc* pDoc )
     : SwClient( rSource.GetRegisteredInNonConst() )
+    , mbKeepExpression(sal_True)
 {
     CopyTOXBase( pDoc, rSource );
 }
@@ -535,6 +538,7 @@ void SwTOXBase::RegisterToTOXType( SwTOXType& rType )
 
 SwTOXBase& SwTOXBase::CopyTOXBase( SwDoc* pDoc, const SwTOXBase& rSource )
 {
+    maMSTOCExpression = rSource.maMSTOCExpression;
     SwTOXType* pType = (SwTOXType*)rSource.GetTOXType();
     if( pDoc && USHRT_MAX == pDoc->GetTOXTypes().GetPos( pType ))
     {
diff --git a/sw/source/filter/ww8/attributeoutputbase.hxx b/sw/source/filter/ww8/attributeoutputbase.hxx
index 75e847a..7e32502 100644
--- a/sw/source/filter/ww8/attributeoutputbase.hxx
+++ b/sw/source/filter/ww8/attributeoutputbase.hxx
@@ -214,7 +214,9 @@ public:
 
     void StartTOX( const SwSection& rSect );
 
-    void EndTOX( const SwSection& rSect );
+    void EndTOX( const SwSection& rSect,bool bCareEnd=true );
+
+    virtual void OnTOXEnding() {}
 
     virtual void TOXMark( const SwTxtNode& rNode, const SwTOXMark& rAttr );
 
diff --git a/sw/source/filter/ww8/writerwordglue.cxx b/sw/source/filter/ww8/writerwordglue.cxx
index af8c32e..7fc6061 100644
--- a/sw/source/filter/ww8/writerwordglue.cxx
+++ b/sw/source/filter/ww8/writerwordglue.cxx
@@ -494,6 +494,10 @@ namespace sw
                 return true;
             if (nB == RES_TXTATR_CHARFMT)
                 return false;
+            if (nA == RES_TXTATR_INETFMT)
+                return true;
+            if (nB == RES_TXTATR_INETFMT)
+               return false;
             return nA < nB;
         }
 
diff --git a/sw/source/filter/ww8/wrtw8nds.cxx b/sw/source/filter/ww8/wrtw8nds.cxx
index 8c608f7..53ced4e 100644
--- a/sw/source/filter/ww8/wrtw8nds.cxx
+++ b/sw/source/filter/ww8/wrtw8nds.cxx
@@ -1974,7 +1974,7 @@ void MSWordExportBase::OutputTextNode( const SwTxtNode& rNode )
                     if ( pTOXSect )
                     {
                         m_aCurrentCharPropStarts.pop();
-                        AttrOutput().EndTOX( *pTOXSect );
+                        AttrOutput().EndTOX( *pTOXSect ,false);
                     }
                     //For i120928,the position of the bullet's graphic is at end of doc
                     if (bLastCR && (!bExported))
@@ -2019,6 +2019,7 @@ void MSWordExportBase::OutputTextNode( const SwTxtNode& rNode )
                 aAttrIter.OutFlys( nEnd );
                 // insert final bookmarks if any before CR and after flys
                 AppendBookmarks( rNode, nEnd, 1 );
+                WriteCR( pTextNodeInfoInner );
                 // #i120928 - position of the bullet's graphic is at end of doc
                 if (bLastCR && (!bExported))
                 {
@@ -2032,8 +2033,6 @@ void MSWordExportBase::OutputTextNode( const SwTxtNode& rNode )
                     AttrOutput().EndTOX( *pTOXSect );
                 }
 
-                WriteCR( pTextNodeInfoInner );
-
                 if ( bRedlineAtEnd )
                 {
                     AttrOutput().Redline( aAttrIter.GetRedline( nEnd ) );
@@ -2447,7 +2446,8 @@ void MSWordExportBase::OutputSectionNode( const SwSectionNode& rSectionNode )
 
     SwNodeIndex aIdx( rSectionNode, 1 );
     const SwNode& rNd = aIdx.GetNode();
-    if ( !rNd.IsSectionNode() && !IsInTable() ) //No sections in table
+    if ( !rNd.IsSectionNode() && !IsInTable()
+        && rSection.GetType() != TOX_CONTENT_SECTION && rSection.GetType() != TOX_HEADER_SECTION) //No sections in table
     {
         // if the first Node inside the section has an own
         // PageDesc or PageBreak attribut, then dont write
diff --git a/sw/source/filter/ww8/wrtww8.cxx b/sw/source/filter/ww8/wrtww8.cxx
index 95ef3fa..e500091 100644
--- a/sw/source/filter/ww8/wrtww8.cxx
+++ b/sw/source/filter/ww8/wrtww8.cxx
@@ -26,6 +26,9 @@
 
 #include <algorithm>
 
+#include <map>
+#include <set>
+
 #include <hintids.hxx>
 #include <string.h>
 #include <osl/endian.h>
@@ -177,41 +180,146 @@ public:
     WW8_FC GetStartFc() const       { return nStartFc; }
 };
 
+typedef std::map<OUString,long> BKMKNames;
+typedef BKMKNames::iterator BKMKNmItr;
+typedef std::pair<bool,OUString> BKMK;
+typedef std::pair<long,BKMK> BKMKCP;
+typedef std::multimap<long,BKMKCP*> BKMKCPs;
+typedef BKMKCPs::iterator CPItr;
+
 class WW8_WrtBookmarks
 {
 private:
-    //! Holds information about a single bookmark.
-    struct BookmarkInfo {
-        sal_uLong  startPos; //!< Starting character position.
-        sal_uLong  endPos;   //!< Ending character position.
-        bool       isField;  //!< True if the bookmark is in a field result.
-        OUString    name;    //!< Name of this bookmark.
-        inline BookmarkInfo(sal_uLong start, sal_uLong end, bool isFld, const OUString& bkName) : startPos(start), endPos(end), isField(isFld), name(bkName) {};
-        //! Operator < is defined purely for sorting.
-        inline bool operator<(const BookmarkInfo &other) const { return startPos < other.startPos; }
-    };
-    std::vector<BookmarkInfo> aBookmarks;
-    typedef std::vector<BookmarkInfo>::iterator BkmIter;
-
-    //! Return the position in aBookmarks where the string rNm can be found.
-    BkmIter GetPos( const OUString& rNm );
-
-    //No copying
+    BKMKCPs aSttCps,aEndCps;
+    BKMKNames maSwBkmkNms;
     WW8_WrtBookmarks(const WW8_WrtBookmarks&);
     WW8_WrtBookmarks& operator=(const WW8_WrtBookmarks&);
+
 public:
     WW8_WrtBookmarks();
     ~WW8_WrtBookmarks();
-
     //! Add a new bookmark to the list OR add an end position to an existing bookmark.
     void Append( WW8_CP nStartCp, const OUString& rNm, const ::sw::mark::IMark* pBkmk=NULL );
     //! Write out bookmarks to file.
     void Write( WW8Export& rWrt );
     //! Move existing field marks from one position to another.
-    void MoveFieldMarks(sal_uLong nFrom,sal_uLong nTo);
-
+    void MoveFieldMarks(WW8_CP nFrom, WW8_CP nTo);
 };
 
+WW8_WrtBookmarks::WW8_WrtBookmarks()
+{}
+
+WW8_WrtBookmarks::~WW8_WrtBookmarks()
+{
+    CPItr aEnd = aSttCps.end();
+    for (CPItr aItr = aSttCps.begin();aItr!=aEnd;aItr++)
+    {
+        if (aItr->second)
+        {
+            delete aItr->second;
+            aItr->second = NULL;
+        }
+    }
+}
+
+void WW8_WrtBookmarks::Append( WW8_CP nStartCp, const OUString& rNm, const ::sw::mark::IMark*)
+{
+    std::pair<BKMKNmItr,bool> aResult = maSwBkmkNms.insert(std::pair<OUString,long>(rNm,0L));
+    if (aResult.second)
+    {
+        BKMK aBK(false,rNm);
+        BKMKCP* pBKCP = new BKMKCP((long)nStartCp,aBK);
+        aSttCps.insert(std::pair<long,BKMKCP*>(nStartCp,pBKCP));
+        aResult.first->second = (long)nStartCp;
+    }
+    else
+    {
+        std::pair<CPItr,CPItr> aRange = aSttCps.equal_range(aResult.first->second);
+        for (CPItr aItr = aRange.first;aItr != aRange.second;aItr++)
+        {
+            if (aItr->second && aItr->second->second.second == rNm)
+            {
+                if (aItr->second->second.first)
+                    nStartCp--;
+                aItr->second->first = (long)nStartCp;
+                break;
+            }
+        }
+    }
+}
+
+void WW8_WrtBookmarks::Write( WW8Export& rWrt)
+{
+    if (!aSttCps.size())
+        return;
+    CPItr aItr;
+    long n;
+    std::vector<OUString> aNames;
+    SvMemoryStream aTempStrm1(65535,65535);
+    SvMemoryStream aTempStrm2(65535,65535);
+    for (aItr = aSttCps.begin();aItr!=aSttCps.end();aItr++)
+    {
+        if (aItr->second)
+        {
+            aEndCps.insert(std::pair<long,BKMKCP*>(aItr->second->first,aItr->second));
+            aNames.push_back(aItr->second->second.second);
+            SwWW8Writer::WriteLong( aTempStrm1, aItr->first);
+        }
+    }
+
+    aTempStrm1.Seek(0L);
+    for (aItr = aEndCps.begin(), n = 0;aItr != aEndCps.end();aItr++,n++)
+    {
+        if (aItr->second)
+        {
+            aItr->second->first = n;
+            SwWW8Writer::WriteLong( aTempStrm2, aItr->first);
+        }
+    }
+
+    aTempStrm2.Seek(0L);
+    rWrt.WriteAsStringTable(aNames, rWrt.pFib->fcSttbfbkmk,rWrt.pFib->lcbSttbfbkmk);
+    SvStream& rStrm = rWrt.bWrtWW8 ? *rWrt.pTableStrm : rWrt.Strm();
+    rWrt.pFib->fcPlcfbkf = rStrm.Tell();
+    rStrm<<aTempStrm1;
+    SwWW8Writer::WriteLong(rStrm, rWrt.pFib->ccpText + rWrt.pFib->ccpTxbx);
+    for (aItr = aSttCps.begin();aItr!=aSttCps.end();aItr++)
+    {
+        if (aItr->second)
+        {
+            SwWW8Writer::WriteLong(rStrm, aItr->second->first);
+        }
+    }
+    rWrt.pFib->lcbPlcfbkf = rStrm.Tell() - rWrt.pFib->fcPlcfbkf;
+    rWrt.pFib->fcPlcfbkl = rStrm.Tell();
+    rStrm<<aTempStrm2;
+    SwWW8Writer::WriteLong(rStrm, rWrt.pFib->ccpText + rWrt.pFib->ccpTxbx);
+    rWrt.pFib->lcbPlcfbkl = rStrm.Tell() - rWrt.pFib->fcPlcfbkl;
+}
+
+void WW8_WrtBookmarks::MoveFieldMarks(WW8_CP nFrom, WW8_CP nTo)
+{
+    std::pair<CPItr,CPItr> aRange = aSttCps.equal_range(nFrom);
+    CPItr aItr = aRange.first;
+    while (aItr != aRange.second)
+    {
+        if (aItr->second)
+        {
+            if (aItr->second->first == nFrom)
+            {
+                aItr->second->second.first = true;
+                aItr->second->first = nTo;
+            }
+            aSttCps.insert(std::pair<long,BKMKCP*>(nTo,aItr->second));
+            aItr->second = NULL;
+            aRange = aSttCps.equal_range(nFrom);
+            aItr = aRange.first;
+            continue;
+        }
+        aItr++;
+    }
+}
+
 #define ANZ_DEFAULT_STYLES 16
 
 // Names of the storage streams
@@ -1237,122 +1345,6 @@ WW8_CP WW8_WrPct::Fc2Cp( sal_uLong nFc ) const
     return nFc + aPcts.back().GetStartCp();
 }
 
-//--------------------------------------------------------------------------
-
-WW8_WrtBookmarks::WW8_WrtBookmarks()
-{
-}
-
-WW8_WrtBookmarks::~WW8_WrtBookmarks()
-{
-}
-
-void WW8_WrtBookmarks::Append( WW8_CP nStartCp, const OUString& rNm,  const ::sw::mark::IMark* )
-{
-    BkmIter bkIter = GetPos( rNm );
-    if( bkIter == aBookmarks.end() )
-    {
-        // new bookmark -> insert with start==end
-        aBookmarks.push_back( BookmarkInfo(nStartCp, nStartCp, false, rNm) );
-    }
-    else
-    {
-        // old bookmark -> this should be the end position
-        OSL_ENSURE( bkIter->endPos == bkIter->startPos, "end position is valid" );
-
-        //If this bookmark was around a field in writer, then we want to move
-        //it to the field result in word. The end is therefore one cp
-        //backwards from the 0x15 end mark that was inserted.
-        if (bkIter->isField)
-            --nStartCp;
-        bkIter->endPos = nStartCp;
-    }
-}
-
-
-void WW8_WrtBookmarks::Write( WW8Export& rWrt )
-{
-    if (!aBookmarks.empty())
-    {
-        //Make sure the bookmarks are sorted in order of start position.
-        std::sort(aBookmarks.begin(), aBookmarks.end());
-
-        // First write the Bookmark Name Stringtable
-        std::vector<OUString> aNames;
-        aNames.reserve(aBookmarks.size());
-        for (BkmIter bIt = aBookmarks.begin(); bIt < aBookmarks.end(); ++bIt)
-            aNames.push_back(bIt->name);
-        rWrt.WriteAsStringTable(aNames, rWrt.pFib->fcSttbfbkmk, rWrt.pFib->lcbSttbfbkmk);
-
-        // Second write the Bookmark start positions as pcf of longs
-        SvStream& rStrm = rWrt.bWrtWW8 ? *rWrt.pTableStrm : rWrt.Strm();
-        rWrt.pFib->fcPlcfbkf = rStrm.Tell();
-        for (BkmIter bIt = aBookmarks.begin(); bIt < aBookmarks.end(); ++bIt)
-            SwWW8Writer::WriteLong( rStrm, bIt->startPos );
-        SwWW8Writer::WriteLong(rStrm, rWrt.pFib->ccpText + rWrt.pFib->ccpTxbx);
-
-        //Lastly, need to write out the end positions (sorted by end position). But
-        //before that we need a lookup table (sorted by start position) to link
-        //start and end positions.
-        //   Start by sorting the end positions.
-        std::vector<sal_uLong> aEndSortTab;
-        aEndSortTab.reserve(aBookmarks.size());
-        for (BkmIter bIt = aBookmarks.begin(); bIt < aBookmarks.end(); ++bIt)
-            aEndSortTab.push_back(bIt->endPos);
-        std::sort(aEndSortTab.begin(), aEndSortTab.end());
-
-        //Now write out the lookups.
-        //Note that in most cases, the positions in both vectors will be very close.
-        for( sal_uLong i = 0; i < aBookmarks.size(); ++i )
-        {
-            sal_uLong nEndCP = aBookmarks[ i ].endPos;
-            sal_uInt16 nPos = i;
-            if( aEndSortTab[ nPos ] > nEndCP )
-            {
-                while( aEndSortTab[ --nPos ] != nEndCP )
-                    ;
-            }
-            else if( aEndSortTab[ nPos ] < nEndCP )
-                while( aEndSortTab[ ++nPos ] != nEndCP )
-                    ;
-            SwWW8Writer::WriteLong( rStrm, nPos );
-        }
-        rWrt.pFib->lcbPlcfbkf = rStrm.Tell() - rWrt.pFib->fcPlcfbkf;
-
-        // Finally, the actual Bookmark end positions.
-        rWrt.pFib->fcPlcfbkl = rStrm.Tell();
-        for(sal_uLong i = 0; i < aEndSortTab.size(); ++i )
-            SwWW8Writer::WriteLong( rStrm, aEndSortTab[ i ] );
-        SwWW8Writer::WriteLong(rStrm, rWrt.pFib->ccpText + rWrt.pFib->ccpTxbx);
-        rWrt.pFib->lcbPlcfbkl = rStrm.Tell() - rWrt.pFib->fcPlcfbkl;
-    }
-}
-
-WW8_WrtBookmarks::BkmIter WW8_WrtBookmarks::GetPos( const OUString& rNm )
-{
-    for (BkmIter bIt = aBookmarks.begin(); bIt < aBookmarks.end(); ++bIt) {
-        if (rNm == bIt->name)
-            return bIt;
-    }
-    return aBookmarks.end();
-}
-
-void WW8_WrtBookmarks::MoveFieldMarks(sal_uLong nFrom, sal_uLong nTo)
-{
-    for (BkmIter i = aBookmarks.begin(); i < aBookmarks.end(); ++i)
-    {
-        if (i->startPos == nFrom)
-        {
-            i->startPos = nTo;
-            if (i->endPos == nFrom)
-            {
-                i->isField = true;
-                i->endPos = nTo;
-            }
-        }
-    }
-}
-
 void WW8Export::AppendBookmarks( const SwTxtNode& rNd,
     xub_StrLen nAktPos, xub_StrLen nLen )
 {
@@ -1397,7 +1389,7 @@ void WW8Export::AppendBookmarks( const SwTxtNode& rNd,
     }
 }
 
-void WW8Export::MoveFieldMarks(sal_uLong nFrom, sal_uLong nTo)
+void WW8Export::MoveFieldMarks(WW8_CP nFrom, WW8_CP nTo)
 {
     pBkmks->MoveFieldMarks(nFrom, nTo);
 }
@@ -2540,7 +2532,8 @@ void MSWordExportBase::WriteText()
                 ;
             else if ( aIdx.GetNode().IsSectionNode() )
                 ;
-            else if ( !IsInTable() ) //No sections in table
+            else if ( !IsInTable()
+                && (rSect.GetType() != TOX_CONTENT_SECTION && rSect.GetType() != TOX_HEADER_SECTION )) //No sections in table
             {
                 //#120140# Do not need to insert a page/section break after a section end. Check this case first
                 sal_Bool bNeedExportBreakHere = sal_True;
diff --git a/sw/source/filter/ww8/wrtww8.hxx b/sw/source/filter/ww8/wrtww8.hxx
index ec9eb54..4185437 100644
--- a/sw/source/filter/ww8/wrtww8.hxx
+++ b/sw/source/filter/ww8/wrtww8.hxx
@@ -1018,7 +1018,7 @@ public:
     virtual void ExportGrfBullet(const SwTxtNode& rNd);
     void OutGrfBullets(const sw::Frame &rFrame);
 
-    void MoveFieldMarks(sal_uLong nFrom, sal_uLong nTo);
+    void MoveFieldMarks(WW8_CP nFrom, WW8_CP nTo);
 
     void WriteAsStringTable(const ::std::vector<OUString>&, sal_Int32& rfcSttbf,
         sal_Int32& rlcbSttbf, sal_uInt16 nExtraLen = 0);
diff --git a/sw/source/filter/ww8/ww8atr.cxx b/sw/source/filter/ww8/ww8atr.cxx
index ca57cf2..1d01bf4 100644
--- a/sw/source/filter/ww8/ww8atr.cxx
+++ b/sw/source/filter/ww8/ww8atr.cxx
@@ -923,7 +923,8 @@ void WW8AttributeOutput::RTLAndCJKState( bool bIsRTL, sal_uInt16 nScript )
 
 void WW8AttributeOutput::EndParagraph( ww8::WW8TableNodeInfoInner::Pointer_t pTextNodeInfoInner )
 {
-    m_rWW8Export.pPapPlc->AppendFkpEntry( m_rWW8Export.Strm().Tell(), m_rWW8Export.pO->size(), m_rWW8Export.pO->data() );
+    m_rWW8Export.pPapPlc->AppendFkpEntry( m_rWW8Export.Strm().Tell() - (mbOnTOXEnding?2:0), m_rWW8Export.pO->size(), m_rWW8Export.pO->data() );
+    mbOnTOXEnding = false;
     m_rWW8Export.pO->clear();
 
     if ( pTextNodeInfoInner.get() != NULL )
@@ -968,6 +969,11 @@ void WW8AttributeOutput::StartRun( const SwRedlineData* pRedlineData, bool /*bSi
     }
 }
 
+void WW8AttributeOutput::OnTOXEnding()
+{
+    mbOnTOXEnding = true;
+}
+
 void WW8AttributeOutput::EndRunProperties( const SwRedlineData* pRedlineData )
 {
     Redline( pRedlineData );
@@ -2034,260 +2040,268 @@ void AttributeOutputBase::StartTOX( const SwSection& rSect )
         static const sal_Char sEntryEnd[] = "\" ";
 
         ww::eField eCode = ww::eTOC;
-        OUString sStr;
-        switch (pTOX->GetType())
+        OUString sStr = pTOX->GetMSTOCExpression();
+        if ( sStr.isEmpty() )
         {
-        case TOX_INDEX:
-            eCode = ww::eINDEX;
-            sStr = FieldString(eCode);
+            switch (pTOX->GetType())
+            {
+            case TOX_INDEX:
+                eCode = ww::eINDEX;
+                sStr = FieldString(eCode);
 
-            if (pTOX->GetTOXForm().IsCommaSeparated())
-                sStr += "\\r ";
+                if (pTOX->GetTOXForm().IsCommaSeparated())
+                    sStr += "\\r ";
 
-            if (nsSwTOIOptions::TOI_ALPHA_DELIMITTER & pTOX->GetOptions())
-                sStr += "\\h \"A\" ";
+                if (nsSwTOIOptions::TOI_ALPHA_DELIMITTER & pTOX->GetOptions())
+                    sStr += "\\h \"A\" ";
 
-            {
-                OUString aFillTxt;
-                for (sal_uInt8 n = 1; n <= 3; ++n)
                 {
-                    OUString aTxt;
-                    int nRet = ::lcl_CheckForm(pTOX->GetTOXForm(), n, aTxt);
+                    OUString aFillTxt;
+                    for (sal_uInt8 n = 1; n <= 3; ++n)
+                    {
+                        OUString aTxt;
+                        int nRet = ::lcl_CheckForm(pTOX->GetTOXForm(), n, aTxt);
 
-                    if( 3 == nRet )
-                        aFillTxt = aTxt;
-                    else if ((4 == nRet) || (2 == nRet))
-                        aFillTxt = "\t";
-                    else
-                        aFillTxt = "";
+                        if( 3 == nRet )
+                            aFillTxt = aTxt;
+                        else if ((4 == nRet) || (2 == nRet)) //#109414#
+                            aFillTxt = "\t";
+                        else
+                            aFillTxt = "";
+                    }
+                    sStr += "\\e \"";
+                    sStr += aFillTxt;
+                    sStr += sEntryEnd;
                 }
-                sStr += "\\e \"";
-                sStr += aFillTxt;
-                sStr += sEntryEnd;
-            }
-            break;
-
-        case TOX_ILLUSTRATIONS:
-        case TOX_OBJECTS:
-        case TOX_TABLES:
-            if (!pTOX->IsFromObjectNames())
-            {
-                sStr = FieldString(eCode);
-
-                sStr += "\\c \"";
-                sStr += pTOX->GetSequenceName();
-                sStr += sEntryEnd;
+                break;
 
-                OUString aTxt;
-                int nRet = ::lcl_CheckForm( pTOX->GetTOXForm(), 1, aTxt );
-                if (1 == nRet)
-                    sStr += "\\n ";
-                else if( 3 == nRet || 4 == nRet )
+                //      case TOX_AUTHORITIES:   eCode = eTOA; sStr = ???; break;
+            case TOX_ILLUSTRATIONS:
+            case TOX_OBJECTS:
+            case TOX_TABLES:
+                if (!pTOX->IsFromObjectNames())
                 {
-                    sStr += "\\p \"";
-                    sStr += aTxt;
-                    sStr += sEntryEnd;
-                }
-            }
-            break;
+                    sStr = FieldString(eCode);
 
-        default:
-            {
-                sStr = FieldString(eCode);
+                    sStr += "\\c \"";
+                    sStr += pTOX->GetSequenceName();
+                    sStr += sEntryEnd;
 
-                OUString sTOption;
-                sal_uInt16 n, nTOXLvl = pTOX->GetLevel();
-                if( !nTOXLvl )
-                    ++nTOXLvl;
+                    OUString aTxt;
+                    int nRet = ::lcl_CheckForm( pTOX->GetTOXForm(), 1, aTxt );
+                    if (1 == nRet)
+                        sStr += "\\n ";
+                    else if( 3 == nRet || 4 == nRet )
+                    {
+                        sStr += "\\p \"";
+                        sStr += aTxt;
+                        sStr += sEntryEnd;
+                    }
+                }
+                break;
 
-                if( nsSwTOXElement::TOX_MARK & pTOX->GetCreateType() )
+                //      case TOX_USER:
+                //      case TOX_CONTENT:
+            default:
                 {
-                    sStr += "\\f ";
+                    sStr = FieldString(eCode);
 
-                    if( TOX_USER == pTOX->GetType() )
-                    {
-                         sStr += "\"";
-                         sStr += OUString((sal_Char)( 'A' + GetExport( ).GetId( *pTOX->GetTOXType() ) ));
-                         sStr += sEntryEnd;
-                    }
+                    OUString sTOption;
+                    sal_uInt16 n, nTOXLvl = pTOX->GetLevel();
+                    if( !nTOXLvl )
+                        ++nTOXLvl;
 
-                    if( nsSwTOXElement::TOX_OUTLINELEVEL & pTOX->GetCreateType() )
+                    if( nsSwTOXElement::TOX_MARK & pTOX->GetCreateType() )
                     {
-                        const int nMinLvl = nTOXLvl;
+                        sStr += "\\f ";
 
-                        if ( nMinLvl > 0 )
+                        if( TOX_USER == pTOX->GetType() )
                         {
-                            int nTmpLvl = nMinLvl;
-                            if (nTmpLvl > WW8ListManager::nMaxLevel)
-                                nTmpLvl = WW8ListManager::nMaxLevel;
-
-                            sStr += "\\o \"1-";
-                            sStr += OUString::number( nTmpLvl );
+                            sStr += "\"";
+                            sStr += OUString((sal_Char)( 'A' + GetExport( ).GetId( *pTOX->GetTOXType() ) ));
                             sStr += sEntryEnd;
                         }
-                    }
 
-                    if( nsSwTOXElement::TOX_OUTLINELEVEL & pTOX->GetCreateType() )
-                    {
-                        // Take the TOC value of the max level to evaluate to as
-                        // the starting point for the \o flag, but reduce it to the
-                        // value of the highest outline level filled by a *standard*
-                        // Heading 1 - 9 style because \o "Builds a table of
-                        // contents from paragraphs formatted with built-in heading
-                        // styles". And afterward fill in any outline styles left
-                        // uncovered by that range to the \t flag
-                        //
-                        // i.e. for
-                        // Heading 1
-                        // Heading 2
-                        // custom-style
-                        // Heading 4
-                        // output
-                        // \o 1-2 \tcustom-style,3,Heading 3,4
-
-                        // Search over all the outline styles used and figure out
-                        // what is the minimum outline level (if any) filled by a
-                        // non-standard style for that level, i.e. ignore headline
-                        // styles 1-9 and find the lowest valid outline level
-                        sal_uInt8 nPosOfLowestNonStandardLvl = MAXLEVEL;
-                        const SwTxtFmtColls& rColls = *GetExport().pDoc->GetTxtFmtColls();
-                        for( n = rColls.size(); n; )
+                        if( nsSwTOXElement::TOX_OUTLINELEVEL & pTOX->GetCreateType() )
                         {
-                            const SwTxtFmtColl* pColl = rColls[ --n ];
-                            sal_uInt16 nPoolId = pColl->GetPoolFmtId();
-                            if (
-                                //Is a Non-Standard Outline Style
-                                (RES_POOLCOLL_HEADLINE1 > nPoolId || RES_POOLCOLL_HEADLINE9 < nPoolId) &&
-                                //Has a valid outline level
-                                (pColl->IsAssignedToListLevelOfOutlineStyle()) &&
-                                // Is less than the lowest known non-standard level
-                                (pColl->GetAssignedOutlineStyleLevel() < nPosOfLowestNonStandardLvl)
-                               )
+                            const int nMinLvl = nTOXLvl;
+                            if ( nMinLvl > 0 )
                             {
-                                nPosOfLowestNonStandardLvl = ::sal::static_int_cast<sal_uInt8>(pColl->GetAssignedOutlineStyleLevel());
-                            }
-                        }
+                                int nTmpLvl = nMinLvl;
+                                if (nTmpLvl > WW8ListManager::nMaxLevel)
+                                    nTmpLvl = WW8ListManager::nMaxLevel;
 
-                        sal_uInt8 nMaxMSAutoEvaluate = nPosOfLowestNonStandardLvl < nTOXLvl ? nPosOfLowestNonStandardLvl : (sal_uInt8)nTOXLvl;
+                                sStr += "\\o \"1-";
+                                sStr += OUString::number(nTmpLvl);
+                                sStr += sEntryEnd;
 
-                        //output \o 1-X where X is the highest normal outline style to be included in the toc
-                        if ( nMaxMSAutoEvaluate )
-                        {
-                            if (nMaxMSAutoEvaluate > WW8ListManager::nMaxLevel)
-                              nMaxMSAutoEvaluate = WW8ListManager::nMaxLevel;
-
-                            sStr += "\\o \"1-";
-                            sStr += OUString::number( nMaxMSAutoEvaluate );
-                            sStr += sEntryEnd;
+                            }
                         }
 
-                        //collect up any other styles in the writer TOC which will
-                        //not already appear in the MS TOC and place then into the
-                        //\t option
-                        if( nMaxMSAutoEvaluate < nTOXLvl )
+                        if( nsSwTOXElement::TOX_OUTLINELEVEL & pTOX->GetCreateType() )
                         {
-                            // collect this templates into the \t otion
-                            for( n = rColls.size(); n;)
+                            // Take the TOC value of the max level to evaluate to as
+                            // the starting point for the \o flag, but reduce it to the
+                            // value of the highest outline level filled by a *standard*
+                            // Heading 1 - 9 style because \o "Builds a table of
+                            // contents from paragraphs formatted with built-in heading
+                            // styles". And afterward fill in any outline styles left
+                            // uncovered by that range to the \t flag
+                            //
+                            // i.e. for
+                            // Heading 1
+                            // Heading 2
+                            // custom-style
+                            // Heading 4
+                            // output
+                            // \o 1-2 \tcustom-style,3,Heading 3,4
+
+                            // Search over all the outline styles used and figure out
+                            // what is the minimum outline level (if any) filled by a
+                            // non-standard style for that level, i.e. ignore headline
+                            // styles 1-9 and find the lowest valid outline level
+                            sal_uInt8 nPosOfLowestNonStandardLvl = MAXLEVEL;
+                            const SwTxtFmtColls& rColls = *GetExport().pDoc->GetTxtFmtColls();
+                            for( n = rColls.size(); n; )
                             {
                                 const SwTxtFmtColl* pColl = rColls[ --n ];
-                                if (!pColl->IsAssignedToListLevelOfOutlineStyle())
-                                    continue;
-                                sal_uInt8 nTestLvl =  ::sal::static_int_cast<sal_uInt8>(pColl->GetAssignedOutlineStyleLevel());
-                                if (nTestLvl < nTOXLvl && nTestLvl >= nMaxMSAutoEvaluate)
+                                sal_uInt16 nPoolId = pColl->GetPoolFmtId();
+                                if (
+                                    //Is a Non-Standard Outline Style
+                                    (RES_POOLCOLL_HEADLINE1 > nPoolId || RES_POOLCOLL_HEADLINE9 < nPoolId) &&
+                                    //Has a valid outline level
+                                    (pColl->IsAssignedToListLevelOfOutlineStyle()) &&
+                                    // Is less than the lowest known non-standard level
+                                    (pColl->GetAssignedOutlineStyleLevel() < nPosOfLowestNonStandardLvl)
+                                    )
+                                {
+                                    nPosOfLowestNonStandardLvl = ::sal::static_int_cast<sal_uInt8>(pColl->GetAssignedOutlineStyleLevel());
+                                }
+                            }
+
+                            sal_uInt8 nMaxMSAutoEvaluate = nPosOfLowestNonStandardLvl < nTOXLvl ? nPosOfLowestNonStandardLvl : (sal_uInt8)nTOXLvl;
+
+                            //output \o 1-X where X is the highest normal outline style to be included in the toc
+                            if ( nMaxMSAutoEvaluate )
+                            {
+                                if (nMaxMSAutoEvaluate > WW8ListManager::nMaxLevel)
+                                    nMaxMSAutoEvaluate = WW8ListManager::nMaxLevel;
+
+                                sStr += "\\o \"1-";
+                                sStr += OUString::number(nMaxMSAutoEvaluate);
+                                sStr += sEntryEnd;
+                            }
+
+                            //collect up any other styles in the writer TOC which will
+                            //not already appear in the MS TOC and place then into the
+                            //\t option
+                            if( nMaxMSAutoEvaluate < nTOXLvl )
+                            {
+                                // collect this templates into the \t otion
+                                for( n = rColls.size(); n;)
                                 {
-                                    if( !sTOption.isEmpty() )
-                                        sTOption += ",";
-                                    sTOption += pColl->GetName()  + "," + OUString::number( nTestLvl + 1 );
+                                    const SwTxtFmtColl* pColl = rColls[ --n ];
+                                    if (!pColl->IsAssignedToListLevelOfOutlineStyle())
+                                        continue;
+                                    sal_uInt8 nTestLvl =  ::sal::static_int_cast<sal_uInt8>(pColl->GetAssignedOutlineStyleLevel());
+                                    if (nTestLvl < nTOXLvl && nTestLvl >= nMaxMSAutoEvaluate)
+                                    {
+                                        if (!sTOption.isEmpty())
+                                            sTOption += ",";
+                                        sTOption += pColl->GetName() + "," + OUString::number( nTestLvl + 1 );
+                                    }
                                 }
                             }
                         }
-                    }
 
-                    if( nsSwTOXElement::TOX_TEMPLATE & pTOX->GetCreateType() )
-                        // #i99641# - Consider additional styles regardless of TOX-outlinelevel
-                        for( n = 0; n < MAXLEVEL; ++n )
-                        {
-                            const OUString& rStyles = pTOX->GetStyleNames( n );
-                            if( !rStyles.isEmpty() )
+                        if( nsSwTOXElement::TOX_TEMPLATE & pTOX->GetCreateType() )
+                            // #i99641# - Consider additional styles regardless of TOX-outlinelevel
+                            for( n = 0; n < MAXLEVEL; ++n )
+                            {
+                                const OUString& rStyles = pTOX->GetStyleNames( n );
+                                if( !rStyles.isEmpty() )
+                                {
+                                    sal_Int32 nPos = 0;
+                                    OUString sLvl = OUString(',');
+                                    sLvl += OUString::number( n + 1 );
+                                    do {
+                                        OUString sStyle( rStyles.getToken( 0, TOX_STYLE_DELIMITER, nPos ));
+                                        if( !sStyle.isEmpty() )
+                                        {
+                                            SwTxtFmtColl* pColl = GetExport().pDoc->FindTxtFmtCollByName(sStyle);
+                                            if (!pColl->IsAssignedToListLevelOfOutlineStyle() || pColl->GetAssignedOutlineStyleLevel() < nTOXLvl)
+                                            {
+                                                if( !sTOption.isEmpty() )
+                                                    sTOption += ",";
+                                                sTOption += sStyle + sLvl;
+                                            }
+                                        }
+                                    } while( -1 != nPos );
+                                }
+                            }
+
                             {
-                                sal_Int32 nPos = 0;
-                                OUString sLvl = OUString(',');
-                                sLvl += OUString::number( n + 1 );
-                                do {
-                                    OUString sStyle( rStyles.getToken( 0, TOX_STYLE_DELIMITER, nPos ));
-                                    if( !sStyle.isEmpty() )
+                                OUString aFillTxt;
+                                sal_uInt8 nNoPgStt = MAXLEVEL, nNoPgEnd = MAXLEVEL;
+                                bool bFirstFillTxt = true, bOnlyText = true;
+                                for( n = 0; n < nTOXLvl; ++n )
+                                {
+                                    OUString aTxt;
+                                    int nRet = ::lcl_CheckForm( pTOX->GetTOXForm(),
+                                        static_cast< sal_uInt8 >(n+1), aTxt );
+                                    if( 1 == nRet )
                                     {
-                                        SwTxtFmtColl* pColl = GetExport().pDoc->FindTxtFmtCollByName(sStyle);
-                                        if (!pColl || !pColl->IsAssignedToListLevelOfOutlineStyle() || pColl->GetAssignedOutlineStyleLevel() < nTOXLvl)
+                                        bOnlyText = false;
+                                        if( MAXLEVEL == nNoPgStt )
+                                            nNoPgStt = static_cast< sal_uInt8 >(n+1);
+                                    }
+                                    else
+                                    {
+                                        if( MAXLEVEL != nNoPgStt &&
+                                            MAXLEVEL == nNoPgEnd )
+                                            nNoPgEnd = sal_uInt8(n);
+
+                                        bOnlyText = bOnlyText && 3 == nRet;
+                                        if( 3 == nRet || 4 == nRet )
                                         {
-                                            if( !sTOption.isEmpty() )
-                                                sTOption += ",";
-                                            ( sTOption += sStyle ) += sLvl;
+                                            if( bFirstFillTxt )
+                                                aFillTxt = aTxt;
+                                            else if( aFillTxt != aTxt )
+                                                aFillTxt = "";
+                                            bFirstFillTxt = false;
                                         }
                                     }
-                                } while( -1 != nPos );
+                                }
+                                if( MAXLEVEL != nNoPgStt )
+                                {
+                                    if (WW8ListManager::nMaxLevel < nNoPgEnd)
+                                        nNoPgEnd = WW8ListManager::nMaxLevel;
+                                    sStr += "\\n ";
+                                    sStr += OUString::number( nNoPgStt );
+                                    sStr += "-";
+                                    sStr += OUString::number( nNoPgEnd  );
+                                    sStr += " ";
+                                }
+                                if( bOnlyText )
+                                {
+                                    sStr += "\\p \"";
+                                    sStr += aFillTxt;
+                                    sStr += sEntryEnd;
+                                }
                             }
-                        }
 
-                    OUString aFillTxt;
-                    sal_uInt8 nNoPgStt = MAXLEVEL, nNoPgEnd = MAXLEVEL;
-                    bool bFirstFillTxt = true, bOnlyText = true;
-                    for( n = 0; n < nTOXLvl; ++n )
-                    {
-                        OUString aTxt;
-                        int nRet = ::lcl_CheckForm( pTOX->GetTOXForm(),
-                                                    static_cast< sal_uInt8 >(n+1), aTxt );
-                        if( 1 == nRet )
-                        {
-                            bOnlyText = false;
-                            if( MAXLEVEL == nNoPgStt )
-                                nNoPgStt = static_cast< sal_uInt8 >(n+1);
-                        }
-                        else
-                        {
-                            if( MAXLEVEL != nNoPgStt &&
-                                MAXLEVEL == nNoPgEnd )
-                                nNoPgEnd = sal_uInt8(n);
-
-                            bOnlyText = bOnlyText && 3 == nRet;
-                            if( 3 == nRet || 4 == nRet )
+                            if( !sTOption.isEmpty() )
                             {
-                                if( bFirstFillTxt )
-                                    aFillTxt = aTxt;
-                                else if( aFillTxt != aTxt )
-                                    aFillTxt = "";
-                                bFirstFillTxt = false;
+                                sStr += "\\t \"";
+                                sStr += sTOption;
+                                sStr += sEntryEnd;
                             }
-                        }
-                    }
-                    if( MAXLEVEL != nNoPgStt )
-                    {
-                        if (WW8ListManager::nMaxLevel < nNoPgEnd)
-                            nNoPgEnd = WW8ListManager::nMaxLevel;
-                        sStr += "\\n ";
-                        sStr += OUString::number( nNoPgStt );
-                        sStr += "-";
-                        sStr += OUString::number( nNoPgEnd  );
-                        sStr += " ";
-                    }
-                    if( bOnlyText )
-                    {
-                        sStr += "\\p \"";
-                        sStr += aFillTxt;
-                        sStr += sEntryEnd;
-                    }
 
-                    if( !sTOption.isEmpty() )
-                    {
-                        sStr += "\\t \"";
-                        sStr += sTOption;
-                        sStr += sEntryEnd;
+                            if (lcl_IsHyperlinked(pTOX->GetTOXForm(), nTOXLvl))
+                                sStr += "\\h";
                     }
-
-                    if (lcl_IsHyperlinked(pTOX->GetTOXForm(), nTOXLvl))
-                        sStr += "\\h";
+                    break;
                 }
-            break;
             }
         }
 
@@ -2302,7 +2316,7 @@ void AttributeOutputBase::StartTOX( const SwSection& rSect )
     GetExport( ).bStartTOX = false;
 }
 
-void AttributeOutputBase::EndTOX( const SwSection& rSect )
+void AttributeOutputBase::EndTOX( const SwSection& rSect,bool bCareEnd )
 {
     const SwTOXBase* pTOX = rSect.GetTOXBase();
     if ( pTOX )
@@ -2311,6 +2325,8 @@ void AttributeOutputBase::EndTOX( const SwSection& rSect )
         GetExport( ).OutputField( 0, eCode, aEmptyOUStr, WRITEFIELD_CLOSE );
     }
     GetExport( ).bInWriteTOX = false;
+    if (bCareEnd)
+        OnTOXEnding();
 }
 
 bool MSWordExportBase::GetNumberFmt(const SwField& rFld, OUString& rStr)
diff --git a/sw/source/filter/ww8/ww8attributeoutput.hxx b/sw/source/filter/ww8/ww8attributeoutput.hxx
index 81691cb..2fc8dbd 100644
--- a/sw/source/filter/ww8/ww8attributeoutput.hxx
+++ b/sw/source/filter/ww8/ww8attributeoutput.hxx
@@ -51,6 +51,8 @@ public:
     ///
     virtual void StartRun( const SwRedlineData* pRedlineData, bool bSingleEmptyRun = false );
 
+    virtual void OnTOXEnding();
+
     /// End of the text run.
     ///
     /// No-op for binary filters.
@@ -441,8 +443,10 @@ protected:
     /// of the field results if we were forced to split text.
     sal_uInt16 m_nFieldResults;
 
+    bool mbOnTOXEnding;
+
 public:
-    WW8AttributeOutput( WW8Export &rWW8Export ) : AttributeOutputBase(), m_rWW8Export( rWW8Export ) {}
+    WW8AttributeOutput( WW8Export &rWW8Export ) : AttributeOutputBase(), m_rWW8Export( rWW8Export ),mbOnTOXEnding(false) {}
     virtual ~WW8AttributeOutput() {}
 
     /// Return the right export class.
diff --git a/sw/source/filter/ww8/ww8par.cxx b/sw/source/filter/ww8/ww8par.cxx
index b3d3426..160b9e5 100644
--- a/sw/source/filter/ww8/ww8par.cxx
+++ b/sw/source/filter/ww8/ww8par.cxx
@@ -3165,8 +3165,14 @@ bool SwWW8ImplReader::ReadChar(long nPosCp, long nCpOfs)
                 cInsert = '\xb5';
             break;
         case 0x15:
-            if( !bSpec )        // Section sign
-                cInsert = '\xa7';
+            if( !bSpec )        // Juristenparagraph
+            {
+                cp_set::iterator aItr = maTOXEndCps.find((WW8_CP)nPosCp);
+                if (aItr == maTOXEndCps.end())
+                    cInsert = '\xa7';
+                else
+                    maTOXEndCps.erase(aItr);
+            }
             break;
         case 0x9:
             cInsert = '\x9';    // Tab
@@ -3576,10 +3582,26 @@ bool SwWW8ImplReader::ReadText(long nStartCp, long nTextLen, ManTypes nType)
         // create a new txtnode and join the two paragraphs together
         if (bStartLine && !pPreviousNode) // Line end
         {
-            // We will record the CP of a paragraph end ('0x0D'), if current loading contents is from main stream;
-            if (mbOnLoadingMain)
-                maEndParaPos.push_back(l-1);
-            AppendTxtNode(*pPaM->GetPoint());
+            bool bSplit = true;
+            if (mbCareFirstParaEndInToc)
+            {
+                mbCareFirstParaEndInToc = false;
+                if (pPaM->End() && pPaM->End()->nNode.GetNode().GetTxtNode() &&  pPaM->End()->nNode.GetNode().GetTxtNode()->Len() == 0)
+                    bSplit = false;
+            }
+            if (mbCareLastParaEndInToc)
+            {
+                mbCareLastParaEndInToc = false;
+                if (pPaM->End() && pPaM->End()->nNode.GetNode().GetTxtNode() &&  pPaM->End()->nNode.GetNode().GetTxtNode()->Len() == 0)
+                    bSplit = false;
+            }
+            if (bSplit)
+            {
+                // We will record the CP of a paragraph end ('0x0D'), if current loading contents is from main stream;
+                if (mbOnLoadingMain)
+                    maEndParaPos.push_back(l-1);
+                AppendTxtNode(*pPaM->GetPoint());
+            }
         }
 
         if (pPreviousNode && bStartLine)
@@ -3714,33 +3736,39 @@ bool SwWW8ImplReader::ReadText(long nStartCp, long nTextLen, ManTypes nType)
  * class SwWW8ImplReader
  */
 SwWW8ImplReader::SwWW8ImplReader(sal_uInt8 nVersionPara, SvStorage* pStorage,
-    SvStream* pSt, SwDoc& rD, const OUString& rBaseURL, bool bNewDoc) :
-    mpDocShell(rD.GetDocShell()),
-    pStg(pStorage),
-    pStrm(pSt),
-    pTableStream(0),
-    pDataStream(0),
-    rDoc(rD),
-    maSectionManager(*this),
-    m_aExtraneousParas(rD),
-    maInsertedTables(rD),
-    maSectionNameGenerator(rD, OUString("WW")),
-    maGrfNameGenerator(bNewDoc, OUString('G')),
-    maParaStyleMapper(rD),
-    maCharStyleMapper(rD),
-    maTxtNodesHavingFirstLineOfstSet(), // #i103711#
-    maTxtNodesHavingLeftIndentSet(), // #i105414#
-    pMSDffManager(0),
-    mpAtnNames(0),
-    sBaseURL(rBaseURL),
-    m_bRegardHindiDigits( false ),
-    mbNewDoc(bNewDoc),
-    nDropCap(0),
-    nIdctHint(0),
-    bBidi(false),
-    bReadTable(false),
-    maCurrAttrCP(-1),
-    mbOnLoadingMain(false)
+    SvStream* pSt, SwDoc& rD, const OUString& rBaseURL, bool bNewDoc)
+    : mpDocShell(rD.GetDocShell())
+    , pStg(pStorage)
+    , pStrm(pSt)
+    , pTableStream(0)
+    , pDataStream(0)
+    , rDoc(rD)
+    , maSectionManager(*this)
+    , m_aExtraneousParas(rD)
+    , maInsertedTables(rD)
+    , maSectionNameGenerator(rD, OUString("WW"))
+    , maGrfNameGenerator(bNewDoc, OUString('G'))
+    , maParaStyleMapper(rD)
+    , maCharStyleMapper(rD)
+    , maTxtNodesHavingFirstLineOfstSet()
+    , maTxtNodesHavingLeftIndentSet()
+    , pMSDffManager(0)
+    , mpAtnNames(0)
+    , sBaseURL(rBaseURL)
+    , m_bRegardHindiDigits( false )
+    , mbNewDoc(bNewDoc)
+    , nDropCap(0)
+    , nIdctHint(0)
+    , bBidi(false)
+    , bReadTable(false)
+    , mbLoadingTOCCache(false)
+    , mbLoadingTOCHyperlink(false)
+    , mpPosAfterTOC(0)
+    , mbCareFirstParaEndInToc(false)
+    , mbCareLastParaEndInToc(false)
+    , maTOXEndCps()
+    , maCurrAttrCP(-1)
+    , mbOnLoadingMain(false)
 {
     pStrm->SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
     nWantedVersion = nVersionPara;
diff --git a/sw/source/filter/ww8/ww8par.hxx b/sw/source/filter/ww8/ww8par.hxx
index ffe4317..30ae35f 100644
--- a/sw/source/filter/ww8/ww8par.hxx
+++ b/sw/source/filter/ww8/ww8par.hxx
@@ -974,6 +974,7 @@ struct WW8TabBandDesc
 //-----------------------------------------
 //            Storage-Reader
 //-----------------------------------------
+typedef std::set<WW8_CP> cp_set;
 typedef std::vector<WW8_CP> cp_vector;
 
 class SwWW8ImplReader
@@ -1276,6 +1277,16 @@ private:
     bool bBidi;
     bool bReadTable;
     boost::shared_ptr<SwPaM> mpTableEndPaM;
+    // Indicate that currently on loading a TOC, managed by Read_F_TOX() and End_Field()
+    bool mbLoadingTOCCache;
+    // Indicate that current on loading a hyperlink, which is inside a TOC; Managed by Read_F_Hyperlink() and End_Field()
+    bool mbLoadingTOCHyperlink;
+    // a document position recorded the after-position of TOC section, managed by Read_F_TOX() and End_Field()
+    SwPaM* mpPosAfterTOC;
+
+    bool mbCareFirstParaEndInToc;
+    bool mbCareLastParaEndInToc;
+    cp_set maTOXEndCps;
 
     cp_vector maEndParaPos;
     WW8_CP maCurrAttrCP;
diff --git a/sw/source/filter/ww8/ww8par5.cxx b/sw/source/filter/ww8/ww8par5.cxx
index 2ce43f2..2326588 100644
--- a/sw/source/filter/ww8/ww8par5.cxx
+++ b/sw/source/filter/ww8/ww8par5.cxx
@@ -116,13 +116,15 @@ long SwWW8ImplReader::Read_Book(WW8PLCFManResult*)
         return 0;
     }
 
-    //"_Toc*" and "_Hlt*" are unnecessary
+    // "_Hlt*" are unnecessary
     const OUString* pName = pB->GetName();
-#if !defined(WW_NATIVE_TOC)
-    if(    !pName || pName->startsWithIgnoreAsciiCase( "_Toc" )
-        || pName->startsWithIgnoreAsciiCase( "_Hlt" ) )
+    // Now, as we read the TOC field completely, we also need the hyperlinks inside keep available.
+    // So the hidden bookmarks inside for hyperlink jumping also should be kept.
+    if ( !pName ||
+         pName->startsWithIgnoreAsciiCase( "_Hlt" ) )
+    {
         return 0;
-#endif
+    }
 
     // do NOT call ToUpper as the bookmark name can also be a hyperlink target!
 
@@ -455,7 +457,8 @@ sal_uInt16 SwWW8ImplReader::End_Field()
     sal_uInt16 nRet = 0;
     WW8PLCFx_FLD* pF = pPlcxMan->GetFld();
     OSL_ENSURE(pF, "WW8PLCFx_FLD - Pointer nicht da");
-    if (!pF || !pF->EndPosIsFieldEnd())
+    WW8_CP nCP = 0;
+    if (!pF || !pF->EndPosIsFieldEnd(nCP))
         return nRet;
 
     const SvtFilterOptions &rOpt = SvtFilterOptions::Get();
@@ -486,28 +489,43 @@ sal_uInt16 SwWW8ImplReader::End_Field()
             }
         }
         break;
-#if defined(WW_NATIVE_TOC)
-        case 8: // TOX_INDEX
-        case 13: // TOX_CONTENT
-        case 88: // HYPERLINK
-        case 37: // REF
-        if (pPaM!=NULL && pPaM->GetPoint()!=NULL) {
+            // Doing corresponding status management for TOC field, index field, hyperlink field and page reference field
+            case 13://TOX
+            case 8://index
+                if (mbLoadingTOCCache)
+                {
+                    maTOXEndCps.insert(nCP);
+                    mbLoadingTOCCache = false;
+                    if ( pPaM->End() &&
+                         pPaM->End()->nNode.GetNode().GetTxtNode() &&
+                         pPaM->End()->nNode.GetNode().GetTxtNode()->Len() == 0 )
+                    {
+                            JoinNode(*pPaM);
+                    }
+                    else
+                    {
+                            mbCareLastParaEndInToc = true;
+                    }
 
-            SwPosition aEndPos = *pPaM->GetPoint();
-            SwPaM aFldPam( maFieldStack.back().GetPtNode(), maFieldStack.back().GetPtCntnt(), aEndPos.nNode, aEndPos.nContent.GetIndex());
-            SwFieldBookmark *pFieldmark=(SwFieldBookmark*)rDoc.makeFieldBookmark(aFldPam, maFieldStack.back().GetBookmarkName(), maFieldStack.back().GetBookmarkType());
-            OSL_ENSURE(pFieldmark!=NULL, "hmmm; why was the bookmark not created?");
-            if (pFieldmark!=NULL) {
-                const IFieldmark::parameter_map_t& pParametersToAdd = maFieldStack.back().getParameters();
-                pFieldmark->GetParameters()->insert(pParameters.begin(), pParameters.end());
-            }
-        }
-        break;
-#else
+                    if (mpPosAfterTOC)
+                    {
+                        *pPaM = *mpPosAfterTOC;
+                        delete mpPosAfterTOC;
+                        mpPosAfterTOC = 0;
+                    }
+                }
+                break;
+            case 37://REF
+                if (mbLoadingTOCCache && !mbLoadingTOCHyperlink)
+                {
+                    pCtrlStck->SetAttr(*pPaM->GetPoint(),RES_TXTATR_INETFMT);
+                }
+                break;
             case 88:
+                if (mbLoadingTOCHyperlink)
+                    mbLoadingTOCHyperlink = false;
                 pCtrlStck->SetAttr(*pPaM->GetPoint(),RES_TXTATR_INETFMT);
-            break;
-#endif
+                break;
             case 36:
             case 68:
                 //Move outside the section associated with this type of field
@@ -592,10 +610,8 @@ bool AcceptableNestedField(sal_uInt16 nFieldCode)
 {
     switch (nFieldCode)
     {
-#if defined(WW_NATIVE_TOC)
-    case 8:  // allow recursive field in TOC...
-    case 13: // allow recursive field in TOC...
-#endif
+        case 8:  // allow recursive field in TOC...
+        case 13: // allow recursive field in TOC...
         case 36:
         case 68:
         case 79:
@@ -2017,27 +2033,36 @@ eF_ResT SwWW8ImplReader::Read_F_PgRef( WW8FieldDesc*, OUString& rStr )
         const sal_Int32 nRet = aReadParam.SkipToNextToken();
         if ( nRet==-1 )
             break;
-        switch( nRet )
+        else if ( nRet == -2 && sOrigName.isEmpty() )
         {
-        case -2:
-            if( sOrigName.isEmpty() )
-                sOrigName = aReadParam.GetResult();
-            break;
+            sOrigName = aReadParam.GetResult();
         }
     }
 
     OUString sName(GetMappedBookmark(sOrigName));
 
-#if defined(WW_NATIVE_TOC)
-    if (1) {
-    OUString aBookmarkName("_REF");
-    maFieldStack.back().SetBookmarkName(aBookmarkName);
-    maFieldStack.back().SetBookmarkType(ODF_PAGEREF);
-    maFieldStack.back().AddParam(OUString(), sName);
-    return FLD_TEXT;
+    //loading page reference field in TOC
+    if (mbLoadingTOCCache )
+    {
+        //Step 1. Insert page ref representation as plain text
+        //Step 2. If there is no hyperlink settings for current toc, assign link to current ref area
+        if ( !mbLoadingTOCHyperlink)
+        {
+            OUString sURL, sTarget;
+            if (!sName.isEmpty())
+                sURL += OUString(INET_MARK_TOKEN) + sName;
+            SwFmtINetFmt aURL( sURL, sTarget );
+            OUString sLinkStyle("Index Link");
+            sal_uInt16 nPoolId =
+                SwStyleNameMapper::GetPoolIdFromUIName( sLinkStyle, nsSwGetPoolIdFromName::GET_POOLID_CHRFMT );
+            aURL.SetVisitedFmt(sLinkStyle);
+            aURL.SetINetFmt(sLinkStyle);
+            aURL.SetVisitedFmtId(nPoolId);
+            aURL.SetINetFmtId(nPoolId);
+            pCtrlStck->NewAttr( *pPaM->GetPoint(), aURL );
+        }
+        return FLD_TEXT;
     }
-#endif
-
 
     SwGetRefField aFld(
         (SwGetRefFieldType*)rDoc.GetSysFldType( RES_GETREFFLD ), sName,
@@ -2771,14 +2796,7 @@ static sal_uInt16 lcl_GetMaxValidWordTOCLevel(const SwForm &rForm)
 
 eF_ResT SwWW8ImplReader::Read_F_Tox( WW8FieldDesc* pF, OUString& rStr )
 {
-#if defined(WW_NATIVE_TOC)
-    if (1) {
-    OUString aBookmarkName("_TOC");
-    maFieldStack.back().SetBookmarkName(aBookmarkName);
-    maFieldStack.back().SetBookmarkType(ODF_TOC);
-    return FLD_TEXT;
-    }
-#endif
+    mbLoadingTOCCache = true;
 
     if (pF->nLRes < 3)
         return FLD_TEXT;      // ignore (#i25440#)
@@ -2906,6 +2924,7 @@ eF_ResT SwWW8ImplReader::Read_F_Tox( WW8FieldDesc* pF, OUString& rStr )
     case TOX_CONTENT:
         {
             bool bIsHyperlink = false;
+            bool bShowPage = true;
             // TOX_OUTLINELEVEL setzen wir genau dann, wenn
             // die Parameter \o in 1 bis 9 liegen
             // oder der Parameter \f existiert
@@ -3076,27 +3095,37 @@ eF_ResT SwWW8ImplReader::Read_F_Tox( WW8FieldDesc* pF, OUString& rStr )
                 }
             }
 
-            if (bIsHyperlink)
-            {
-                SwForm aForm(pBase->GetTOXForm());
-                sal_uInt16 nEnd = aForm.GetFormMax()-1;
-                SwFormToken aLinkStart(TOKEN_LINK_START);
-                SwFormToken aLinkEnd(TOKEN_LINK_END);
+            // For loading the expression of TOC field, we need to mapping its parameters to TOX entries tokens
+            // also include the hyperlinks and page references
+            SwFormToken aLinkStart(TOKEN_LINK_START);
+            SwFormToken aLinkEnd(TOKEN_LINK_END);
+            aLinkStart.sCharStyleName = "Index Link";
+            aLinkEnd.sCharStyleName = "Index Link";
+            SwForm aForm(pBase->GetTOXForm());
+            sal_uInt16 nEnd = aForm.GetFormMax()-1;
 
-                // -> #i21237#
-                for(sal_uInt16 nLevel = 1; nLevel <= nEnd; ++nLevel)
+            for(sal_uInt16 nLevel = 1; nLevel <= nEnd; ++nLevel)
+            {
+                SwFormTokens aPattern = aForm.GetPattern(nLevel);
+                if ( bIsHyperlink )
                 {
-                    SwFormTokens aPattern = aForm.GetPattern(nLevel);
-
                     aPattern.insert(aPattern.begin(), aLinkStart);
-                    aPattern.push_back(aLinkEnd);
-
-                    aForm.SetPattern(nLevel, aPattern);
-
                 }
-                // <- #i21237#
-                pBase->SetTOXForm(aForm);
+                else if ( bShowPage )
+                {
+                    for (SwFormTokens::iterator aItr = aPattern.begin();aItr!= aPattern.end();aItr++)
+                    {
+                        if (aItr->eTokenType == TOKEN_PAGE_NUMS)
+                        {
+                            aPattern.insert(aItr,aLinkStart);
+                            break;
+                        }
+                    }
+                }
+                aPattern.push_back(aLinkEnd);
+                aForm.SetPattern(nLevel, aPattern);
             }
+            pBase->SetTOXForm(aForm);
 
             if (!nMaxLevel)
                 nMaxLevel = WW8ListManager::nMaxLevel;
@@ -3177,11 +3206,11 @@ eF_ResT SwWW8ImplReader::Read_F_Tox( WW8FieldDesc* pF, OUString& rStr )
                         pattern which do not apply to illustration indices
                         */
                         SwForm aOldForm( pBase->GetTOXForm() );
-                        SwForm aForm( eType );
-                        sal_uInt16 nEnd = aForm.GetFormMax()-1;
+                        SwForm aNewForm( eType );
+                        sal_uInt16 nNewEnd = aNewForm.GetFormMax()-1;
 
                         // #i21237#
-                        for(sal_uInt16 nLevel = 1; nLevel <= nEnd; ++nLevel)
+                        for(sal_uInt16 nLevel = 1; nLevel <= nNewEnd; ++nLevel)
                         {
                             SwFormTokens aPattern = aOldForm.GetPattern(nLevel);
 
@@ -3191,13 +3220,13 @@ eF_ResT SwWW8ImplReader::Read_F_Tox( WW8FieldDesc* pF, OUString& rStr )
                             // table index imported with wrong page number format
                             aPattern.erase (new_end, aPattern.end() );
 
-                            aForm.SetPattern(nLevel, aPattern);
+                            aNewForm.SetPattern(nLevel, aPattern);
 
-                            aForm.SetTemplate( nLevel,
+                            aNewForm.SetTemplate( nLevel,
                                 aOldForm.GetTemplate(nLevel));
                         }
 
-                        pBase->SetTOXForm( aForm );
+                        pBase->SetTOXForm( aNewForm );
                     }
                     break;
                 default:
@@ -3213,15 +3242,23 @@ eF_ResT SwWW8ImplReader::Read_F_Tox( WW8FieldDesc* pF, OUString& rStr )
         break;
     } // ToxBase fertig
 
-    // Update fuer TOX anstossen
-    rDoc.SetUpdateTOX(true);
+    // no Update of TOC anymore as its actual content is imported and kept.
+    //rDoc.SetUpdateTOX(true);
 
     // #i21237# - propagate tab stops from paragraph styles
     // used in TOX to patterns of the TOX
 
     pBase->AdjustTabStops(rDoc, sal_True);
 
-    // #i10028# - inserting a toc implicltly acts like a parabreak in word and writer
+    // #i10028# - inserting a toc implictly acts like a parabreak in word and writer
+
+    if ( pPaM->End() &&
+         pPaM->End()->nNode.GetNode().GetTxtNode() &&
+         pPaM->End()->nNode.GetNode().GetTxtNode()->Len() != 0 )
+    {
+        mbCareFirstParaEndInToc = true;
+    }
+
     if (pPaM->GetPoint()->nContent.GetIndex())
         AppendTxtNode(*pPaM->GetPoint());
 
@@ -3252,14 +3289,22 @@ eF_ResT SwWW8ImplReader::Read_F_Tox( WW8FieldDesc* pF, OUString& rStr )
 
     rDoc.InsertTableOf(*pPaM->GetPoint(), *aFltTOX.GetBase());
 
-    //inserting a toc inserts a section before this point, so adjust pos
-    //for future page/section segment insertion
+    //The TOC field representation contents should be inserted into TOC section, but not after TOC section.
+    //So we need update the document position when loading TOC representation and after loading TOC;
+    if (mpPosAfterTOC)
+    {
+        delete mpPosAfterTOC;
+    }
+    mpPosAfterTOC = new SwPaM(*pPaM);
+    (*pPaM).Move(fnMoveBackward);
     SwPaM aRegion(*pPaM);
-    aRegion.Move(fnMoveBackward);
+
     OSL_ENSURE(rDoc.GetCurTOX(*aRegion.GetPoint()), "Misunderstood how toc works");
     if (SwTOXBase* pBase2 = (SwTOXBase*)rDoc.GetCurTOX(*aRegion.GetPoint()))
     {
-        if(nIndexCols>1)
+        pBase2->SetMSTOCExpression(rStr);
+
+        if ( nIndexCols > 1 )
         {
             // Set the column number for index
             SfxItemSet aSet( rDoc.GetAttrPool(), RES_COL, RES_COL );
@@ -3269,8 +3314,9 @@ eF_ResT SwWW8ImplReader::Read_F_Tox( WW8FieldDesc* pF, OUString& rStr )
             pBase2->SetAttrSet( aSet );
         }
 
-        maSectionManager.PrependedInlineNode(*pPaM->GetPoint(),
-            *aRegion.GetNode());
+        // inserting a toc inserts a section before this point, so adjust pos
+        // for future page/section segment insertion
+        maSectionManager.PrependedInlineNode( *mpPosAfterTOC->GetPoint(), *aRegion.GetNode() );
     }
 
     // Setze Ende in Stack
@@ -3278,7 +3324,11 @@ eF_ResT SwWW8ImplReader::Read_F_Tox( WW8FieldDesc* pF, OUString& rStr )
 
     if (!maApos.back()) //a para end in apo doesn't count
         bWasParaEnd = true;
-    return FLD_OK;
+
+    //Return FLD_TEXT, instead of FLD_OK
+    //FLD_TEXT means the following content, commonly indicate the field representation content should be parsed
+    //FLD_OK means the current field loading is finished. The rest part should be ignored.
+    return FLD_TEXT;
 }
 
 eF_ResT SwWW8ImplReader::Read_F_Shape(WW8FieldDesc* /*pF*/, OUString& /*rStr*/)
@@ -3293,17 +3343,7 @@ eF_ResT SwWW8ImplReader::Read_F_Shape(WW8FieldDesc* /*pF*/, OUString& /*rStr*/)
 
 eF_ResT SwWW8ImplReader::Read_F_Hyperlink( WW8FieldDesc* /*pF*/, OUString& rStr )
 {
-#if defined(WW_NATIVE_TOC)
-    if (1) {
-    OUString aBookmarkName("_HYPERLINK");
-    maFieldStack.back().SetBookmarkName(aBookmarkName);
-    maFieldStack.back().SetBookmarkType(ODF_HYPERLINK);
-    return FLD_TEXT;
-    }
-#endif
-
-    OUString sURL, sMark;
-    OUString sTarget;
+    OUString sURL, sTarget, sMark;
     bool bDataImport = false;
     //HYPERLINK "filename" [switches]
 
@@ -3338,6 +3378,10 @@ eF_ResT SwWW8ImplReader::Read_F_Hyperlink( WW8FieldDesc* /*pF*/, OUString& rStr
                         if( sMark.endsWith("\""))
                             sMark = sMark.copy( 0, sMark.getLength() - 1 );
 
+                        if (mbLoadingTOCCache)
+                        {
+                            mbLoadingTOCHyperlink = true;//on loading a TOC field nested hyperlink field
+                        }
                     }
                     break;
                 case 't':
@@ -3362,6 +3406,17 @@ eF_ResT SwWW8ImplReader::Read_F_Hyperlink( WW8FieldDesc* /*pF*/, OUString& rStr
         ( sURL += OUString(INET_MARK_TOKEN) ) += sMark;
 
     SwFmtINetFmt aURL( sURL, sTarget );
+    // If on loading TOC field, change the default style into the "index link"
+    if (mbLoadingTOCCache)
+    {
+        OUString sLinkStyle("Index Link");
+        sal_uInt16 nPoolId =
+            SwStyleNameMapper::GetPoolIdFromUIName( sLinkStyle, nsSwGetPoolIdFromName::GET_POOLID_CHRFMT );
+        aURL.SetVisitedFmt(sLinkStyle);
+        aURL.SetINetFmt(sLinkStyle);
+        aURL.SetVisitedFmtId(nPoolId);
+        aURL.SetINetFmtId(nPoolId);
+    }
 
     //As an attribute this needs to be closed, and that'll happen from
     //EndExtSprm in conjunction with the maFieldStack If there are are flyfrms
diff --git a/sw/source/filter/ww8/ww8par6.cxx b/sw/source/filter/ww8/ww8par6.cxx
index 3e13770..14e9cdf 100644
--- a/sw/source/filter/ww8/ww8par6.cxx
+++ b/sw/source/filter/ww8/ww8par6.cxx
@@ -3723,6 +3723,15 @@ void SwWW8ImplReader::Read_CColl( sal_uInt16, const sal_uInt8* pData, short nLen
         || vColl[nId].bColl )              // oder Para-Style ?
         return;                             // dann ignorieren
 
+    // if current on loading a TOC field, and current trying to apply a hyperlink character style,
+    // just ignore. For the hyperlinks inside TOC in MS Word is not same with a common hyperlink
+    // Character styles: without underline and blue font color. And such type style will be applied in others
+    // processes.
+    if (mbLoadingTOCCache && vColl[nId].GetWWStyleId() == ww::stiHyperlink)
+    {
+        return;
+    }
+
     NewAttr( SwFmtCharFmt( (SwCharFmt*)vColl[nId].pFmt ) );
     nCharFmt = (short) nId;
 }
diff --git a/sw/source/filter/ww8/ww8scan.cxx b/sw/source/filter/ww8/ww8scan.cxx
index c89faf7..5a6d79c 100644
--- a/sw/source/filter/ww8/ww8scan.cxx
+++ b/sw/source/filter/ww8/ww8scan.cxx
@@ -3703,7 +3703,7 @@ bool WW8PLCFx_FLD::StartPosIsFieldStart()
     return true;
 }
 
-bool WW8PLCFx_FLD::EndPosIsFieldEnd()
+bool WW8PLCFx_FLD::EndPosIsFieldEnd(WW8_CP& nCP)
 {
     bool bRet = false;
 
@@ -3716,7 +3716,10 @@ bool WW8PLCFx_FLD::EndPosIsFieldEnd()
         void* pData;
         sal_Int32 nTest;
         if ( pPLCF->Get(nTest, pData) && ((((sal_uInt8*)pData)[0] & 0x1f) == 0x15) )
+        {
+            nCP = nTest;
             bRet = true;
+        }
 
         pPLCF->SetIdx(n);
     }
@@ -4026,7 +4029,14 @@ void WW8PLCFx_Book::advance()
         else if( l1 < l0 )
             nIsEnd = 1;
         else
-            nIsEnd = ( nIsEnd ) ? 0 : 1;
+        {
+            const void * p = pBook[0]->GetData(pBook[0]->GetIdx());
+            long nPairFor = (p == NULL)? 0L : SVBT16ToShort(*((SVBT16*) p));
+            if (nPairFor == pBook[1]->GetIdx())
+                nIsEnd = 0;
+            else
+                nIsEnd = ( nIsEnd ) ? 0 : 1;
+        }
     }
 }
 
diff --git a/sw/source/filter/ww8/ww8scan.hxx b/sw/source/filter/ww8/ww8scan.hxx
index e6fa8c2..4f7e06e 100644
--- a/sw/source/filter/ww8/ww8scan.hxx
+++ b/sw/source/filter/ww8/ww8scan.hxx
@@ -706,7 +706,7 @@ public:
     virtual void GetSprms(WW8PLCFxDesc* p);
     virtual void advance();
     bool StartPosIsFieldStart();
-    bool EndPosIsFieldEnd();
+    bool EndPosIsFieldEnd(WW8_CP&);
     bool GetPara(long nIdx, WW8FieldDesc& rF);
 };
 
diff --git a/sw/source/ui/index/toxmgr.cxx b/sw/source/ui/index/toxmgr.cxx
index f022302..eb8fdf0 100644
--- a/sw/source/ui/index/toxmgr.cxx
+++ b/sw/source/ui/index/toxmgr.cxx
@@ -449,7 +449,9 @@ sal_Bool SwTOXMgr::UpdateOrInsertTOX(const SwTOXDescription& rDesc,
         if (pNewTOX != NULL) // => pTOX != NULL
             pDoc->ChgTOX(*pTOX, *pNewTOX);
 
+        pTOX->DisableKeepExpression();
         bRet = pSh->UpdateTableOf(*pTOX, pSet);
+        pTOX->EnableKeepExpression();
 
         if (pDoc->GetIDocumentUndoRedo().DoesUndo())
         {


More information about the Libreoffice-commits mailing list