[PATCH] solve fdo54819

Maxime de Roucy (via Code Review) gerrit at gerrit.libreoffice.org
Tue Apr 23 08:48:31 PDT 2013


Hi,

I have submitted a patch for review:

    https://gerrit.libreoffice.org/3583

To pull it, you can do:

    git pull ssh://gerrit.libreoffice.org:29418/core refs/changes/83/3583/1

solve fdo54819

Better handling of format in paragraph linked to deletion redline.
Format changes are now transmit to next and previews paragraphs in case
they are linked by deletion redline.

Change-Id: I989d3f9e56503ddc6280d134ed433b8af94ed052
---
A sw/inc/docRecurseThroughLinkedRedline.hxx
M sw/inc/node.hxx
M sw/source/core/doc/docredln.cxx
M sw/source/core/docnode/node.cxx
M sw/source/core/txtnode/ndtxt.cxx
5 files changed, 763 insertions(+), 300 deletions(-)



diff --git a/sw/inc/docRecurseThroughLinkedRedline.hxx b/sw/inc/docRecurseThroughLinkedRedline.hxx
new file mode 100644
index 0000000..e8cdbb8
--- /dev/null
+++ b/sw/inc/docRecurseThroughLinkedRedline.hxx
@@ -0,0 +1,306 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ *   Licensed to the Apache Software Foundation (ASF) under one or more
+ *   contributor license agreements. See the NOTICE file distributed
+ *   with this work for additional information regarding copyright
+ *   ownership. The ASF licenses this file to you under the Apache
+ *   License, Version 2.0 (the "License"); you may not use this file
+ *   except in compliance with the License. You may obtain a copy of
+ *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef SW_DOCRECURSETHROUGHLINKEDREDLINE_HX
+#define SW_DOCRECURSETHROUGHLINKEDREDLINE_HX
+
+#include <redline.hxx>
+#include <node.hxx>
+
+// wait for c++11 variadic template to merge all this ugly copy/past into one template
+
+template<typename T>
+void SwCntntNode::RecurseThroughLinkedRedline(const T methode)
+{
+    // if the redline table isn't empty and the redlines are shown
+    const SwRedlineTbl& rRedlineTbl = GetDoc()->GetRedlineTbl();
+    if ((GetDoc()->GetRedlineMode() & nsRedlineMode_t::REDLINE_SHOW_MASK) && rRedlineTbl.size() != 0)
+    {
+        // get the start start and end position of the current node
+        SwPosition aNodeStart = SwPosition(*this);
+        SwPosition aNodeEnd   = SwPosition(*this, Len());
+
+        // loop through the redline table
+        unsigned int nRedlineIndex = 0;
+        while (nRedlineIndex < rRedlineTbl.size())
+        {
+            // if the current redline is a deletion redline and it contain the start or the end
+            // of the current node
+            if ((rRedlineTbl[ nRedlineIndex ]->GetType() & nsRedlineType_t::REDLINE_DELETE) &&
+                    (rRedlineTbl[ nRedlineIndex ]->ContainsPosition(aNodeStart) ||
+                     rRedlineTbl[ nRedlineIndex ]->ContainsPosition(aNodeEnd)))
+            {
+                // get the start position of the first and last node of the redline
+                SwPosition aRedlineFirstNodeStart = SwPosition(rRedlineTbl[ nRedlineIndex ]->Start()->nNode.GetNode());
+                SwPosition aRedlineLastNodeStart  = SwPosition(rRedlineTbl[ nRedlineIndex ]->End()->nNode.GetNode());
+
+                // if the redline impact only one node
+                if (aRedlineFirstNodeStart == aRedlineLastNodeStart)
+                {
+                    // nothing to do…
+                    // (it doesn't make sense to copy the format of a node to past it on the same node)
+                    // we continu with the next redline
+                    ++nRedlineIndex;
+                    continue;
+                }
+
+                // unless the only direction handled is "preview"
+                // or the current node is in the middle of the redline (it is not the first node of the redline)
+                if(m_eHandleRedlineDirection != SwCntntNode::REDLINE_DIRECTION_PREVIEW && aNodeStart == aRedlineFirstNodeStart)
+                {
+                    // get the first node of the redline
+                    SwCntntNode* pRedlineFirstNode = aRedlineLastNodeStart.nNode.GetNode().GetCntntNode();
+
+                    if (pRedlineFirstNode != NULL)
+                    {
+                        // limit the recurse redline direction to "next", explain :
+                        // "methode" will call RecurseThroughLinkedRedline, if we don't limit the direction
+                        // the RecurseThroughLinkedRedline function will re-call "methode" on the current
+                        // node
+                        // → infinit loop
+                        pRedlineFirstNode->m_eHandleRedlineDirection = SwCntntNode::REDLINE_DIRECTION_NEXT;
+
+                        // call "methode" (modify the format) on the first node of the redline
+                        (pRedlineFirstNode->*methode)();
+
+                        // "methode" is finished, next call to RecurseThroughLinkedRedline have to
+                        // be able to go on both direction
+                        pRedlineFirstNode->m_eHandleRedlineDirection = SwCntntNode::REDLINE_DIRECTION_BOTH;
+                    }
+                }
+                // unless the only direction handled is "next"
+                // or the current node is in the middle of the redline (it is not the last node of the redline)
+                else if (m_eHandleRedlineDirection != SwCntntNode::REDLINE_DIRECTION_NEXT && aNodeStart == aRedlineLastNodeStart)
+                {
+                    // get the last node of the redline
+                    SwCntntNode* pRedlineLastNode = aRedlineFirstNodeStart.nNode.GetNode().GetCntntNode();
+
+                    if (pRedlineLastNode != NULL)
+                    {
+                        // limit the recurse redline direction to "preview" (see above)
+                        pRedlineLastNode->m_eHandleRedlineDirection = SwCntntNode::REDLINE_DIRECTION_PREVIEW;
+                        // call "methode" (modify the format) on the last node of the redline
+                        (pRedlineLastNode->*methode)();
+                        // "methode" is finished, next call to RecurseThroughLinkedRedline have to
+                        // be able to go on both direction
+                        pRedlineLastNode->m_eHandleRedlineDirection = SwCntntNode::REDLINE_DIRECTION_BOTH;
+                    }
+                }
+            }
+            // the current redline is beyond the current node
+            else if (aNodeEnd < *(rRedlineTbl[ nRedlineIndex ]->Start()))
+            {
+                // no need to continu the loop : all the next redline will also be beyond
+                // the current node (the redline table is sorted).
+                break;
+            }
+
+            // goto the next redline in the redline table
+            ++nRedlineIndex;
+        }
+    }
+}
+
+template<typename T, typename U>
+void SwCntntNode::RecurseThroughLinkedRedline(const T methode, U arg1)
+{
+    // if the redline table isn't empty and the redlines are shown
+    const SwRedlineTbl& rRedlineTbl = GetDoc()->GetRedlineTbl();
+    if ((GetDoc()->GetRedlineMode() & nsRedlineMode_t::REDLINE_SHOW_MASK) && rRedlineTbl.size() != 0)
+    {
+        // get the start start and end position of the current node
+        SwPosition aNodeStart = SwPosition(*this);
+        SwPosition aNodeEnd   = SwPosition(*this, Len());
+
+        // loop through the redline table
+        unsigned int nRedlineIndex = 0;
+        while (nRedlineIndex < rRedlineTbl.size())
+        {
+            // if the current redline is a deletion redline and it contain the start or the end
+            // of the current node
+            if ((rRedlineTbl[ nRedlineIndex ]->GetType() & nsRedlineType_t::REDLINE_DELETE) &&
+                    (rRedlineTbl[ nRedlineIndex ]->ContainsPosition(aNodeStart) ||
+                     rRedlineTbl[ nRedlineIndex ]->ContainsPosition(aNodeEnd)))
+            {
+                // get the start position of the first and last node of the redline
+                SwPosition aRedlineFirstNodeStart = SwPosition(rRedlineTbl[ nRedlineIndex ]->Start()->nNode.GetNode());
+                SwPosition aRedlineLastNodeStart  = SwPosition(rRedlineTbl[ nRedlineIndex ]->End()->nNode.GetNode());
+
+                // if the redline impact only one node
+                if (aRedlineFirstNodeStart == aRedlineLastNodeStart)
+                {
+                    // nothing to do…
+                    // (it doesn't make sense to copy the format of a node to past it on the same node)
+                    // we continu with the next redline
+                    ++nRedlineIndex;
+                    continue;
+                }
+
+                // unless the only direction handled is "preview"
+                // or the current node is in the middle of the redline (it is not the first node of the redline)
+                if(m_eHandleRedlineDirection != SwCntntNode::REDLINE_DIRECTION_PREVIEW && aNodeStart == aRedlineFirstNodeStart)
+                {
+                    // get the first node of the redline
+                    SwCntntNode* pRedlineFirstNode = aRedlineLastNodeStart.nNode.GetNode().GetCntntNode();
+
+                    if (pRedlineFirstNode != NULL)
+                    {
+                        // limit the recurse redline direction to "next", explain :
+                        // "methode" will call RecurseThroughLinkedRedline, if we don't limit the direction
+                        // the RecurseThroughLinkedRedline function will re-call "methode" on the current
+                        // node
+                        // → infinit loop
+                        pRedlineFirstNode->m_eHandleRedlineDirection = SwCntntNode::REDLINE_DIRECTION_NEXT;
+
+                        // call "methode" (modify the format) on the first node of the redline
+                        (pRedlineFirstNode->*methode)(arg1);
+
+                        // "methode" is finished, next call to RecurseThroughLinkedRedline have to
+                        // be able to go on both direction
+                        pRedlineFirstNode->m_eHandleRedlineDirection = SwCntntNode::REDLINE_DIRECTION_BOTH;
+                    }
+                }
+                // unless the only direction handled is "next"
+                // or the current node is in the middle of the redline (it is not the last node of the redline)
+                else if (m_eHandleRedlineDirection != SwCntntNode::REDLINE_DIRECTION_NEXT && aNodeStart == aRedlineLastNodeStart)
+                {
+                    // get the last node of the redline
+                    SwCntntNode* pRedlineLastNode = aRedlineFirstNodeStart.nNode.GetNode().GetCntntNode();
+
+                    if (pRedlineLastNode != NULL)
+                    {
+                        // limit the recurse redline direction to "preview" (see above)
+                        pRedlineLastNode->m_eHandleRedlineDirection = SwCntntNode::REDLINE_DIRECTION_PREVIEW;
+                        // call "methode" (modify the format) on the last node of the redline
+                        (pRedlineLastNode->*methode)(arg1);
+                        // "methode" is finished, next call to RecurseThroughLinkedRedline have to
+                        // be able to go on both direction
+                        pRedlineLastNode->m_eHandleRedlineDirection = SwCntntNode::REDLINE_DIRECTION_BOTH;
+                    }
+                }
+            }
+            // the current redline is beyond the current node
+            else if (aNodeEnd < *(rRedlineTbl[ nRedlineIndex ]->Start()))
+            {
+                // no need to continu the loop : all the next redline will also be beyond
+                // the current node (the redline table is sorted).
+                break;
+            }
+
+            // goto the next redline in the redline table
+            ++nRedlineIndex;
+        }
+    }
+}
+
+template<typename T, typename U, typename V>
+void SwCntntNode::RecurseThroughLinkedRedline(const T methode, U arg1, V arg2)
+{
+    // if the redline table isn't empty and the redlines are shown
+    const SwRedlineTbl& rRedlineTbl = GetDoc()->GetRedlineTbl();
+    if ((GetDoc()->GetRedlineMode() & nsRedlineMode_t::REDLINE_SHOW_MASK) && rRedlineTbl.size() != 0)
+    {
+        // get the start start and end position of the current node
+        SwPosition aNodeStart = SwPosition(*this);
+        SwPosition aNodeEnd   = SwPosition(*this, Len());
+
+        // loop through the redline table
+        unsigned int nRedlineIndex = 0;
+        while (nRedlineIndex < rRedlineTbl.size())
+        {
+            // if the current redline is a deletion redline and it contain the start or the end
+            // of the current node
+            if ((rRedlineTbl[ nRedlineIndex ]->GetType() & nsRedlineType_t::REDLINE_DELETE) &&
+                    (rRedlineTbl[ nRedlineIndex ]->ContainsPosition(aNodeStart) ||
+                     rRedlineTbl[ nRedlineIndex ]->ContainsPosition(aNodeEnd)))
+            {
+                // get the start position of the first and last node of the redline
+                SwPosition aRedlineFirstNodeStart = SwPosition(rRedlineTbl[ nRedlineIndex ]->Start()->nNode.GetNode());
+                SwPosition aRedlineLastNodeStart  = SwPosition(rRedlineTbl[ nRedlineIndex ]->End()->nNode.GetNode());
+
+                // if the redline impact only one node
+                if (aRedlineFirstNodeStart == aRedlineLastNodeStart)
+                {
+                    // nothing to do…
+                    // (it doesn't make sense to copy the format of a node to past it on the same node)
+                    // we continu with the next redline
+                    ++nRedlineIndex;
+                    continue;
+                }
+
+                // unless the only direction handled is "preview"
+                // or the current node is in the middle of the redline (it is not the first node of the redline)
+                if(m_eHandleRedlineDirection != SwCntntNode::REDLINE_DIRECTION_PREVIEW && aNodeStart == aRedlineFirstNodeStart)
+                {
+                    // get the first node of the redline
+                    SwCntntNode* pRedlineFirstNode = aRedlineLastNodeStart.nNode.GetNode().GetCntntNode();
+
+                    if (pRedlineFirstNode != NULL)
+                    {
+                        // limit the recurse redline direction to "next", explain :
+                        // "methode" will call RecurseThroughLinkedRedline, if we don't limit the direction
+                        // the RecurseThroughLinkedRedline function will re-call "methode" on the current
+                        // node
+                        // → infinit loop
+                        pRedlineFirstNode->m_eHandleRedlineDirection = SwCntntNode::REDLINE_DIRECTION_NEXT;
+
+                        // call "methode" (modify the format) on the first node of the redline
+                        (pRedlineFirstNode->*methode)(arg1, arg2);
+
+                        // "methode" is finished, next call to RecurseThroughLinkedRedline have to
+                        // be able to go on both direction
+                        pRedlineFirstNode->m_eHandleRedlineDirection = SwCntntNode::REDLINE_DIRECTION_BOTH;
+                    }
+                }
+                // unless the only direction handled is "next"
+                // or the current node is in the middle of the redline (it is not the last node of the redline)
+                else if (m_eHandleRedlineDirection != SwCntntNode::REDLINE_DIRECTION_NEXT && aNodeStart == aRedlineLastNodeStart)
+                {
+                    // get the last node of the redline
+                    SwCntntNode* pRedlineLastNode = aRedlineFirstNodeStart.nNode.GetNode().GetCntntNode();
+
+                    if (pRedlineLastNode != NULL)
+                    {
+                        // limit the recurse redline direction to "preview" (see above)
+                        pRedlineLastNode->m_eHandleRedlineDirection = SwCntntNode::REDLINE_DIRECTION_PREVIEW;
+                        // call "methode" (modify the format) on the last node of the redline
+                        (pRedlineLastNode->*methode)(arg1, arg2);
+                        // "methode" is finished, next call to RecurseThroughLinkedRedline have to
+                        // be able to go on both direction
+                        pRedlineLastNode->m_eHandleRedlineDirection = SwCntntNode::REDLINE_DIRECTION_BOTH;
+                    }
+                }
+            }
+            // the current redline is beyond the current node
+            else if (aNodeEnd < *(rRedlineTbl[ nRedlineIndex ]->Start()))
+            {
+                // no need to continu the loop : all the next redline will also be beyond
+                // the current node (the redline table is sorted).
+                break;
+            }
+
+            // goto the next redline in the redline table
+            ++nRedlineIndex;
+        }
+    }
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/inc/node.hxx b/sw/inc/node.hxx
index 7690cf8..c4efb5e 100644
--- a/sw/inc/node.hxx
+++ b/sw/inc/node.hxx
@@ -381,6 +381,52 @@
 
    virtual void Modify( const SfxPoolItem* pOld, const SfxPoolItem *pNew);
 
+   /** used by RecurseThroughLinkedRedline\n
+    *  § == paragraph ; RecurseThroughLinkedRedline is launch on the 2nd §.\n
+    *  1st § begining <begin 1st deletion redline> end of 1st § ¶\n
+    *  2nd § begining <end 1st deletion redline> middle of 2nd § <begin 2nd deletion redline> end of 2nd § ¶\n
+    *  3rd § begining <end 2nd deletion redline> end of 3rd § ¶ */
+    enum HandleRedlineDirection {
+        /// RecurseThroughLinkedRedline handle preview (1st) and next (3rd) deleted §
+        REDLINE_DIRECTION_BOTH,
+        /// RecurseThroughLinkedRedline handle only the preview (1st) deleted § (it's as the 2nd deletion redline doesn't exist)
+        REDLINE_DIRECTION_PREVIEW,
+        /// RecurseThroughLinkedRedline handle only the next (3rd) deleted § (it's as the 1st deletion redline doesn't exist)
+        REDLINE_DIRECTION_NEXT};
+
+    /// see HandleRedlineDirection
+    enum HandleRedlineDirection m_eHandleRedlineDirection;
+    /** § == paragraph ; RecurseThroughLinkedRedline is launch on the 2nd §.\n
+     *  1st § begining <begin 1st deletion redline> end of 1st § ¶\n
+     *  2nd § begining <end 1st deletion redline> middle of 2nd § <begin 2nd deletion redline> end of 2nd § ¶\n
+     *  3rd § begining <end 2nd deletion redline> end of 3rd § ¶\n
+     *  \n
+     *  The format of 1st, 2nd and 3rd should be the same since ¶ are deleted by the two redlines.
+     *  RecurseThroughLinkedRedline is used in format modification functions to transmit the modifications to
+     *  previews and next § in case they are linked by deletion redlines.
+     *
+     *  @param  methode  the current format modification function where RecurseThroughLinkedRedline is called
+     */
+    template<typename T>
+    void RecurseThroughLinkedRedline(const T methode);
+    /** copy of RecurseThroughLinkedRedline(const T methode)
+     *  wait for c++11 variadic template so we can merge all those functions
+     *
+     *  @param  methode  The current format modification function where RecurseThroughLinkedRedline is called
+     *  @param  arg1     The first argument of the current format modification function where RecurseThroughLinkedRedline is called
+     */
+    template<typename T, typename U>
+    void RecurseThroughLinkedRedline(const T methode, U arg1);
+    /** copy of RecurseThroughLinkedRedline(const T methode)
+     *  wait for c++11 variadic template so we can merge all those functions
+     *
+     *  @param  methode  The current format modification function where RecurseThroughLinkedRedline is called
+     *  @param  arg1     The first argument of the current format modification function where RecurseThroughLinkedRedline is called
+     *  @param  arg2     The second argument of the current format modification function where RecurseThroughLinkedRedline is called
+     */
+    template<typename T, typename U, typename V>
+    void RecurseThroughLinkedRedline(const T methode, U arg1, V arg2);
+
 public:
     TYPEINFO();     /// Already contained in base class Client.
 
diff --git a/sw/source/core/doc/docredln.cxx b/sw/source/core/doc/docredln.cxx
index 6f3e18b..7a8b948 100644
--- a/sw/source/core/doc/docredln.cxx
+++ b/sw/source/core/doc/docredln.cxx
@@ -309,8 +309,9 @@
         }
 
         SwPosition* pStt = pNewRedl->Start(),
-                  * pEnd = pStt == pNewRedl->GetPoint() ? pNewRedl->GetMark()
-                                                        : pNewRedl->GetPoint();
+                  * pEnd = (pStt == pNewRedl->GetPoint()) ? pNewRedl->GetMark()
+                                                          : pNewRedl->GetPoint();
+
         {
             SwTxtNode* pTxtNode = pStt->nNode.GetNode().GetTxtNode();
             if( pTxtNode == NULL )
@@ -321,13 +322,10 @@
                     pStt->nContent = 0;
                 }
             }
-            else
+            else if( pStt->nContent > pTxtNode->Len() )
             {
-                if( pStt->nContent > pTxtNode->Len() )
-                {
-                    OSL_ENSURE( false, "Redline start: index behind text" );
-                    pStt->nContent = pTxtNode->Len();
-                }
+                OSL_ENSURE( false, "Redline start: index behind text" );
+                pStt->nContent = pTxtNode->Len();
             }
             pTxtNode = pEnd->nNode.GetNode().GetTxtNode();
             if( pTxtNode == NULL )
@@ -338,28 +336,29 @@
                     pEnd->nContent = 0;
                 }
             }
-            else
+            else if( pEnd->nContent > pTxtNode->Len() )
             {
-                if( pEnd->nContent > pTxtNode->Len() )
-                {
-                    OSL_ENSURE( false, "Redline end: index behind text" );
-                    pEnd->nContent = pTxtNode->Len();
-                }
+                OSL_ENSURE( false, "Redline end: index behind text" );
+                pEnd->nContent = pTxtNode->Len();
             }
         }
+
+        // Do not insert empty redlines
         if( ( *pStt == *pEnd ) &&
             ( pNewRedl->GetContentIdx() == NULL ) )
-        {   // Do not insert empty redlines
+        {
             delete pNewRedl;
             return false;
         }
+
         bool bCompress = false;
         sal_uInt16 n = 0;
+
         // look up the first Redline for the starting position
         if( !GetRedline( *pStt, &n ) && n )
             --n;
-        bool bDec = false;
 
+        bool bDec = false;
         for( ; pNewRedl && n < mpRedlineTbl->size(); bDec ? n : ++n )
         {
             bDec = false;
@@ -1211,7 +1210,38 @@
                 pNewRedl = 0;
             }
             else
+            {
+                // redline creation
+                // if the redline is a deletion redline
+                // copy the format of the first paragraph into the last
+                // as when redlining is off
+                if (pNewRedl->GetType() & nsRedlineType_t::REDLINE_DELETE)
+                {
+                    SwCntntNode* pRedlineLastNode = pNewRedl->End()->nNode.GetNode().GetCntntNode();
+                    SwPosition aRedlineLastNodeEnd = SwPosition(*pRedlineLastNode, pRedlineLastNode->Len());
+
+                    SwCntntNode* pRedlineFirstNode = pNewRedl->Start()->nNode.GetNode().GetCntntNode();
+
+                    // don't copy the format if the first and the last redline nodes are the same node
+                    // or if the redline end at the end of the last node.
+                    if (pRedlineFirstNode != pRedlineLastNode && aRedlineLastNodeEnd != *(pNewRedl->End()))
+                    {
+                        // TODO handle undo
+                        // copy the named paragraph formats of the first paragraph into the last
+                        SwFmtColl* pFirstNodeFmtColl = pRedlineFirstNode->GetFmtColl();
+                        pRedlineLastNode->ChgFmtColl( pFirstNodeFmtColl );
+
+                        // copy the direct paragraph formats of the first paragraph into the last
+                        SfxItemSet aFirstNodeAutoParagraphFormat = SfxItemSet(*mpAttrPool, RES_PARATR_BEGIN, RES_PARATR_END -1, 0);
+                        pRedlineFirstNode->GetAttr(aFirstNodeAutoParagraphFormat);
+                        pRedlineLastNode->ResetAttr(RES_PARATR_BEGIN, RES_PARATR_END -1);
+                        pRedlineLastNode->SetAttr(aFirstNodeAutoParagraphFormat);
+
+                    }
+                }
+
                 mpRedlineTbl->Insert( pNewRedl );
+            }
         }
 
         if( bCompress )
@@ -1675,13 +1705,19 @@
 
             if( pDelStt && pDelEnd )
             {
+                // create a SwPaM matching the redline
                 SwPaM aPam( *pDelStt, *pDelEnd );
+                // get the first and last node "touched" by the redline
                 SwCntntNode* pCSttNd = pDelStt->nNode.GetNode().GetCntntNode();
                 SwCntntNode* pCEndNd = pDelEnd->nNode.GetNode().GetCntntNode();
+
+                // no need to copy the format of pCSttNd in pCEndNd snce it's
+                // done during the format modification or redline creation
 
                 if( bDelRedl )
                     delete pRedl;
 
+                // disable mode ON and IGNORE
                 RedlineMode_t eOld = rDoc.GetRedlineMode();
                 rDoc.SetRedlineMode_intern( (RedlineMode_t)(eOld & ~(nsRedlineMode_t::REDLINE_ON | nsRedlineMode_t::REDLINE_IGNORE)));
 
@@ -3262,7 +3298,7 @@
             aHt.nEnd = (n == nEndNd)
                 ? nEndCnt
                 : static_cast<SwTxtNode*>(pNd)->GetTxt().getLength();
-            ((SwTxtNode*)pNd)->ModifyNotification( &aHt, &aHt );
+            static_cast<SwTxtNode*>(pNd)->ModifyNotification( &aHt, &aHt );
         }
     }
 }
@@ -3304,258 +3340,273 @@
 
 void SwRedline::MoveToSection()
 {
-    if( !pCntntSect )
+    if( pCntntSect )
     {
-        const SwPosition* pStt = Start(),
-                        * pEnd = pStt == GetPoint() ? GetMark() : GetPoint();
+        InvalidateRange();
+        return;
+    }
 
-        SwDoc* pDoc = GetDoc();
-        SwPaM aPam( *pStt, *pEnd );
-        SwCntntNode* pCSttNd = pStt->nNode.GetNode().GetCntntNode();
-        SwCntntNode* pCEndNd = pEnd->nNode.GetNode().GetCntntNode();
+    const SwPosition* pStt = Start(),
+                    * pEnd = pStt == GetPoint() ? GetMark() : GetPoint();
 
-        if( !pCSttNd )
+    SwDoc* pDoc = GetDoc();
+    SwPaM aPam( *pStt, *pEnd );
+    SwCntntNode* pCSttNd = pStt->nNode.GetNode().GetCntntNode();
+    SwCntntNode* pCEndNd = pEnd->nNode.GetNode().GetCntntNode();
+
+    if( !pCSttNd )
+    {
+        // In order to not move other Redlines' indices, we set them
+        // to the end (is exclusive)
+        const SwRedlineTbl& rTbl = pDoc->GetRedlineTbl();
+        for( sal_uInt16 n = 0; n < rTbl.size(); ++n )
         {
-            // In order to not move other Redlines' indices, we set them
-            // to the end (is exclusive)
-            const SwRedlineTbl& rTbl = pDoc->GetRedlineTbl();
-            for( sal_uInt16 n = 0; n < rTbl.size(); ++n )
-            {
-                SwRedline* pRedl = rTbl[ n ];
-                if( pRedl->GetBound(sal_True) == *pStt )
-                    pRedl->GetBound(sal_True) = *pEnd;
-                if( pRedl->GetBound(sal_False) == *pStt )
-                    pRedl->GetBound(sal_False) = *pEnd;
-            }
+            SwRedline* pRedl = rTbl[ n ];
+            if( pRedl->GetBound(sal_True) == *pStt )
+                pRedl->GetBound(sal_True) = *pEnd;
+            if( pRedl->GetBound(sal_False) == *pStt )
+                pRedl->GetBound(sal_False) = *pEnd;
         }
+    }
 
-        SwStartNode* pSttNd;
-        SwNodes& rNds = pDoc->GetNodes();
-        if( pCSttNd || pCEndNd )
-        {
-            SwTxtFmtColl* pColl = (pCSttNd && pCSttNd->IsTxtNode() )
-                                    ? ((SwTxtNode*)pCSttNd)->GetTxtColl()
-                                    : (pCEndNd && pCEndNd->IsTxtNode() )
-                                        ? ((SwTxtNode*)pCEndNd)->GetTxtColl()
-                                        : pDoc->GetTxtCollFromPool(
-                                                RES_POOLCOLL_STANDARD );
+    SwStartNode* pSttNd;
+    SwNodes& rNds = pDoc->GetNodes();
+    if( pCSttNd || pCEndNd )
+    {
+        SwTxtFmtColl* pColl = (pCSttNd && pCSttNd->IsTxtNode() )
+            ? ((SwTxtNode*)pCSttNd)->GetTxtColl()
+            : (pCEndNd && pCEndNd->IsTxtNode() )
+            ? ((SwTxtNode*)pCEndNd)->GetTxtColl()
+            : pDoc->GetTxtCollFromPool(
+                    RES_POOLCOLL_STANDARD );
 
-            pSttNd = rNds.MakeTextSection( SwNodeIndex( rNds.GetEndOfRedlines() ),
-                                            SwNormalStartNode, pColl );
-            SwTxtNode* pTxtNd = rNds[ pSttNd->GetIndex() + 1 ]->GetTxtNode();
+        pSttNd = rNds.MakeTextSection( SwNodeIndex( rNds.GetEndOfRedlines() ),
+                                                    SwNormalStartNode, pColl );
+        SwTxtNode* pTxtNd = rNds[ pSttNd->GetIndex() + 1 ]->GetTxtNode();
 
-            SwNodeIndex aNdIdx( *pTxtNd );
-            SwPosition aPos( aNdIdx, SwIndex( pTxtNd ));
-            if( pCSttNd && pCEndNd )
-                pDoc->MoveAndJoin( aPam, aPos, IDocumentContentOperations::DOC_MOVEDEFAULT );
-            else
-            {
-                if( pCSttNd && !pCEndNd )
-                    bDelLastPara = sal_True;
-                pDoc->MoveRange( aPam, aPos,
-                    IDocumentContentOperations::DOC_MOVEDEFAULT );
-            }
-        }
+        SwNodeIndex aNdIdx( *pTxtNd );
+        SwPosition aPos( aNdIdx, SwIndex( pTxtNd ));
+        if( pCSttNd && pCEndNd )
+            pDoc->MoveAndJoin( aPam, aPos, IDocumentContentOperations::DOC_MOVEDEFAULT );
         else
         {
-            pSttNd = rNds.MakeEmptySection( SwNodeIndex( rNds.GetEndOfRedlines() ),
-                                            SwNormalStartNode );
+            if( pCSttNd && !pCEndNd )
+                bDelLastPara = sal_True;
 
-            SwPosition aPos( *pSttNd->EndOfSectionNode() );
             pDoc->MoveRange( aPam, aPos,
-                IDocumentContentOperations::DOC_MOVEDEFAULT );
+                    IDocumentContentOperations::DOC_MOVEDEFAULT );
         }
-        pCntntSect = new SwNodeIndex( *pSttNd );
-
-        if( pStt == GetPoint() )
-            Exchange();
-
-        DeleteMark();
     }
     else
-        InvalidateRange();
+    {
+        pSttNd = rNds.MakeEmptySection( SwNodeIndex( rNds.GetEndOfRedlines() ),
+                SwNormalStartNode );
+
+        SwPosition aPos( *pSttNd->EndOfSectionNode() );
+        pDoc->MoveRange( aPam, aPos,
+                IDocumentContentOperations::DOC_MOVEDEFAULT );
+    }
+
+    pCntntSect = new SwNodeIndex( *pSttNd );
+
+    if( pStt == GetPoint() )
+        Exchange();
+
+    DeleteMark();
 }
 
 void SwRedline::CopyToSection()
 {
-    if( !pCntntSect )
-    {
-        const SwPosition* pStt = Start(),
-                        * pEnd = pStt == GetPoint() ? GetMark() : GetPoint();
+    if( pCntntSect )
+        return;
 
-        SwCntntNode* pCSttNd = pStt->nNode.GetNode().GetCntntNode();
-        SwCntntNode* pCEndNd = pEnd->nNode.GetNode().GetCntntNode();
+    const SwPosition* pStt = Start(),
+                    * pEnd = pStt == GetPoint() ? GetMark() : GetPoint();
 
-        SwStartNode* pSttNd;
-        SwDoc* pDoc = GetDoc();
-        SwNodes& rNds = pDoc->GetNodes();
+    SwCntntNode* pCSttNd = pStt->nNode.GetNode().GetCntntNode();
+    SwCntntNode* pCEndNd = pEnd->nNode.GetNode().GetCntntNode();
 
-        sal_Bool bSaveCopyFlag = pDoc->IsCopyIsMove(),
+    SwStartNode* pSttNd;
+    SwDoc* pDoc = GetDoc();
+    SwNodes& rNds = pDoc->GetNodes();
+
+    sal_Bool bSaveCopyFlag   = pDoc->IsCopyIsMove(),
              bSaveRdlMoveFlg = pDoc->IsRedlineMove();
-        pDoc->SetCopyIsMove( sal_True );
+    pDoc->SetCopyIsMove( sal_True );
 
-        // The IsRedlineMove() flag causes the behaviour of the
-        // SwDoc::_CopyFlyInFly method to change, which will eventually be
-        // called by the pDoc->Copy line below (through SwDoc::_Copy,
-        // SwDoc::CopyWithFlyInFly). This rather obscure bugfix
-        // apparently never really worked.
-        pDoc->SetRedlineMove( pStt->nContent == 0 );
+    // The IsRedlineMove() flag causes the behaviour of the
+    // SwDoc::_CopyFlyInFly method to change, which will eventually be
+    // called by the pDoc->Copy line below (through SwDoc::_Copy,
+    // SwDoc::CopyWithFlyInFly). This rather obscure bugfix
+    // apparently never really worked.
+    pDoc->SetRedlineMove( pStt->nContent == 0 );
 
-        if( pCSttNd )
+    if( pCSttNd )
+    {
+        SwTxtFmtColl* pColl = (pCSttNd && pCSttNd->IsTxtNode() )
+            ? ((SwTxtNode*)pCSttNd)->GetTxtColl()
+            : pDoc->GetTxtCollFromPool(
+                    RES_POOLCOLL_STANDARD );
+
+        pSttNd = rNds.MakeTextSection( SwNodeIndex( rNds.GetEndOfRedlines() ),
+                SwNormalStartNode, pColl );
+
+        SwNodeIndex aNdIdx( *pSttNd, 1 );
+        SwTxtNode* pTxtNd = aNdIdx.GetNode().GetTxtNode();
+        SwPosition aPos( aNdIdx, SwIndex( pTxtNd ));
+        pDoc->CopyRange( *this, aPos, false );
+
+        // Take over the style from the EndNode if needed
+        // We don't want this in Doc::Copy
+        if( pCEndNd && pCEndNd != pCSttNd )
         {
-            SwTxtFmtColl* pColl = (pCSttNd && pCSttNd->IsTxtNode() )
-                                    ? ((SwTxtNode*)pCSttNd)->GetTxtColl()
-                                    : pDoc->GetTxtCollFromPool(
-                                                RES_POOLCOLL_STANDARD );
-
-            pSttNd = rNds.MakeTextSection( SwNodeIndex( rNds.GetEndOfRedlines() ),
-                                            SwNormalStartNode, pColl );
-
-            SwNodeIndex aNdIdx( *pSttNd, 1 );
-            SwTxtNode* pTxtNd = aNdIdx.GetNode().GetTxtNode();
-            SwPosition aPos( aNdIdx, SwIndex( pTxtNd ));
-            pDoc->CopyRange( *this, aPos, false );
-
-            // Take over the style from the EndNode if needed
-            // We don't want this in Doc::Copy
-            if( pCEndNd && pCEndNd != pCSttNd )
+            SwCntntNode* pDestNd = aPos.nNode.GetNode().GetCntntNode();
+            if( pDestNd )
             {
-                SwCntntNode* pDestNd = aPos.nNode.GetNode().GetCntntNode();
-                if( pDestNd )
-                {
-                    if( pDestNd->IsTxtNode() && pCEndNd->IsTxtNode() )
-                        ((SwTxtNode*)pCEndNd)->CopyCollFmt(
-                                            *(SwTxtNode*)pDestNd );
-                    else
-                        pDestNd->ChgFmtColl( pCEndNd->GetFmtColl() );
-                }
+                if( pDestNd->IsTxtNode() && pCEndNd->IsTxtNode() )
+                    ((SwTxtNode*)pCEndNd)->CopyCollFmt(
+                        *(SwTxtNode*)pDestNd );
+                else
+                    pDestNd->ChgFmtColl( pCEndNd->GetFmtColl() );
             }
+        }
+    }
+    else
+    {
+        pSttNd = rNds.MakeEmptySection( SwNodeIndex( rNds.GetEndOfRedlines() ),
+                SwNormalStartNode );
+
+        if( pCEndNd )
+        {
+            SwPosition aPos( *pSttNd->EndOfSectionNode() );
+            pDoc->CopyRange( *this, aPos, false );
         }
         else
         {
-            pSttNd = rNds.MakeEmptySection( SwNodeIndex( rNds.GetEndOfRedlines() ),
-                                            SwNormalStartNode );
-
-            if( pCEndNd )
-            {
-                SwPosition aPos( *pSttNd->EndOfSectionNode() );
-                pDoc->CopyRange( *this, aPos, false );
-            }
-            else
-            {
-                SwNodeIndex aInsPos( *pSttNd->EndOfSectionNode() );
-                SwNodeRange aRg( pStt->nNode, 0, pEnd->nNode, 1 );
-                pDoc->CopyWithFlyInFly( aRg, 0, aInsPos );
-            }
+            SwNodeIndex aInsPos( *pSttNd->EndOfSectionNode() );
+            SwNodeRange aRg( pStt->nNode, 0, pEnd->nNode, 1 );
+            pDoc->CopyWithFlyInFly( aRg, 0, aInsPos );
         }
-        pCntntSect = new SwNodeIndex( *pSttNd );
-
-        pDoc->SetCopyIsMove( bSaveCopyFlag );
-        pDoc->SetRedlineMove( bSaveRdlMoveFlg );
     }
+    pCntntSect = new SwNodeIndex( *pSttNd );
+
+    pDoc->SetCopyIsMove( bSaveCopyFlag );
+    pDoc->SetRedlineMove( bSaveRdlMoveFlg );
 }
 
 void SwRedline::DelCopyOfSection()
 {
-    if( pCntntSect )
+    if( !pCntntSect )
+        return;
+
+    const SwPosition* pStt = Start(),
+                    * pEnd = pStt == GetPoint() ? GetMark() : GetPoint();
+
+    SwDoc* pDoc = GetDoc();
+    SwPaM aPam( *pStt, *pEnd );
+    SwCntntNode* pCSttNd = pStt->nNode.GetNode().GetCntntNode();
+    SwCntntNode* pCEndNd = pEnd->nNode.GetNode().GetCntntNode();
+
+    if( !pCSttNd )
     {
-        const SwPosition* pStt = Start(),
-                        * pEnd = pStt == GetPoint() ? GetMark() : GetPoint();
-
-        SwDoc* pDoc = GetDoc();
-        SwPaM aPam( *pStt, *pEnd );
-        SwCntntNode* pCSttNd = pStt->nNode.GetNode().GetCntntNode();
-        SwCntntNode* pCEndNd = pEnd->nNode.GetNode().GetCntntNode();
-
-        if( !pCSttNd )
+        // In order to not move other Redlines' indices, we set them
+        // to the end (is exclusive)
+        const SwRedlineTbl& rTbl = pDoc->GetRedlineTbl();
+        for( sal_uInt16 n = 0; n < rTbl.size(); ++n )
         {
-            // In order to not move other Redlines' indices, we set them
-            // to the end (is exclusive)
-            const SwRedlineTbl& rTbl = pDoc->GetRedlineTbl();
-            for( sal_uInt16 n = 0; n < rTbl.size(); ++n )
-            {
-                SwRedline* pRedl = rTbl[ n ];
-                if( pRedl->GetBound(sal_True) == *pStt )
-                    pRedl->GetBound(sal_True) = *pEnd;
-                if( pRedl->GetBound(sal_False) == *pStt )
-                    pRedl->GetBound(sal_False) = *pEnd;
-            }
+            SwRedline* pRedl = rTbl[ n ];
+            if( pRedl->GetBound(sal_True) == *pStt )
+                pRedl->GetBound(sal_True) = *pEnd;
+            if( pRedl->GetBound(sal_False) == *pStt )
+                pRedl->GetBound(sal_False) = *pEnd;
         }
-
-        if( pCSttNd && pCEndNd )
-        {
-            // #i100466# - force a <join next> on <delete and join> operation
-            pDoc->DeleteAndJoin( aPam, true );
-        }
-        else if( pCSttNd || pCEndNd )
-        {
-            if( pCSttNd && !pCEndNd )
-                bDelLastPara = sal_True;
-            pDoc->DeleteRange( aPam );
-
-            if( bDelLastPara )
-            {
-                // To prevent dangling references to the paragraph to
-                // be deleted, redline that point into this paragraph should be
-                // moved to the new end position. Since redlines in the redline
-                // table are sorted and the pEnd position is an endnode (see
-                // bDelLastPara condition above), only redlines before the
-                // current ones can be affected.
-                const SwRedlineTbl& rTbl = pDoc->GetRedlineTbl();
-                sal_uInt16 n = rTbl.GetPos( this );
-                OSL_ENSURE( n != USHRT_MAX, "How strange. We don't exist!" );
-                for( bool bBreak = false; !bBreak && n > 0; )
-                {
-                    --n;
-                    bBreak = true;
-                    if( rTbl[ n ]->GetBound(sal_True) == *aPam.GetPoint() )
-                    {
-                        rTbl[ n ]->GetBound(sal_True) = *pEnd;
-                        bBreak = false;
-                    }
-                    if( rTbl[ n ]->GetBound(sal_False) == *aPam.GetPoint() )
-                    {
-                        rTbl[ n ]->GetBound(sal_False) = *pEnd;
-                        bBreak = false;
-                    }
-                }
-
-                SwPosition aEnd( *pEnd );
-                *GetPoint() = *pEnd;
-                *GetMark() = *pEnd;
-                DeleteMark();
-
-                aPam.GetBound( sal_True ).nContent.Assign( 0, 0 );
-                aPam.GetBound( sal_False ).nContent.Assign( 0, 0 );
-                aPam.DeleteMark();
-                pDoc->DelFullPara( aPam );
-            }
-        }
-        else
-        {
-            pDoc->DeleteRange( aPam );
-        }
-
-        if( pStt == GetPoint() )
-            Exchange();
-
-        DeleteMark();
     }
+
+    if( pCSttNd && pCEndNd )
+    {
+        // #i100466# - force a <join next> on <delete and join> operation
+        pDoc->DeleteAndJoin( aPam, true );
+    }
+    else if( pCSttNd || pCEndNd )
+    {
+        if( pCSttNd && !pCEndNd )
+            bDelLastPara = sal_True;
+        pDoc->DeleteRange( aPam );
+
+        if( bDelLastPara )
+        {
+            // To prevent dangling references to the paragraph to
+            // be deleted, redline that point into this paragraph should be
+            // moved to the new end position. Since redlines in the redline
+            // table are sorted and the pEnd position is an endnode (see
+            // bDelLastPara condition above), only redlines before the
+            // current ones can be affected.
+            const SwRedlineTbl& rTbl = pDoc->GetRedlineTbl();
+            sal_uInt16 n = rTbl.GetPos( this );
+            OSL_ENSURE( n != USHRT_MAX, "How strange. We don't exist!" );
+            for( bool bBreak = false; !bBreak && n > 0; )
+            {
+                --n;
+                bBreak = true;
+                if( rTbl[ n ]->GetBound(sal_True) == *aPam.GetPoint() )
+                {
+                    rTbl[ n ]->GetBound(sal_True) = *pEnd;
+                    bBreak = false;
+                }
+                if( rTbl[ n ]->GetBound(sal_False) == *aPam.GetPoint() )
+                {
+                    rTbl[ n ]->GetBound(sal_False) = *pEnd;
+                    bBreak = false;
+                }
+            }
+
+            SwPosition aEnd( *pEnd );
+            *GetPoint() = *pEnd;
+            *GetMark() = *pEnd;
+            DeleteMark();
+
+            aPam.GetBound( sal_True ).nContent.Assign( 0, 0 );
+            aPam.GetBound( sal_False ).nContent.Assign( 0, 0 );
+            aPam.DeleteMark();
+            pDoc->DelFullPara( aPam );
+        }
+    }
+    else
+    {
+        pDoc->DeleteRange( aPam );
+    }
+
+    if( pStt == GetPoint() )
+        Exchange();
+
+    DeleteMark();
 }
 
 void SwRedline::MoveFromSection()
 {
-    if( pCntntSect )
+    if( !pCntntSect )
     {
-        SwDoc* pDoc = GetDoc();
-        const SwRedlineTbl& rTbl = pDoc->GetRedlineTbl();
-        std::vector<SwPosition*> aBeforeArr, aBehindArr;
-        sal_uInt16 nMyPos = rTbl.GetPos( this );
-        OSL_ENSURE( this, "this is not in the array?" );
-        bool bBreak = false;
+        InvalidateRange();
+        return;
+    }
+
+    SwDoc* pDoc = GetDoc();
+    const SwRedlineTbl& rTbl = pDoc->GetRedlineTbl();
+
+    // get the index of the current SwRedline in the
+    // SwRedlineTbl of the document
+    const sal_uInt16 nMyPos = rTbl.GetPos( this );
+    OSL_ENSURE( this, "this is not in the array?" );
+
+
+    std::vector<SwPosition*> aBeforeArr, aBehindArr;
+
+    {
+        bool bBreak;
+        // index to navigate into the SwRedlineTbl
         sal_uInt16 n;
 
-        for( n = nMyPos+1; !bBreak && n < rTbl.size(); ++n )
+        for(bBreak = false, n = nMyPos+1; !bBreak && n < rTbl.size(); ++n )
         {
             bBreak = true;
             if( rTbl[ n ]->GetBound(sal_True) == *GetPoint() )
@@ -3569,7 +3620,8 @@
                 bBreak = false;
             }
         }
-        for( bBreak = false, n = nMyPos; !bBreak && n ; )
+
+        for( bBreak = false, n = nMyPos; !bBreak && n != 0;)
         {
             --n;
             bBreak = true;
@@ -3584,79 +3636,88 @@
                 bBreak = false;
             }
         }
-
-        const SwNode* pKeptCntntSectNode( &pCntntSect->GetNode() ); // #i95711#
-        {
-            SwPaM aPam( pCntntSect->GetNode(),
-                        *pCntntSect->GetNode().EndOfSectionNode(), 1,
-                        ( bDelLastPara ? -2 : -1 ) );
-            SwCntntNode* pCNd = aPam.GetCntntNode();
-            if( pCNd )
-                aPam.GetPoint()->nContent.Assign( pCNd, pCNd->Len() );
-            else
-                aPam.GetPoint()->nNode++;
-
-            SwFmtColl* pColl = pCNd && pCNd->Len() && aPam.GetPoint()->nNode !=
-                                        aPam.GetMark()->nNode
-                                ? pCNd->GetFmtColl() : 0;
-
-            SwNodeIndex aNdIdx( GetPoint()->nNode, -1 );
-            sal_uInt16 nPos = GetPoint()->nContent.GetIndex();
-
-            SwPosition aPos( *GetPoint() );
-            if( bDelLastPara && *aPam.GetPoint() == *aPam.GetMark() )
-            {
-                aPos.nNode--;
-
-                pDoc->AppendTxtNode( aPos );
-            }
-            else
-            {
-                pDoc->MoveRange( aPam, aPos,
-                    IDocumentContentOperations::DOC_MOVEALLFLYS );
-            }
-
-            SetMark();
-            *GetPoint() = aPos;
-            GetMark()->nNode = aNdIdx.GetIndex() + 1;
-            pCNd = GetMark()->nNode.GetNode().GetCntntNode();
-            GetMark()->nContent.Assign( pCNd, nPos );
-
-            if( bDelLastPara )
-            {
-                GetPoint()->nNode++;
-                GetPoint()->nContent.Assign( pCNd = GetCntntNode(), 0 );
-                bDelLastPara = sal_False;
-            }
-            else if( pColl )
-                pCNd = GetCntntNode();
-
-            if( pColl && pCNd )
-                pCNd->ChgFmtColl( pColl );
-        }
-        // #i95771#
-        // Under certain conditions the previous <SwDoc::Move(..)> has already
-        // removed the change tracking section of this <SwRedline> instance from
-        // the change tracking nodes area.
-        // Thus, check if <pCntntSect> still points to the change tracking section
-        // by comparing it with the "indexed" <SwNode> instance copied before
-        // perform the intrinsic move.
-        // Note: Such condition is e.g. a "delete" change tracking only containing a table.
-        if ( &pCntntSect->GetNode() == pKeptCntntSectNode )
-        {
-            pDoc->DeleteSection( &pCntntSect->GetNode() );
-        }
-        delete pCntntSect, pCntntSect = 0;
-
-        // adjustment of redline table positions must take start and
-        // end into account, not point and mark.
-        for( n = 0; n < aBeforeArr.size(); ++n )
-            *aBeforeArr[ n ] = *Start();
-        for( n = 0; n < aBehindArr.size(); ++n )
-            *aBehindArr[ n ] = *End();
     }
-    else
-        InvalidateRange();
+
+    const SwNode* pKeptCntntSectNode( &pCntntSect->GetNode() ); // #i95711#
+
+    {
+        SwPaM aPam( pCntntSect->GetNode(),
+                *pCntntSect->GetNode().EndOfSectionNode(), 1,
+                ( bDelLastPara ? -2 : -1 ) );
+
+        // get the content of the redline
+        SwCntntNode* pCNd = aPam.GetCntntNode();
+
+        if( pCNd )
+            aPam.GetPoint()->nContent.Assign( pCNd, pCNd->Len() );
+        else
+            aPam.GetPoint()->nNode++;
+
+        // copy the named format of the last paragraph of the redline
+        // (to later copy it in the paragraph following it)
+        SwFmtColl* pColl = pCNd &&
+            aPam.GetPoint()->nNode != aPam.GetMark()->nNode
+            ? pCNd->GetFmtColl()
+            : 0;
+
+        SwNodeIndex aNdIdx( GetPoint()->nNode, -1 );
+        sal_uInt16 nPos = GetPoint()->nContent.GetIndex();
+
+        SwPosition aPos( *GetPoint() );
+        if( bDelLastPara && *aPam.GetPoint() == *aPam.GetMark() )
+        {
+            aPos.nNode--;
+
+            pDoc->AppendTxtNode( aPos );
+        }
+        else
+        {
+            pDoc->MoveRange( aPam, aPos,
+                    IDocumentContentOperations::DOC_MOVEALLFLYS );
+        }
+
+        SetMark();
+        *GetPoint() = aPos;
+        GetMark()->nNode = aNdIdx.GetIndex() + 1;
+        pCNd = GetMark()->nNode.GetNode().GetCntntNode();
+        GetMark()->nContent.Assign( pCNd, nPos );
+
+        if( bDelLastPara )
+        {
+            GetPoint()->nNode++;
+            GetPoint()->nContent.Assign( pCNd = GetCntntNode(), 0 );
+            bDelLastPara = sal_False;
+        }
+        else if( pColl )
+            pCNd = GetCntntNode();
+
+        // past the named format of the last paragraph of the redline
+        // in the paragraph following it
+        if( pColl && pCNd )
+            pCNd->ChgFmtColl( pColl );
+    }
+
+    // #i95771#
+    // Under certain conditions the previous <SwDoc::Move(..)> has already
+    // removed the change tracking section of this <SwRedline> instance from
+    // the change tracking nodes area.
+    // Thus, check if <pCntntSect> still points to the change tracking section
+    // by comparing it with the "indexed" <SwNode> instance copied before
+    // perform the intrinsic move.
+    // Note: Such condition is e.g. a "delete" change tracking only containing a table.
+    if ( &pCntntSect->GetNode() == pKeptCntntSectNode )
+    {
+        pDoc->DeleteSection( &pCntntSect->GetNode() );
+    }
+    delete pCntntSect, pCntntSect = 0;
+
+    // adjustment of redline table positions must take start and
+    // end into account, not point and mark.
+    for(sal_uInt16 n = 0; n < aBeforeArr.size(); ++n )
+        *aBeforeArr[ n ] = *Start();
+
+    for(sal_uInt16 n = 0; n < aBehindArr.size(); ++n )
+        *aBehindArr[ n ] = *End();
 }
 
 // for Undo
diff --git a/sw/source/core/docnode/node.cxx b/sw/source/core/docnode/node.cxx
index b6f27f0..a4322ec 100644
--- a/sw/source/core/docnode/node.cxx
+++ b/sw/source/core/docnode/node.cxx
@@ -63,6 +63,7 @@
 #include <IDocumentListItems.hxx>
 #include <switerator.hxx>
 #include "ndole.hxx"
+#include <docRecurseThroughLinkedRedline.hxx>
 
 using namespace ::com::sun::star::i18n;
 
@@ -937,7 +938,8 @@
     : SwModify( pColl ),     // CrsrsShell, FrameFmt,
     SwNode( rWhere, nNdType ),
     pCondColl( 0 ),
-    mbSetModifyAtAttr( false )
+    mbSetModifyAtAttr( false ),
+    m_eHandleRedlineDirection(SwCntntNode::REDLINE_DIRECTION_BOTH)
 {
 }
 
@@ -1081,15 +1083,17 @@
 
 xub_StrLen SwCntntNode::Len() const { return 0; }
 
-
-
 SwFmtColl *SwCntntNode::ChgFmtColl( SwFmtColl *pNewColl )
 {
     OSL_ENSURE( pNewColl, "Collectionpointer is 0." );
-    SwFmtColl *pOldColl = GetFmtColl();
 
+    SwFmtColl *pOldColl = GetFmtColl();
     if( pNewColl != pOldColl )
     {
+        // call ChgFmtColl on previews and nexts nodes, in case they are linked
+        // by deletion redlines, in order to transmit them the formats modifications
+        RecurseThroughLinkedRedline(&SwCntntNode::ChgFmtColl, pNewColl);
+
         pNewColl->Add( this );
 
         // Set the Parent of out AutoAttributes to the new Collection
@@ -1111,14 +1115,15 @@
             SwCntntNode::Modify( &aTmp1, &aTmp2 );
         }
     }
+
     if ( IsInCache() )
     {
         SwFrm::GetCache().Delete( this );
         SetInCache( sal_False );
     }
+
     return pOldColl;
 }
-
 
 sal_Bool SwCntntNode::GoNext(SwIndex * pIdx, sal_uInt16 nMode ) const
 {
@@ -1338,6 +1343,10 @@
 
     OSL_ENSURE( GetpSwAttrSet(), "Why did't we create an AttrSet?");
 
+    // call ChgFmtColl on previews and nexts nodes, in case they are linked
+    // by deletion redlines, in order to transmit them the formats modifications
+    RecurseThroughLinkedRedline< sal_Bool (SwCntntNode::*)(const SfxPoolItem& ), const SfxPoolItem& >(&SwCntntNode::SetAttr, rAttr);
+
     if ( IsInCache() )
     {
         SwFrm::GetCache().Delete( this );
@@ -1368,6 +1377,10 @@
 
 sal_Bool SwCntntNode::SetAttr( const SfxItemSet& rSet )
 {
+    // call ChgFmtColl on previews and nexts nodes, in case they are linked
+    // by deletion redlines, in order to transmit them the formats modifications
+    RecurseThroughLinkedRedline< sal_Bool (SwCntntNode::*)( const SfxItemSet& ), const SfxItemSet& >(&SwCntntNode::SetAttr, rSet);
+
     if ( IsInCache() )
     {
         SwFrm::GetCache().Delete( this );
@@ -1447,6 +1460,10 @@
     if( !GetpSwAttrSet() )
         return sal_False;
 
+    // call ChgFmtColl on previews and nexts nodes, in case they are linked
+    // by deletion redlines, in order to transmit them the formats modifications
+    RecurseThroughLinkedRedline< sal_Bool (SwCntntNode::*)( sal_uInt16, sal_uInt16 ), sal_uInt16, sal_uInt16 >(&SwCntntNode::ResetAttr, nWhich1, nWhich2);
+
     if ( IsInCache() )
     {
         SwFrm::GetCache().Delete( this );
@@ -1495,6 +1512,10 @@
     if( !GetpSwAttrSet() )
         return sal_False;
 
+    // call ChgFmtColl on previews and nexts nodes, in case they are linked
+    // by deletion redlines, in order to transmit them the formats modifications
+    RecurseThroughLinkedRedline<sal_Bool (SwCntntNode::*)( const std::vector<sal_uInt16>& ), const std::vector<sal_uInt16>& >(&SwCntntNode::ResetAttr, rWhichArr);
+
     if ( IsInCache() )
     {
         SwFrm::GetCache().Delete( this );
@@ -1536,6 +1557,10 @@
     if( !GetpSwAttrSet() )
         return 0;
 
+    // call ChgFmtColl on previews and nexts nodes, in case they are linked
+    // by deletion redlines, in order to transmit them the formats modifications
+    RecurseThroughLinkedRedline(&SwCntntNode::ResetAllAttr);
+
     if ( IsInCache() )
     {
         SwFrm::GetCache().Delete( this );
diff --git a/sw/source/core/txtnode/ndtxt.cxx b/sw/source/core/txtnode/ndtxt.cxx
index 437cf44..a79d754 100644
--- a/sw/source/core/txtnode/ndtxt.cxx
+++ b/sw/source/core/txtnode/ndtxt.cxx
@@ -3636,6 +3636,9 @@
     OSL_ENSURE( HAS_BASE( SwTxtFmtColl, pNewColl ),
                 "ChgFmtColl: is not a Text Collection pointer." );
 
+    // no need to explicitly call RecurseThroughLinkedRedline it will be call by
+    // SwCntntNode::ChgFmtColl
+
     SwTxtFmtColl *pOldColl = GetTxtColl();
     if( pNewColl != pOldColl )
     {
@@ -3763,6 +3766,9 @@
         return;
     }
 
+    // no need to explicitly call RecurseThroughLinkedRedline it will be call by
+    // SetAttr
+
     SfxInt16Item aNewListLevelItem( RES_PARATR_LIST_LEVEL,
                                     static_cast<sal_Int16>(nLevel) );
     SetAttr( aNewListLevelItem );
@@ -3843,7 +3849,11 @@
 
 void SwTxtNode::SetAttrListRestartValue( SwNumberTree::tSwNumTreeNumber nNumber )
 {
-//    CreateNum()->SetStart(nNumber);
+    // no need to explicitly call RecurseThroughLinkedRedline it will be call by
+    // ResetAttr
+    // or
+    // SetAttr
+
     const bool bChanged( HasAttrListRestartValue()
                          ? GetAttrListRestartValue() != nNumber
                          : nNumber != USHRT_MAX );
@@ -4545,6 +4555,9 @@
 
 sal_Bool SwTxtNode::SetAttr( const SfxPoolItem& pItem )
 {
+    // no need to explicitly call RecurseThroughLinkedRedline it will be call by
+    // SwCntntNode::SetAttr
+
     const bool bOldIsSetOrResetAttr( mbInSetOrResetAttr );
     mbInSetOrResetAttr = true;
 
@@ -4559,6 +4572,9 @@
 
 sal_Bool SwTxtNode::SetAttr( const SfxItemSet& rSet )
 {
+    // no need to explicitly call RecurseThroughLinkedRedline it will be call by
+    // SwCntntNode::SetAttr
+
     const bool bOldIsSetOrResetAttr( mbInSetOrResetAttr );
     mbInSetOrResetAttr = true;
 
@@ -4847,6 +4863,9 @@
 
 sal_Bool SwTxtNode::ResetAttr( sal_uInt16 nWhich1, sal_uInt16 nWhich2 )
 {
+    // no need to explicitly call RecurseThroughLinkedRedline it will be call by
+    // SwCntntNode::ResetAttr
+
     const bool bOldIsSetOrResetAttr( mbInSetOrResetAttr );
     mbInSetOrResetAttr = true;
 
@@ -4861,6 +4880,9 @@
 
 sal_Bool SwTxtNode::ResetAttr( const std::vector<sal_uInt16>& rWhichArr )
 {
+    // no need to explicitly call RecurseThroughLinkedRedline it will be call by
+    // SwCntntNode::ResetAttr
+
     const bool bOldIsSetOrResetAttr( mbInSetOrResetAttr );
     mbInSetOrResetAttr = true;
 
@@ -4875,6 +4897,9 @@
 
 sal_uInt16 SwTxtNode::ResetAllAttr()
 {
+    // no need to explicitly call RecurseThroughLinkedRedline it will be call by
+    // SwCntntNode::ResetAllAttr
+
     const bool bOldIsSetOrResetAttr( mbInSetOrResetAttr );
     mbInSetOrResetAttr = true;
 

-- 
To view, visit https://gerrit.libreoffice.org/3583
To unsubscribe, visit https://gerrit.libreoffice.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I989d3f9e56503ddc6280d134ed433b8af94ed052
Gerrit-PatchSet: 1
Gerrit-Project: core
Gerrit-Branch: master
Gerrit-Owner: Maxime de Roucy <mderoucy at linagora.com>



More information about the LibreOffice mailing list