[Libreoffice-commits] core.git: Branch 'private/mst/sw_redlinehide_2' - 13 commits - svl/source sw/inc sw/source

Libreoffice Gerrit user logerrit at kemper.freedesktop.org
Wed Aug 22 17:01:30 UTC 2018


 svl/source/items/itemiter.cxx                           |    2 
 sw/inc/ndarr.hxx                                        |    3 
 sw/inc/ndgrf.hxx                                        |    2 
 sw/inc/ndole.hxx                                        |    2 
 sw/inc/ndtxt.hxx                                        |    2 
 sw/inc/node.hxx                                         |    2 
 sw/inc/unocrsr.hxx                                      |    6 +
 sw/source/core/doc/DocumentContentOperationsManager.cxx |    2 
 sw/source/core/doc/docedt.cxx                           |    6 +
 sw/source/core/docnode/ndcopy.cxx                       |    4 -
 sw/source/core/docnode/node.cxx                         |   37 +++++----
 sw/source/core/docnode/nodes.cxx                        |    7 -
 sw/source/core/graphic/ndgrf.cxx                        |    2 
 sw/source/core/inc/txtfrm.hxx                           |    9 ++
 sw/source/core/layout/ssfrm.cxx                         |    9 +-
 sw/source/core/layout/wsfrm.cxx                         |    6 +
 sw/source/core/ole/ndole.cxx                            |    2 
 sw/source/core/text/redlnitr.cxx                        |    1 
 sw/source/core/text/txtfrm.cxx                          |   11 ++
 sw/source/core/txtnode/ndtxt.cxx                        |   57 ++++++++++++++-
 sw/source/core/undo/undel.cxx                           |   60 ++++++++++++++--
 21 files changed, 183 insertions(+), 49 deletions(-)

New commits:
commit 99622df8e03019e79c67a29d6d3770ba011b7b54
Author:     Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Wed Aug 22 17:09:02 2018 +0200
Commit:     Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Wed Aug 22 18:58:20 2018 +0200

    sw_redlinehide_2: SwUndoDelete
    
    This is problematic because of the calls to SplitNode.
    Ideally we'd want the SplitNode to create merged frames already, but
    that doesn't seem to be easy to achieve; several problems with this are:
    
    1. the redlines are only restored at the end of UndoImpl
    2. even if we store another set of SwRedlineSaveDatas right before the
       Join (while preventing the first SwRedlineSaveDatas from deleting
       them), and restore them by passing a closure to SplitNode, there
       are complaints about empty redlines, and also this case isn't
       handled properly:
    
         f<delete start>o<redline start>o
         b<redline end>a<redline start>r
         b<redline end>a<delete end>z
    
    So instead, let SplitNode create whatever frames it does, and fix it up
    at the end manually on the start node's frames.
    
    This necessitates delaying the creation of the frames on the moved nodes
    until the end too.
    
    Change-Id: I8ba2967659cc2ddbe6f7c40e0447d79601498ed6

diff --git a/sw/source/core/undo/undel.cxx b/sw/source/core/undo/undel.cxx
index 7e942b427ecb..f4f6c5559d85 100644
--- a/sw/source/core/undo/undel.cxx
+++ b/sw/source/core/undo/undel.cxx
@@ -41,6 +41,9 @@
 #include <sfx2/app.hxx>
 #include <fldbas.hxx>
 #include <fmtfld.hxx>
+#include <frmtool.hxx>
+#include <txtfrm.hxx>
+#include <rootfrm.hxx>
 #include <strings.hrc>
 #include <vector>
 
@@ -763,6 +766,7 @@ void SwUndoDelete::UndoImpl(::sw::UndoRedoContext & rContext)
 
     SwNodeIndex aIdx(rDoc.GetNodes(), nCalcStt);
     SwNode* pInsNd = &aIdx.GetNode();
+    SwNode* pMovedNode = nullptr;
 
     {   // code block so that SwPosition is detached when deleting a Node
         SwPosition aPos( aIdx );
@@ -838,7 +842,6 @@ void SwUndoDelete::UndoImpl(::sw::UndoRedoContext & rContext)
                     ++aPos.nNode;
             }
         }
-        SwNode* pMovedNode = nullptr;
         if( m_nSectDiff )
         {
             sal_uLong nMoveIndex = aPos.nNode.GetIndex();
@@ -866,7 +869,11 @@ void SwUndoDelete::UndoImpl(::sw::UndoRedoContext & rContext)
         {
             SwNodeRange aRange( *m_pMvStt, 0, *m_pMvStt, m_nNode );
             SwNodeIndex aCopyIndex( aPos.nNode, -1 );
-            rDoc.GetUndoManager().GetUndoNodes().Copy_( aRange, aPos.nNode );
+            rDoc.GetUndoManager().GetUndoNodes().Copy_(aRange, aPos.nNode,
+                    // sw_redlinehide: delay creating frames: the flags on the
+                    // nodes aren't necessarily up-to-date, and the redlines
+                    // from m_pRedlSaveData aren't applied yet...
+                    false);
 
             if( m_nReplaceDummy )
             {
@@ -889,9 +896,6 @@ void SwUndoDelete::UndoImpl(::sw::UndoRedoContext & rContext)
             }
         }
 
-        if( pMovedNode )
-            lcl_MakeAutoFrames(*rDoc.GetSpzFrameFormats(), pMovedNode->GetIndex());
-
         if( m_aSttStr )
         {
             aPos.nNode = nSttNode - m_nNdDiff + ( m_bJoinNext ? 0 : m_nReplaceDummy );
@@ -958,6 +962,52 @@ void SwUndoDelete::UndoImpl(::sw::UndoRedoContext & rContext)
     if( m_pRedlSaveData )
         SetSaveData(rDoc, *m_pRedlSaveData);
 
+    if (m_aSttStr && (!m_bFromTableCopy || 0 != m_nNode))
+    {
+        // only now do we have redlines in the document again; fix up the split
+        // frames
+        SwTextNode *const pStartNode(aIdx.GetNodes()[nSttNode]->GetTextNode());
+        assert(pStartNode);
+        std::vector<SwTextFrame*> frames;
+        SwIterator<SwTextFrame, SwTextNode, sw::IteratorMode::UnwrapMulti> aIter(*pStartNode);
+        for (SwTextFrame* pFrame = aIter.First(); pFrame; pFrame = aIter.Next())
+        {
+            if (pFrame->getRootFrame()->IsHideRedlines())
+            {
+                frames.push_back(pFrame);
+            }
+        }
+        for (SwTextFrame * pFrame : frames)
+        {
+            // SplitNode could have moved the original frame to the start node
+            // & created a new one on end, or could have created new frame on
+            // start node... grab start node's frame and recreate MergedPara.
+            SwTextNode & rFirstNode(pFrame->GetMergedPara()
+                ? *pFrame->GetMergedPara()->pFirstNode
+                : *pStartNode);
+            assert(rFirstNode.GetIndex() <= pStartNode->GetIndex());
+            pFrame->SetMergedPara(sw::CheckParaRedlineMerge(
+                        *pFrame, rFirstNode, sw::FrameMode::Existing));
+            // note: this may or may not delete frames on the end node
+        }
+    }
+
+    // create frames after SetSaveData has recreated redlines
+    if (0 != m_nNode)
+    {
+        // don't include end node in the range: it may have been merged already
+        // by the start node, or it may be merged by one of the moved nodes,
+        // but if it isn't merged, its current frame(s) should be good...
+        SwNodeIndex const start(rDoc.GetNodes(), nSttNode + (m_bDelFullPara ? 0 : 1));
+        SwNodeIndex const end(rDoc.GetNodes(), nEndNode);
+        ::MakeFrames(&rDoc, start, end);
+    }
+
+    if (pMovedNode)
+    {   // probably better do this after creating all frames
+        lcl_MakeAutoFrames(*rDoc.GetSpzFrameFormats(), pMovedNode->GetIndex());
+    }
+
     AddUndoRedoPaM(rContext, true);
 }
 
commit dba10d891484273d665547eda544b40e420b2004
Author:     Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Wed Aug 22 15:09:59 2018 +0200
Commit:     Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Wed Aug 22 18:58:20 2018 +0200

    sw_redlinehide_2: something about Join
    
    Change-Id: I047b6008c5f0bb6e79c63421a4dba09ba8cf3320
    Todo: remember what i was thinking when i wrote this

diff --git a/sw/source/core/doc/docedt.cxx b/sw/source/core/doc/docedt.cxx
index 89454ea879ae..54c6a1c56e74 100644
--- a/sw/source/core/doc/docedt.cxx
+++ b/sw/source/core/doc/docedt.cxx
@@ -412,7 +412,13 @@ bool sw_JoinText( SwPaM& rPam, bool bJoinPrev )
                     rPam.GetBound( false ) = aAlphaPos;
             }
             // delete the Node, at last!
+            SwNode::Merge const eOldMergeFlag(pOldTextNd->GetRedlineMergeFlag());
+            if (eOldMergeFlag == SwNode::Merge::First)
+            {
+                sw::MoveDeletedPrevFrames(*pOldTextNd, *pTextNd);
+            }
             pDoc->GetNodes().Delete( aOldIdx );
+            sw::CheckResetRedlineMergeFlag(*pTextNd, eOldMergeFlag == SwNode::Merge::NonFirst);
         }
         else
         {
diff --git a/sw/source/core/inc/txtfrm.hxx b/sw/source/core/inc/txtfrm.hxx
index 7d677b74ab0f..3bae9bcd7905 100644
--- a/sw/source/core/inc/txtfrm.hxx
+++ b/sw/source/core/inc/txtfrm.hxx
@@ -106,6 +106,9 @@ TextFrameIndex UpdateMergedParaForDelete(MergedPara & rMerged,
         bool isRealDelete,
         SwTextNode const& rNode, sal_Int32 nIndex, sal_Int32 nLen);
 
+void MoveDeletedPrevFrames(SwTextNode & rDeletedPrev, SwTextNode & rNode);
+void CheckResetRedlineMergeFlag(SwTextNode & rNode, bool bRecreateMerged);
+
 } // namespace sw
 
 /// Represents the visualization of a paragraph. Typical upper is an
@@ -730,7 +733,7 @@ public:
 
     static void repaintTextFrames( const SwTextNode& rNode );
 
-    void RegisterToNode( SwTextNode& );
+    void RegisterToNode(SwTextNode &, bool isForceNodeAsFirst = false);
 
     virtual void dumpAsXmlAttributes(xmlTextWriterPtr writer) const override;
 };
diff --git a/sw/source/core/layout/ssfrm.cxx b/sw/source/core/layout/ssfrm.cxx
index 3a37ae92bc7f..8b8e7bd22610 100644
--- a/sw/source/core/layout/ssfrm.cxx
+++ b/sw/source/core/layout/ssfrm.cxx
@@ -440,14 +440,19 @@ SwContentFrame::~SwContentFrame()
 {
 }
 
-void SwTextFrame::RegisterToNode(SwTextNode & rNode)
+void SwTextFrame::RegisterToNode(SwTextNode & rNode, bool const isForceNodeAsFirst)
 {
+    if (isForceNodeAsFirst && m_pMergedPara)
+    {   // nothing registered here, in particular no redlines
+        assert(m_pMergedPara->pFirstNode->GetIndex() + 1 == rNode.GetIndex());
+        assert(!m_pMergedPara->pFirstNode->HasAnyIndex());
+    }
     assert(&rNode != GetDep());
     assert(!m_pMergedPara
         || (m_pMergedPara->pFirstNode->GetIndex() < rNode.GetIndex())
         || (rNode.GetIndex() + 1 == m_pMergedPara->pFirstNode->GetIndex()));
     SwTextNode & rFirstNode(
-        (m_pMergedPara && m_pMergedPara->pFirstNode->GetIndex() < rNode.GetIndex())
+        (!isForceNodeAsFirst && m_pMergedPara && m_pMergedPara->pFirstNode->GetIndex() < rNode.GetIndex())
             ? *m_pMergedPara->pFirstNode
             : rNode);
     // sw_redlinehide: use New here, because the only caller also calls lcl_ChangeFootnoteRef
diff --git a/sw/source/core/txtnode/ndtxt.cxx b/sw/source/core/txtnode/ndtxt.cxx
index 22a06fbbc32e..0d5673afc345 100644
--- a/sw/source/core/txtnode/ndtxt.cxx
+++ b/sw/source/core/txtnode/ndtxt.cxx
@@ -823,8 +823,51 @@ void SwTextNode::MoveTextAttr_To_AttrSet()
 
 }
 
-namespace {
+namespace sw {
+
+    // None,Node->None
+    // None,First->First
+    // First,NonFirst->First
+    // NonFirst,First->NonFirst
+    // NonFirst,None->NonFirst
+
 
+void MoveDeletedPrevFrames(SwTextNode & rDeletedPrev, SwTextNode & rNode)
+{
+    std::vector<SwTextFrame*> frames;
+    SwIterator<SwTextFrame, SwTextNode, sw::IteratorMode::UnwrapMulti> aIter(rDeletedPrev);
+    for (SwTextFrame* pFrame = aIter.First(); pFrame; pFrame = aIter.Next())
+    {
+        frames.push_back(pFrame);
+    }
+    {
+        auto frames2(frames);
+        SwIterator<SwTextFrame, SwTextNode, sw::IteratorMode::UnwrapMulti> aIt(rNode);
+        for (SwTextFrame* pFrame = aIt.First(); pFrame; pFrame = aIt.Next())
+        {
+            auto const it(std::find(frames2.begin(), frames2.end(), pFrame));
+            assert(it != frames2.end());
+            frames2.erase(it);
+        }
+        assert(frames2.empty());
+    }
+    for (SwTextFrame * pFrame : frames)
+    {
+        pFrame->RegisterToNode(rNode, true);
+#if 0
+        if (pFrame->m_pMergedPara && pFrame->m_pMergedPara->pFirstNode == &rDeletedPrev && GetIndex() <= pFrame->m_pMergedPara->pLastNode->GetIndex())
+        {
+            pFrame->listeners.StopListening(&rDeletedPrev);
+            pFrame->m_pMergedPara->pFirstNode = &rNode;
+            &rNode.SetRedlineMergeFlag(SwNodes::Merge::First);
+        }
+#endif
+    }
+}
+
+    /// not only fix the flag; if prev is First the frame is actually deleted!!!
+    // if prev is First : must not delete frame but move it
+    // if prev is NonFirst : must delete frame (if this is First/None) & merge into prev
 void CheckResetRedlineMergeFlag(SwTextNode & rNode, bool const bRecreateMerged)
 {
     if (bRecreateMerged)
@@ -843,6 +886,9 @@ void CheckResetRedlineMergeFlag(SwTextNode & rNode, bool const bRecreateMerged)
             assert(rFirstNode.GetIndex() <= rNode.GetIndex());
             pFrame->SetMergedPara(sw::CheckParaRedlineMerge(
                         *pFrame, rFirstNode, sw::FrameMode::Existing));
+            assert(pFrame->GetMergedPara());
+            assert(pFrame->GetMergedPara()->listener.IsListeningTo(&rNode));
+            assert(rNode.GetIndex() <= pFrame->GetMergedPara()->pLastNode->GetIndex());
         }
     }
     else if (rNode.GetRedlineMergeFlag() != SwNode::Merge::None)
@@ -1048,6 +1094,10 @@ void SwTextNode::JoinPrev()
             pDoc->CorrAbs( aIdx, SwPosition( *this ), nLen, true );
         }
         SwNode::Merge const eOldMergeFlag(pTextNode->GetRedlineMergeFlag());
+        if (eOldMergeFlag == SwNode::Merge::First)
+        {
+            sw::MoveDeletedPrevFrames(*pTextNode, *this);
+        }
         rNds.Delete(aIdx);
         SetWrong( pList, false );
         SetGrammarCheck( pList3, false );
commit a8427efa6d290fba8302ee4ac877ec6e7f0bf9d4
Author:     Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Wed Aug 22 15:04:18 2018 +0200
Commit:     Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Wed Aug 22 18:58:20 2018 +0200

    sw_redlinehide_2: DelFrames is called for hidden nodes too now
    
    Change-Id: I9933d8b8ee29bb4da74819d7d2350a5b2b04aa09

diff --git a/sw/source/core/layout/wsfrm.cxx b/sw/source/core/layout/wsfrm.cxx
index 8d8a4072bcdd..3e6ff2d4f565 100644
--- a/sw/source/core/layout/wsfrm.cxx
+++ b/sw/source/core/layout/wsfrm.cxx
@@ -4348,8 +4348,9 @@ static void UnHideRedlines(SwRootFrame & rLayout,
             {
                 if (rNode.IsContentNode())
                 {
-                    // note: no-op for NonFirst nodes, only Hidden will delete
-                    static_cast<SwContentNode&>(rNode).DelFrames(&rLayout);
+                    // note: nothing to do here, already done
+                    auto const pFrame(static_cast<SwContentNode&>(rNode).getLayoutFrame(&rLayout));
+                    assert(!pFrame || static_cast<SwTextFrame*>(pFrame)->GetMergedPara()->pFirstNode != &rNode);
                 }
                 else if (rNode.IsTableNode())
                 {
commit a1ba8de3f60be612e304fe5acaecd8db605c0573
Author:     Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Wed Aug 22 15:03:42 2018 +0200
Commit:     Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Wed Aug 22 15:03:42 2018 +0200

    sw_redlinehide_2: another assert (merge this?)
    
    Change-Id: Ica141176e0accd07f9b4246a71df5e660119078e

diff --git a/sw/source/core/layout/wsfrm.cxx b/sw/source/core/layout/wsfrm.cxx
index bcea7f789905..8d8a4072bcdd 100644
--- a/sw/source/core/layout/wsfrm.cxx
+++ b/sw/source/core/layout/wsfrm.cxx
@@ -4172,6 +4172,7 @@ static void UnHideRedlines(SwRootFrame & rLayout,
         std::set<sal_uLong> *const pSkipped)
 {
     assert(rEndOfSectionNode.IsEndNode());
+    assert(rNodes[rEndOfSectionNode.StartOfSectionNode()->GetIndex() + 1]->IsCreateFrameWhenHidingRedlines()); // first node is never hidden
     for (sal_uLong i = rEndOfSectionNode.StartOfSectionNode()->GetIndex() + 1;
          i < rEndOfSectionNode.GetIndex(); ++i)
     {
commit 63dc6a90d53c48269d693a16825c4e9729699bdf
Author:     Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Wed Aug 22 13:26:18 2018 +0200
Commit:     Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Wed Aug 22 14:51:43 2018 +0200

    Revert "this looks like a wrong path..."
    
    This reverts commit 391b6325117483c73f6fd0fb2286b37aaeeb46e4.

diff --git a/sw/inc/IDocumentContentOperations.hxx b/sw/inc/IDocumentContentOperations.hxx
index b3204109a8a0..fb4006334a15 100644
--- a/sw/inc/IDocumentContentOperations.hxx
+++ b/sw/inc/IDocumentContentOperations.hxx
@@ -22,7 +22,6 @@
 
 #include <sal/types.h>
 #include <rtl/ustring.hxx>
-#include <functional>
 #include "swtypes.hxx"
 
 class SwPaM;
@@ -38,9 +37,6 @@ class SwFrameFormat;
 class SwDrawFrameFormat;
 class SwFlyFrameFormat;
 class SwNodeIndex;
-class SwTextNode;
-
-namespace sw { namespace mark { enum class RestoreMode; } }
 
 namespace utl { class TransliterationWrapper; }
 namespace svt { class EmbeddedObjectRef; }
@@ -190,8 +186,7 @@ public:
 
     /** Split a node at rPos (implemented only for TextNode).
     */
-    virtual bool SplitNode(const SwPosition &rPos, bool bChkTableStart,
-        std::function<void ()> const* pRedlineRestore = nullptr) = 0;
+    virtual bool SplitNode(const SwPosition &rPos, bool bChkTableStart) = 0;
 
     virtual bool AppendTextNode(SwPosition& rPos) = 0;
 
diff --git a/sw/inc/IDocumentRedlineAccess.hxx b/sw/inc/IDocumentRedlineAccess.hxx
index d6c44b24e680..a68af07fb707 100644
--- a/sw/inc/IDocumentRedlineAccess.hxx
+++ b/sw/inc/IDocumentRedlineAccess.hxx
@@ -180,7 +180,7 @@ public:
     virtual bool DeleteRedline(
         /*[in]*/const SwPaM& rPam,
         /*[in]*/bool bSaveInUndo,
-        /*[in]*/sal_uInt16 nDelType, bool bIgnoreJoining = false) = 0;
+        /*[in]*/sal_uInt16 nDelType) = 0;
 
     virtual bool DeleteRedline(
         /*[in]*/const SwStartNode& rSection,
diff --git a/sw/inc/undobj.hxx b/sw/inc/undobj.hxx
index afb4ecee7184..2e84ff9c1d6e 100644
--- a/sw/inc/undobj.hxx
+++ b/sw/inc/undobj.hxx
@@ -119,11 +119,9 @@ public:
 
     bool IsDelBox() const;
 
-    enum class DelRange { Ignore, Delete, DeleteNonJoining };
     // Save and set Redline data.
     static bool FillSaveData( const SwPaM& rRange, SwRedlineSaveDatas& rSData,
-                              DelRange eDelRange = DelRange::Delete,
-                              bool bCopyNext = true );
+                              bool bDelRange = true, bool bCopyNext = true );
     static bool FillSaveDataForFormat( const SwPaM& , SwRedlineSaveDatas& );
     static void SetSaveData( SwDoc& rDoc, SwRedlineSaveDatas& rSData );
     static bool HasHiddenRedlines( const SwRedlineSaveDatas& rSData );
diff --git a/sw/source/core/doc/DocumentContentOperationsManager.cxx b/sw/source/core/doc/DocumentContentOperationsManager.cxx
index 688318420c85..f6a2562983cd 100644
--- a/sw/source/core/doc/DocumentContentOperationsManager.cxx
+++ b/sw/source/core/doc/DocumentContentOperationsManager.cxx
@@ -2831,8 +2831,7 @@ SwDrawFrameFormat* DocumentContentOperationsManager::InsertDrawObj(
     return pFormat;
 }
 
-bool DocumentContentOperationsManager::SplitNode( const SwPosition &rPos, bool bChkTableStart,
-        std::function<void ()> const*const pRedlineRestore)
+bool DocumentContentOperationsManager::SplitNode( const SwPosition &rPos, bool bChkTableStart )
 {
     SwContentNode *pNode = rPos.nNode.GetNode().GetContentNode();
     if(nullptr == pNode)
@@ -2966,10 +2965,6 @@ bool DocumentContentOperationsManager::SplitNode( const SwPosition &rPos, bool b
                         m_rDoc.getIDocumentRedlineAccess().SplitRedline(aPam);
                     }
                 }
-                if (pRedlineRestore)
-                {
-                    (*pRedlineRestore)();
-                }
             }
         });
     pNode->GetTextNode()->SplitContentNode(rPos, &restoreFunc);
diff --git a/sw/source/core/doc/DocumentRedlineManager.cxx b/sw/source/core/doc/DocumentRedlineManager.cxx
index beb8728b0c9a..ad9c292810a1 100644
--- a/sw/source/core/doc/DocumentRedlineManager.cxx
+++ b/sw/source/core/doc/DocumentRedlineManager.cxx
@@ -1923,7 +1923,7 @@ bool DocumentRedlineManager::SplitRedline( const SwPaM& rRange )
 }
 
 bool DocumentRedlineManager::DeleteRedline( const SwPaM& rRange, bool bSaveInUndo,
-        sal_uInt16 const nDelType, bool const bIgnoreJoining)
+                            sal_uInt16 nDelType )
 {
     if( RedlineFlags::IgnoreDeleteRedlines & meRedlineFlags ||
         !rRange.HasMark() || *rRange.GetMark() == *rRange.GetPoint() )
@@ -1956,13 +1956,6 @@ bool DocumentRedlineManager::DeleteRedline( const SwPaM& rRange, bool bSaveInUnd
         SwPosition* pRStt = pRedl->Start(),
                   * pREnd = pRStt == pRedl->GetPoint() ? pRedl->GetMark()
                                                        : pRedl->GetPoint();
-        if (bIgnoreJoining && pRStt->nNode != pREnd->nNode
-            && pRStt->nNode.GetIndex() <= pStt->nNode.GetIndex()
-            && pEnd->nNode.GetIndex() <= pREnd->nNode.GetIndex())
-        {
-            continue; // ignore node-joining redline
-        }
-
         switch( ComparePosition( *pStt, *pEnd, *pRStt, *pREnd ) )
         {
         case SwComparePosition::Equal:
diff --git a/sw/source/core/inc/DocumentContentOperationsManager.hxx b/sw/source/core/inc/DocumentContentOperationsManager.hxx
index 55f15ad3b79e..c60676617b78 100644
--- a/sw/source/core/inc/DocumentContentOperationsManager.hxx
+++ b/sw/source/core/inc/DocumentContentOperationsManager.hxx
@@ -78,8 +78,7 @@ public:
     SwFlyFrameFormat* InsertOLE(const SwPaM &rRg, const OUString& rObjName, sal_Int64 nAspect, const SfxItemSet* pFlyAttrSet,
                            const SfxItemSet* pGrfAttrSet) override;
 
-    bool SplitNode(const SwPosition &rPos, bool bChkTableStart,
-        std::function<void ()> const* pRedlineRestore = nullptr) override;
+    bool SplitNode(const SwPosition &rPos, bool bChkTableStart) override;
 
     bool AppendTextNode(SwPosition& rPos) override;
 
diff --git a/sw/source/core/inc/DocumentRedlineManager.hxx b/sw/source/core/inc/DocumentRedlineManager.hxx
index d9cdf7ca3e59..f534cccea3fd 100644
--- a/sw/source/core/inc/DocumentRedlineManager.hxx
+++ b/sw/source/core/inc/DocumentRedlineManager.hxx
@@ -61,7 +61,7 @@ public:
     virtual bool DeleteRedline(
         /*[in]*/const SwPaM& rPam,
         /*[in]*/bool bSaveInUndo,
-        /*[in]*/sal_uInt16 nDelType, bool bIgnoreJoining = false) override;
+        /*[in]*/sal_uInt16 nDelType) override;
 
     virtual bool DeleteRedline(
         /*[in]*/const SwStartNode& rSection,
diff --git a/sw/source/core/inc/UndoDelete.hxx b/sw/source/core/inc/UndoDelete.hxx
index 91840ff5554b..7a155fb20322 100644
--- a/sw/source/core/inc/UndoDelete.hxx
+++ b/sw/source/core/inc/UndoDelete.hxx
@@ -41,7 +41,6 @@ class SwUndoDelete
     std::unique_ptr<SwNodeIndex> m_pMvStt;            // Position of Nodes in UndoNodes-Array
     boost::optional<OUString> m_aSttStr, m_aEndStr;
     std::unique_ptr<SwRedlineSaveDatas> m_pRedlSaveData;
-    std::unique_ptr<SwRedlineSaveDatas> m_pRedlSaveDataAtEnd;
     std::shared_ptr< ::sfx2::MetadatableUndo > m_pMetadataUndoStart;
     std::shared_ptr< ::sfx2::MetadatableUndo > m_pMetadataUndoEnd;
 
diff --git a/sw/source/core/undo/undel.cxx b/sw/source/core/undo/undel.cxx
index 0b7e93979016..7e942b427ecb 100644
--- a/sw/source/core/undo/undel.cxx
+++ b/sw/source/core/undo/undel.cxx
@@ -32,8 +32,6 @@
 #include <swundo.hxx>
 #include <pam.hxx>
 #include <ndtxt.hxx>
-#include <txtfrm.hxx>
-#include <rootfrm.hxx>
 #include <UndoCore.hxx>
 #include <rolbck.hxx>
 #include <poolfmt.hxx>
@@ -121,15 +119,11 @@ SwUndoDelete::SwUndoDelete(
     bCacheComment = false;
 
     SwDoc * pDoc = rPam.GetDoc();
-    bool bMustDelete(false);
 
     if( !pDoc->getIDocumentRedlineAccess().IsIgnoreRedline() && !pDoc->getIDocumentRedlineAccess().GetRedlineTable().empty() )
     {
         m_pRedlSaveData.reset(new SwRedlineSaveDatas);
-//        if (!FillSaveData(rPam, *m_pRedlSaveData, false /*true in 2nd call*/))
-        bMustDelete = rPam.GetPoint()->nNode != rPam.GetMark()->nNode;
-//        if (!FillSaveData(rPam, *m_pRedlSaveData, rPam.GetPoint()->nNode == rPam.GetMark()->nNode))
-        if (!FillSaveData(rPam, *m_pRedlSaveData, SwUndo::DelRange::DeleteNonJoining))
+        if( !FillSaveData( rPam, *m_pRedlSaveData ))
         {
             m_pRedlSaveData.reset();
         }
@@ -216,7 +210,7 @@ SwUndoDelete::SwUndoDelete(
 
     if( !pSttTextNd && !pEndTextNd )
         --rPam.GetPoint()->nNode;
-//    rPam.DeleteMark();          // the SPoint is in the selection
+    rPam.DeleteMark();          // the SPoint is in the selection
 
     if( !pEndTextNd )
         nEndContent = 0;
@@ -360,22 +354,6 @@ SwUndoDelete::SwUndoDelete(
     // is a history necessary here at all?
     if( pHistory && !pHistory->Count() )
         pHistory.reset();
-
-    assert(pDoc->getIDocumentRedlineAccess().IsIgnoreRedline()
-        || pDoc->getIDocumentRedlineAccess().GetRedlineTable().empty()
-        || (pStt->nNode != pEnd->nNode) == bMustDelete);
-    if (pStt->nNode != pEnd->nNode
-        && !pDoc->getIDocumentRedlineAccess().IsIgnoreRedline()
-        && !pDoc->getIDocumentRedlineAccess().GetRedlineTable().empty())
-    {   // horrible duplication that SplitNode can undo
-        m_pRedlSaveDataAtEnd.reset(new SwRedlineSaveDatas);
-        if (!FillSaveData(rPam, *m_pRedlSaveDataAtEnd))
-        {
-            m_pRedlSaveDataAtEnd.reset();
-        }
-    }
-
-    rPam.DeleteMark(); // now it is no longer a range...
 }
 
 bool SwUndoDelete::SaveContent( const SwPosition* pStt, const SwPosition* pEnd,
@@ -506,7 +484,7 @@ bool SwUndoDelete::CanGrouping( SwDoc* pDoc, const SwPaM& rDelPam )
 
     {
         SwRedlineSaveDatas aTmpSav;
-        const bool bSaved = FillSaveData(rDelPam, aTmpSav, SwUndo::DelRange::Ignore);
+        const bool bSaved = FillSaveData( rDelPam, aTmpSav, false );
 
         bool bOk = ( !m_pRedlSaveData && !bSaved ) ||
                    ( m_pRedlSaveData && bSaved &&
@@ -810,7 +788,6 @@ void SwUndoDelete::UndoImpl(::sw::UndoRedoContext & rContext)
             pInsNd = nullptr;         // do not delete Node!
 
         bool bNodeMove = 0 != m_nNode;
-        bool bRedlAtEndRestored(false);
 
         if( m_aEndStr )
         {
@@ -826,17 +803,7 @@ void SwUndoDelete::UndoImpl(::sw::UndoRedoContext & rContext)
             if( m_aSttStr && !m_bFromTableCopy )
             {
                 sal_uLong nOldIdx = aPos.nNode.GetIndex();
-                // call this before messing with frames in SplitNode
-                std::function<void ()> restoreFunc(
-                    [&]()
-                    {
-                        if (m_pRedlSaveDataAtEnd)
-                        {
-                            SetSaveData(rDoc, *m_pRedlSaveDataAtEnd);
-                        }
-                    });
-                rDoc.getIDocumentContentOperations().SplitNode(aPos, false, &restoreFunc);
-                bRedlAtEndRestored = true;
+                rDoc.getIDocumentContentOperations().SplitNode( aPos, false );
                 // After the split all objects are anchored at the first
                 // paragraph, but the pHistory of the fly frame formats relies
                 // on anchoring at the start of the selection
@@ -845,11 +812,6 @@ void SwUndoDelete::UndoImpl(::sw::UndoRedoContext & rContext)
                     lcl_ReAnchorAtContentFlyFrames(*rDoc.GetSpzFrameFormats(), aPos, nOldIdx);
                 pTextNd = aPos.nNode.GetNode().GetTextNode();
             }
-            else if (m_pRedlSaveDataAtEnd)
-            {
-                SetSaveData(rDoc, *m_pRedlSaveDataAtEnd);
-                bRedlAtEndRestored = true;
-            }
             if( pTextNd )
             {
                 OUString const ins( pTextNd->InsertText(*m_aEndStr, aPos.nContent,
@@ -868,30 +830,14 @@ void SwUndoDelete::UndoImpl(::sw::UndoRedoContext & rContext)
                 if (nSttContent < pNd->GetText().getLength())
                 {
                     sal_uLong nOldIdx = aPos.nNode.GetIndex();
-                    // call this before messing with frames in SplitNode
-                    std::function<void ()> restoreFunc(
-                        [&]()
-                        {
-                            if (m_pRedlSaveDataAtEnd)
-                            {
-                                SetSaveData(rDoc, *m_pRedlSaveDataAtEnd);
-                            }
-                        });
-                    rDoc.getIDocumentContentOperations().SplitNode(aPos, false, &restoreFunc);
-                    bRedlAtEndRestored = true;
+                    rDoc.getIDocumentContentOperations().SplitNode( aPos, false );
                     if( m_bBackSp )
                         lcl_ReAnchorAtContentFlyFrames(*rDoc.GetSpzFrameFormats(), aPos, nOldIdx);
                 }
                 else
-                {
                     ++aPos.nNode;
-                }
             }
         }
-        if (!bRedlAtEndRestored && m_pRedlSaveDataAtEnd)
-        {
-            SetSaveData(rDoc, *m_pRedlSaveDataAtEnd);
-        }
         SwNode* pMovedNode = nullptr;
         if( m_nSectDiff )
         {
@@ -920,23 +866,7 @@ void SwUndoDelete::UndoImpl(::sw::UndoRedoContext & rContext)
         {
             SwNodeRange aRange( *m_pMvStt, 0, *m_pMvStt, m_nNode );
             SwNodeIndex aCopyIndex( aPos.nNode, -1 );
-            rDoc.GetUndoManager().GetUndoNodes().Copy_(aRange, aPos.nNode,
-                    // SplitNode would have inited this flag; at this point,
-                    // either all these nodes are Hidden or all are None
-                    // (it might be that in the None case, the 2nd SetSaveData
-                    //  below will introduce new redlines...)
-                    false);
-#if 0
-                    aPos.nNode.GetRedlineMergeFlag() == SwNode::Merge::None);
-#endif
-            if (aPos.nNode.GetNode().GetRedlineMergeFlag() != SwNode::Merge::None)
-            {
-                for (sal_uLong i = aCopyIndex.GetIndex() + m_nNode; aCopyIndex.GetIndex() < i; --i)
-                {
-                    rDoc.GetNodes()[i]->SetRedlineMergeFlag(SwNode::Merge::Hidden);
-                }
-            }
-            // TODO after the SetSaveData we need to check again ???
+            rDoc.GetUndoManager().GetUndoNodes().Copy_( aRange, aPos.nNode );
 
             if( m_nReplaceDummy )
             {
@@ -1026,62 +956,8 @@ void SwUndoDelete::UndoImpl(::sw::UndoRedoContext & rContext)
     if( pInsNd )
         rDoc.GetNodes().Delete( aIdx );
     if( m_pRedlSaveData )
-    {
         SetSaveData(rDoc, *m_pRedlSaveData);
 
-#if 0
-        if (m_aSttStr && (!m_bFromTableCopy || 0 != m_nNode))
-        {
-            // only now do we have redlines in the document again; fix up the frame
-            SwTextNode *const pStartNode(aIdx.GetNodes()[nSttNode]->GetTextNode());
-            SwTextNode *const pEndNode(aIdx.GetNodes()[nEndNode]->GetTextNode());
-            // FIXME we need to fetch frame of end node????
-            // the MakeCopy already creates frames of intermediate nodes depending on their flag... problem: deletion was with redlines shown, restore with hidden
-            assert(pNode);
-            std::vector<SwTextFrame*> frames;
-            SwIterator<SwTextFrame, SwTextNode, sw::IteratorMode::UnwrapMulti> aIter(*pEndNode);
-            for (SwTextFrame* pFrame = aIter.First(); pFrame; pFrame = aIter.Next())
-            {
-                if (pFrame->getRootFrame()->IsHideRedlines())
-                {
-                    frames.push_back(pFrame);
-                }
-            }
-            for (SwTextFrame * pFrame : frames)
-            {
-// this is not going to work if there are intermediate nodes with frames                pFrame->RegisterToNode(*pStartNode);
-#if 0
-                SwTextNode & rFirstNode(pFrame->GetMergedPara()
-                    ? *pFrame->GetMergedPara()->pFirstNode
-                    : *pStartNode);
-                assert(rFirstNode.GetIndex() <= pNode->GetIndex());
-                pFrame->SetMergedPara(sw::CheckParaRedlineMerge(
-                            *pFrame, rFirstNode, sw::FrameMode::Existing));
-#endif
-            }
-        }
-#endif
-    }
-
-    // create frames after SetSaveData has recreated redlines
-    if (0 != m_nNode)
-    {
-        SwNodeIndex const start(rDoc.GetNodes(), nSttNode + 1);
-        SwNodeIndex const end(rDoc.GetNodes(), nEndNode);
-        ::MakeFrames(&rDoc, start, end);
-    }
-
-    // ... plan: let SplitNode do whatever;
-    // don't create frames on moved nodes;
-    // after SetSaveData, call CheckRedline... on start node,
-    // then MakeFrames
-    // ... what about end node ? will be either properly merged or properly un-merged after handling start node, so just include it in MakeFrames range.
-    //
-    // The interesting case is
-    //  f<delete start>o<redline start>o
-    //  b<redline end>a<redline start>r
-    //  b<redline end>a<delete end>z
-
     AddUndoRedoPaM(rContext, true);
 }
 
diff --git a/sw/source/core/undo/undobj.cxx b/sw/source/core/undo/undobj.cxx
index 94299badd501..5afbde167ad2 100644
--- a/sw/source/core/undo/undobj.cxx
+++ b/sw/source/core/undo/undobj.cxx
@@ -1378,7 +1378,7 @@ void SwRedlineSaveData::RedlineToDoc( SwPaM const & rPam )
 bool SwUndo::FillSaveData(
     const SwPaM& rRange,
     SwRedlineSaveDatas& rSData,
-    DelRange const eDelRange,
+    bool bDelRange,
     bool bCopyNext )
 {
     rSData.clear();
@@ -1403,10 +1403,9 @@ bool SwUndo::FillSaveData(
             rSData.push_back(std::unique_ptr<SwRedlineSaveData, o3tl::default_delete<SwRedlineSaveData>>(new SwRedlineSaveData(eCmpPos, *pStt, *pEnd, *pRedl, bCopyNext)));
         }
     }
-    if (!rSData.empty() && eDelRange != DelRange::Ignore)
+    if( !rSData.empty() && bDelRange )
     {
-        rRange.GetDoc()->getIDocumentRedlineAccess().DeleteRedline(
-            rRange, false, USHRT_MAX, eDelRange == DelRange::DeleteNonJoining);
+        rRange.GetDoc()->getIDocumentRedlineAccess().DeleteRedline( rRange, false, USHRT_MAX );
     }
     return !rSData.empty();
 }
diff --git a/sw/source/core/undo/unovwr.cxx b/sw/source/core/undo/unovwr.cxx
index 6e6a64fbd52a..e2fb76a19f63 100644
--- a/sw/source/core/undo/unovwr.cxx
+++ b/sw/source/core/undo/unovwr.cxx
@@ -48,7 +48,7 @@ SwUndoOverwrite::SwUndoOverwrite( SwDoc* pDoc, SwPosition& rPos,
         SwPaM aPam( rPos.nNode, rPos.nContent.GetIndex(),
                     rPos.nNode, rPos.nContent.GetIndex()+1 );
         pRedlSaveData.reset( new SwRedlineSaveDatas );
-        if (!FillSaveData( aPam, *pRedlSaveData, SwUndo::DelRange::Ignore))
+        if( !FillSaveData( aPam, *pRedlSaveData, false ))
         {
             pRedlSaveData.reset();
         }
@@ -125,7 +125,7 @@ bool SwUndoOverwrite::CanGrouping( SwDoc* pDoc, SwPosition& rPos,
         SwPaM aPam( rPos.nNode, rPos.nContent.GetIndex(),
                     rPos.nNode, rPos.nContent.GetIndex()+1 );
 
-        const bool bSaved = FillSaveData(aPam, aTmpSav, SwUndo::DelRange::Ignore);
+        const bool bSaved = FillSaveData( aPam, aTmpSav, false );
 
         bool bOk = ( !pRedlSaveData && !bSaved ) ||
                    ( pRedlSaveData && bSaved &&
diff --git a/sw/source/core/undo/unredln.cxx b/sw/source/core/undo/unredln.cxx
index 9bdad5c20299..58d2de808363 100644
--- a/sw/source/core/undo/unredln.cxx
+++ b/sw/source/core/undo/unredln.cxx
@@ -58,8 +58,7 @@ SwUndoRedline::SwUndoRedline( SwUndoId nUsrId, const SwPaM& rRange )
     sal_uLong nEndExtra = rDoc.GetNodes().GetEndOfExtras().GetIndex();
 
     mpRedlSaveData.reset( new SwRedlineSaveDatas );
-    if (!FillSaveData(rRange, *mpRedlSaveData, SwUndo::DelRange::Ignore,
-                      SwUndoId::REJECT_REDLINE != mnUserId))
+    if( !FillSaveData( rRange, *mpRedlSaveData, false, SwUndoId::REJECT_REDLINE != mnUserId ))
     {
         mpRedlSaveData.reset();
     }
@@ -119,8 +118,7 @@ void SwUndoRedline::RedoImpl(::sw::UndoRedoContext & rContext)
     if( mpRedlSaveData && mbHiddenRedlines )
     {
         sal_uLong nEndExtra = rDoc.GetNodes().GetEndOfExtras().GetIndex();
-        FillSaveData(rPam, *mpRedlSaveData, SwUndo::DelRange::Ignore,
-                SwUndoId::REJECT_REDLINE != mnUserId);
+        FillSaveData(rPam, *mpRedlSaveData, false, SwUndoId::REJECT_REDLINE != mnUserId );
 
         nEndExtra -= rDoc.GetNodes().GetEndOfExtras().GetIndex();
         nSttNode -= nEndExtra;
@@ -399,7 +397,7 @@ SwUndoCompDoc::SwUndoCompDoc( const SwRangeRedline& rRedl )
     }
 
     pRedlSaveData.reset( new SwRedlineSaveDatas );
-    if (!FillSaveData( rRedl, *pRedlSaveData, SwUndo::DelRange::Ignore))
+    if( !FillSaveData( rRedl, *pRedlSaveData, false ))
     {
         pRedlSaveData.reset();
     }
diff --git a/sw/source/core/undo/unsect.cxx b/sw/source/core/undo/unsect.cxx
index b225ae42235e..f17cae630316 100644
--- a/sw/source/core/undo/unsect.cxx
+++ b/sw/source/core/undo/unsect.cxx
@@ -88,7 +88,7 @@ SwUndoInsSection::SwUndoInsSection(
         SetRedlineFlags( rDoc.getIDocumentRedlineAccess().GetRedlineFlags() );
     }
         m_pRedlineSaveData.reset( new SwRedlineSaveDatas );
-        if (!FillSaveData( rPam, *m_pRedlineSaveData, SwUndo::DelRange::Ignore))
+        if( !FillSaveData( rPam, *m_pRedlineSaveData, false ))
             m_pRedlineSaveData.reset( nullptr );
 
     if( !rPam.HasMark() )
commit bbc47b4fed2e88615bd871946555eafa240fe71e
Author:     Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Wed Aug 22 13:22:29 2018 +0200
Commit:     Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Wed Aug 22 14:51:43 2018 +0200

    this looks like a wrong path...
    
    Change-Id: I81181ecb8fa3bae47e9dc0d2a5b49b92608629e6

diff --git a/sw/inc/IDocumentContentOperations.hxx b/sw/inc/IDocumentContentOperations.hxx
index fb4006334a15..b3204109a8a0 100644
--- a/sw/inc/IDocumentContentOperations.hxx
+++ b/sw/inc/IDocumentContentOperations.hxx
@@ -22,6 +22,7 @@
 
 #include <sal/types.h>
 #include <rtl/ustring.hxx>
+#include <functional>
 #include "swtypes.hxx"
 
 class SwPaM;
@@ -37,6 +38,9 @@ class SwFrameFormat;
 class SwDrawFrameFormat;
 class SwFlyFrameFormat;
 class SwNodeIndex;
+class SwTextNode;
+
+namespace sw { namespace mark { enum class RestoreMode; } }
 
 namespace utl { class TransliterationWrapper; }
 namespace svt { class EmbeddedObjectRef; }
@@ -186,7 +190,8 @@ public:
 
     /** Split a node at rPos (implemented only for TextNode).
     */
-    virtual bool SplitNode(const SwPosition &rPos, bool bChkTableStart) = 0;
+    virtual bool SplitNode(const SwPosition &rPos, bool bChkTableStart,
+        std::function<void ()> const* pRedlineRestore = nullptr) = 0;
 
     virtual bool AppendTextNode(SwPosition& rPos) = 0;
 
diff --git a/sw/inc/IDocumentRedlineAccess.hxx b/sw/inc/IDocumentRedlineAccess.hxx
index a68af07fb707..d6c44b24e680 100644
--- a/sw/inc/IDocumentRedlineAccess.hxx
+++ b/sw/inc/IDocumentRedlineAccess.hxx
@@ -180,7 +180,7 @@ public:
     virtual bool DeleteRedline(
         /*[in]*/const SwPaM& rPam,
         /*[in]*/bool bSaveInUndo,
-        /*[in]*/sal_uInt16 nDelType) = 0;
+        /*[in]*/sal_uInt16 nDelType, bool bIgnoreJoining = false) = 0;
 
     virtual bool DeleteRedline(
         /*[in]*/const SwStartNode& rSection,
diff --git a/sw/inc/undobj.hxx b/sw/inc/undobj.hxx
index 2e84ff9c1d6e..afb4ecee7184 100644
--- a/sw/inc/undobj.hxx
+++ b/sw/inc/undobj.hxx
@@ -119,9 +119,11 @@ public:
 
     bool IsDelBox() const;
 
+    enum class DelRange { Ignore, Delete, DeleteNonJoining };
     // Save and set Redline data.
     static bool FillSaveData( const SwPaM& rRange, SwRedlineSaveDatas& rSData,
-                              bool bDelRange = true, bool bCopyNext = true );
+                              DelRange eDelRange = DelRange::Delete,
+                              bool bCopyNext = true );
     static bool FillSaveDataForFormat( const SwPaM& , SwRedlineSaveDatas& );
     static void SetSaveData( SwDoc& rDoc, SwRedlineSaveDatas& rSData );
     static bool HasHiddenRedlines( const SwRedlineSaveDatas& rSData );
diff --git a/sw/source/core/doc/DocumentContentOperationsManager.cxx b/sw/source/core/doc/DocumentContentOperationsManager.cxx
index f6a2562983cd..688318420c85 100644
--- a/sw/source/core/doc/DocumentContentOperationsManager.cxx
+++ b/sw/source/core/doc/DocumentContentOperationsManager.cxx
@@ -2831,7 +2831,8 @@ SwDrawFrameFormat* DocumentContentOperationsManager::InsertDrawObj(
     return pFormat;
 }
 
-bool DocumentContentOperationsManager::SplitNode( const SwPosition &rPos, bool bChkTableStart )
+bool DocumentContentOperationsManager::SplitNode( const SwPosition &rPos, bool bChkTableStart,
+        std::function<void ()> const*const pRedlineRestore)
 {
     SwContentNode *pNode = rPos.nNode.GetNode().GetContentNode();
     if(nullptr == pNode)
@@ -2965,6 +2966,10 @@ bool DocumentContentOperationsManager::SplitNode( const SwPosition &rPos, bool b
                         m_rDoc.getIDocumentRedlineAccess().SplitRedline(aPam);
                     }
                 }
+                if (pRedlineRestore)
+                {
+                    (*pRedlineRestore)();
+                }
             }
         });
     pNode->GetTextNode()->SplitContentNode(rPos, &restoreFunc);
diff --git a/sw/source/core/doc/DocumentRedlineManager.cxx b/sw/source/core/doc/DocumentRedlineManager.cxx
index ad9c292810a1..beb8728b0c9a 100644
--- a/sw/source/core/doc/DocumentRedlineManager.cxx
+++ b/sw/source/core/doc/DocumentRedlineManager.cxx
@@ -1923,7 +1923,7 @@ bool DocumentRedlineManager::SplitRedline( const SwPaM& rRange )
 }
 
 bool DocumentRedlineManager::DeleteRedline( const SwPaM& rRange, bool bSaveInUndo,
-                            sal_uInt16 nDelType )
+        sal_uInt16 const nDelType, bool const bIgnoreJoining)
 {
     if( RedlineFlags::IgnoreDeleteRedlines & meRedlineFlags ||
         !rRange.HasMark() || *rRange.GetMark() == *rRange.GetPoint() )
@@ -1956,6 +1956,13 @@ bool DocumentRedlineManager::DeleteRedline( const SwPaM& rRange, bool bSaveInUnd
         SwPosition* pRStt = pRedl->Start(),
                   * pREnd = pRStt == pRedl->GetPoint() ? pRedl->GetMark()
                                                        : pRedl->GetPoint();
+        if (bIgnoreJoining && pRStt->nNode != pREnd->nNode
+            && pRStt->nNode.GetIndex() <= pStt->nNode.GetIndex()
+            && pEnd->nNode.GetIndex() <= pREnd->nNode.GetIndex())
+        {
+            continue; // ignore node-joining redline
+        }
+
         switch( ComparePosition( *pStt, *pEnd, *pRStt, *pREnd ) )
         {
         case SwComparePosition::Equal:
diff --git a/sw/source/core/inc/DocumentContentOperationsManager.hxx b/sw/source/core/inc/DocumentContentOperationsManager.hxx
index c60676617b78..55f15ad3b79e 100644
--- a/sw/source/core/inc/DocumentContentOperationsManager.hxx
+++ b/sw/source/core/inc/DocumentContentOperationsManager.hxx
@@ -78,7 +78,8 @@ public:
     SwFlyFrameFormat* InsertOLE(const SwPaM &rRg, const OUString& rObjName, sal_Int64 nAspect, const SfxItemSet* pFlyAttrSet,
                            const SfxItemSet* pGrfAttrSet) override;
 
-    bool SplitNode(const SwPosition &rPos, bool bChkTableStart) override;
+    bool SplitNode(const SwPosition &rPos, bool bChkTableStart,
+        std::function<void ()> const* pRedlineRestore = nullptr) override;
 
     bool AppendTextNode(SwPosition& rPos) override;
 
diff --git a/sw/source/core/inc/DocumentRedlineManager.hxx b/sw/source/core/inc/DocumentRedlineManager.hxx
index f534cccea3fd..d9cdf7ca3e59 100644
--- a/sw/source/core/inc/DocumentRedlineManager.hxx
+++ b/sw/source/core/inc/DocumentRedlineManager.hxx
@@ -61,7 +61,7 @@ public:
     virtual bool DeleteRedline(
         /*[in]*/const SwPaM& rPam,
         /*[in]*/bool bSaveInUndo,
-        /*[in]*/sal_uInt16 nDelType) override;
+        /*[in]*/sal_uInt16 nDelType, bool bIgnoreJoining = false) override;
 
     virtual bool DeleteRedline(
         /*[in]*/const SwStartNode& rSection,
diff --git a/sw/source/core/inc/UndoDelete.hxx b/sw/source/core/inc/UndoDelete.hxx
index 7a155fb20322..91840ff5554b 100644
--- a/sw/source/core/inc/UndoDelete.hxx
+++ b/sw/source/core/inc/UndoDelete.hxx
@@ -41,6 +41,7 @@ class SwUndoDelete
     std::unique_ptr<SwNodeIndex> m_pMvStt;            // Position of Nodes in UndoNodes-Array
     boost::optional<OUString> m_aSttStr, m_aEndStr;
     std::unique_ptr<SwRedlineSaveDatas> m_pRedlSaveData;
+    std::unique_ptr<SwRedlineSaveDatas> m_pRedlSaveDataAtEnd;
     std::shared_ptr< ::sfx2::MetadatableUndo > m_pMetadataUndoStart;
     std::shared_ptr< ::sfx2::MetadatableUndo > m_pMetadataUndoEnd;
 
diff --git a/sw/source/core/undo/undel.cxx b/sw/source/core/undo/undel.cxx
index 7e942b427ecb..0b7e93979016 100644
--- a/sw/source/core/undo/undel.cxx
+++ b/sw/source/core/undo/undel.cxx
@@ -32,6 +32,8 @@
 #include <swundo.hxx>
 #include <pam.hxx>
 #include <ndtxt.hxx>
+#include <txtfrm.hxx>
+#include <rootfrm.hxx>
 #include <UndoCore.hxx>
 #include <rolbck.hxx>
 #include <poolfmt.hxx>
@@ -119,11 +121,15 @@ SwUndoDelete::SwUndoDelete(
     bCacheComment = false;
 
     SwDoc * pDoc = rPam.GetDoc();
+    bool bMustDelete(false);
 
     if( !pDoc->getIDocumentRedlineAccess().IsIgnoreRedline() && !pDoc->getIDocumentRedlineAccess().GetRedlineTable().empty() )
     {
         m_pRedlSaveData.reset(new SwRedlineSaveDatas);
-        if( !FillSaveData( rPam, *m_pRedlSaveData ))
+//        if (!FillSaveData(rPam, *m_pRedlSaveData, false /*true in 2nd call*/))
+        bMustDelete = rPam.GetPoint()->nNode != rPam.GetMark()->nNode;
+//        if (!FillSaveData(rPam, *m_pRedlSaveData, rPam.GetPoint()->nNode == rPam.GetMark()->nNode))
+        if (!FillSaveData(rPam, *m_pRedlSaveData, SwUndo::DelRange::DeleteNonJoining))
         {
             m_pRedlSaveData.reset();
         }
@@ -210,7 +216,7 @@ SwUndoDelete::SwUndoDelete(
 
     if( !pSttTextNd && !pEndTextNd )
         --rPam.GetPoint()->nNode;
-    rPam.DeleteMark();          // the SPoint is in the selection
+//    rPam.DeleteMark();          // the SPoint is in the selection
 
     if( !pEndTextNd )
         nEndContent = 0;
@@ -354,6 +360,22 @@ SwUndoDelete::SwUndoDelete(
     // is a history necessary here at all?
     if( pHistory && !pHistory->Count() )
         pHistory.reset();
+
+    assert(pDoc->getIDocumentRedlineAccess().IsIgnoreRedline()
+        || pDoc->getIDocumentRedlineAccess().GetRedlineTable().empty()
+        || (pStt->nNode != pEnd->nNode) == bMustDelete);
+    if (pStt->nNode != pEnd->nNode
+        && !pDoc->getIDocumentRedlineAccess().IsIgnoreRedline()
+        && !pDoc->getIDocumentRedlineAccess().GetRedlineTable().empty())
+    {   // horrible duplication that SplitNode can undo
+        m_pRedlSaveDataAtEnd.reset(new SwRedlineSaveDatas);
+        if (!FillSaveData(rPam, *m_pRedlSaveDataAtEnd))
+        {
+            m_pRedlSaveDataAtEnd.reset();
+        }
+    }
+
+    rPam.DeleteMark(); // now it is no longer a range...
 }
 
 bool SwUndoDelete::SaveContent( const SwPosition* pStt, const SwPosition* pEnd,
@@ -484,7 +506,7 @@ bool SwUndoDelete::CanGrouping( SwDoc* pDoc, const SwPaM& rDelPam )
 
     {
         SwRedlineSaveDatas aTmpSav;
-        const bool bSaved = FillSaveData( rDelPam, aTmpSav, false );
+        const bool bSaved = FillSaveData(rDelPam, aTmpSav, SwUndo::DelRange::Ignore);
 
         bool bOk = ( !m_pRedlSaveData && !bSaved ) ||
                    ( m_pRedlSaveData && bSaved &&
@@ -788,6 +810,7 @@ void SwUndoDelete::UndoImpl(::sw::UndoRedoContext & rContext)
             pInsNd = nullptr;         // do not delete Node!
 
         bool bNodeMove = 0 != m_nNode;
+        bool bRedlAtEndRestored(false);
 
         if( m_aEndStr )
         {
@@ -803,7 +826,17 @@ void SwUndoDelete::UndoImpl(::sw::UndoRedoContext & rContext)
             if( m_aSttStr && !m_bFromTableCopy )
             {
                 sal_uLong nOldIdx = aPos.nNode.GetIndex();
-                rDoc.getIDocumentContentOperations().SplitNode( aPos, false );
+                // call this before messing with frames in SplitNode
+                std::function<void ()> restoreFunc(
+                    [&]()
+                    {
+                        if (m_pRedlSaveDataAtEnd)
+                        {
+                            SetSaveData(rDoc, *m_pRedlSaveDataAtEnd);
+                        }
+                    });
+                rDoc.getIDocumentContentOperations().SplitNode(aPos, false, &restoreFunc);
+                bRedlAtEndRestored = true;
                 // After the split all objects are anchored at the first
                 // paragraph, but the pHistory of the fly frame formats relies
                 // on anchoring at the start of the selection
@@ -812,6 +845,11 @@ void SwUndoDelete::UndoImpl(::sw::UndoRedoContext & rContext)
                     lcl_ReAnchorAtContentFlyFrames(*rDoc.GetSpzFrameFormats(), aPos, nOldIdx);
                 pTextNd = aPos.nNode.GetNode().GetTextNode();
             }
+            else if (m_pRedlSaveDataAtEnd)
+            {
+                SetSaveData(rDoc, *m_pRedlSaveDataAtEnd);
+                bRedlAtEndRestored = true;
+            }
             if( pTextNd )
             {
                 OUString const ins( pTextNd->InsertText(*m_aEndStr, aPos.nContent,
@@ -830,14 +868,30 @@ void SwUndoDelete::UndoImpl(::sw::UndoRedoContext & rContext)
                 if (nSttContent < pNd->GetText().getLength())
                 {
                     sal_uLong nOldIdx = aPos.nNode.GetIndex();
-                    rDoc.getIDocumentContentOperations().SplitNode( aPos, false );
+                    // call this before messing with frames in SplitNode
+                    std::function<void ()> restoreFunc(
+                        [&]()
+                        {
+                            if (m_pRedlSaveDataAtEnd)
+                            {
+                                SetSaveData(rDoc, *m_pRedlSaveDataAtEnd);
+                            }
+                        });
+                    rDoc.getIDocumentContentOperations().SplitNode(aPos, false, &restoreFunc);
+                    bRedlAtEndRestored = true;
                     if( m_bBackSp )
                         lcl_ReAnchorAtContentFlyFrames(*rDoc.GetSpzFrameFormats(), aPos, nOldIdx);
                 }
                 else
+                {
                     ++aPos.nNode;
+                }
             }
         }
+        if (!bRedlAtEndRestored && m_pRedlSaveDataAtEnd)
+        {
+            SetSaveData(rDoc, *m_pRedlSaveDataAtEnd);
+        }
         SwNode* pMovedNode = nullptr;
         if( m_nSectDiff )
         {
@@ -866,7 +920,23 @@ void SwUndoDelete::UndoImpl(::sw::UndoRedoContext & rContext)
         {
             SwNodeRange aRange( *m_pMvStt, 0, *m_pMvStt, m_nNode );
             SwNodeIndex aCopyIndex( aPos.nNode, -1 );
-            rDoc.GetUndoManager().GetUndoNodes().Copy_( aRange, aPos.nNode );
+            rDoc.GetUndoManager().GetUndoNodes().Copy_(aRange, aPos.nNode,
+                    // SplitNode would have inited this flag; at this point,
+                    // either all these nodes are Hidden or all are None
+                    // (it might be that in the None case, the 2nd SetSaveData
+                    //  below will introduce new redlines...)
+                    false);
+#if 0
+                    aPos.nNode.GetRedlineMergeFlag() == SwNode::Merge::None);
+#endif
+            if (aPos.nNode.GetNode().GetRedlineMergeFlag() != SwNode::Merge::None)
+            {
+                for (sal_uLong i = aCopyIndex.GetIndex() + m_nNode; aCopyIndex.GetIndex() < i; --i)
+                {
+                    rDoc.GetNodes()[i]->SetRedlineMergeFlag(SwNode::Merge::Hidden);
+                }
+            }
+            // TODO after the SetSaveData we need to check again ???
 
             if( m_nReplaceDummy )
             {
@@ -956,8 +1026,62 @@ void SwUndoDelete::UndoImpl(::sw::UndoRedoContext & rContext)
     if( pInsNd )
         rDoc.GetNodes().Delete( aIdx );
     if( m_pRedlSaveData )
+    {
         SetSaveData(rDoc, *m_pRedlSaveData);
 
+#if 0
+        if (m_aSttStr && (!m_bFromTableCopy || 0 != m_nNode))
+        {
+            // only now do we have redlines in the document again; fix up the frame
+            SwTextNode *const pStartNode(aIdx.GetNodes()[nSttNode]->GetTextNode());
+            SwTextNode *const pEndNode(aIdx.GetNodes()[nEndNode]->GetTextNode());
+            // FIXME we need to fetch frame of end node????
+            // the MakeCopy already creates frames of intermediate nodes depending on their flag... problem: deletion was with redlines shown, restore with hidden
+            assert(pNode);
+            std::vector<SwTextFrame*> frames;
+            SwIterator<SwTextFrame, SwTextNode, sw::IteratorMode::UnwrapMulti> aIter(*pEndNode);
+            for (SwTextFrame* pFrame = aIter.First(); pFrame; pFrame = aIter.Next())
+            {
+                if (pFrame->getRootFrame()->IsHideRedlines())
+                {
+                    frames.push_back(pFrame);
+                }
+            }
+            for (SwTextFrame * pFrame : frames)
+            {
+// this is not going to work if there are intermediate nodes with frames                pFrame->RegisterToNode(*pStartNode);
+#if 0
+                SwTextNode & rFirstNode(pFrame->GetMergedPara()
+                    ? *pFrame->GetMergedPara()->pFirstNode
+                    : *pStartNode);
+                assert(rFirstNode.GetIndex() <= pNode->GetIndex());
+                pFrame->SetMergedPara(sw::CheckParaRedlineMerge(
+                            *pFrame, rFirstNode, sw::FrameMode::Existing));
+#endif
+            }
+        }
+#endif
+    }
+
+    // create frames after SetSaveData has recreated redlines
+    if (0 != m_nNode)
+    {
+        SwNodeIndex const start(rDoc.GetNodes(), nSttNode + 1);
+        SwNodeIndex const end(rDoc.GetNodes(), nEndNode);
+        ::MakeFrames(&rDoc, start, end);
+    }
+
+    // ... plan: let SplitNode do whatever;
+    // don't create frames on moved nodes;
+    // after SetSaveData, call CheckRedline... on start node,
+    // then MakeFrames
+    // ... what about end node ? will be either properly merged or properly un-merged after handling start node, so just include it in MakeFrames range.
+    //
+    // The interesting case is
+    //  f<delete start>o<redline start>o
+    //  b<redline end>a<redline start>r
+    //  b<redline end>a<delete end>z
+
     AddUndoRedoPaM(rContext, true);
 }
 
diff --git a/sw/source/core/undo/undobj.cxx b/sw/source/core/undo/undobj.cxx
index 5afbde167ad2..94299badd501 100644
--- a/sw/source/core/undo/undobj.cxx
+++ b/sw/source/core/undo/undobj.cxx
@@ -1378,7 +1378,7 @@ void SwRedlineSaveData::RedlineToDoc( SwPaM const & rPam )
 bool SwUndo::FillSaveData(
     const SwPaM& rRange,
     SwRedlineSaveDatas& rSData,
-    bool bDelRange,
+    DelRange const eDelRange,
     bool bCopyNext )
 {
     rSData.clear();
@@ -1403,9 +1403,10 @@ bool SwUndo::FillSaveData(
             rSData.push_back(std::unique_ptr<SwRedlineSaveData, o3tl::default_delete<SwRedlineSaveData>>(new SwRedlineSaveData(eCmpPos, *pStt, *pEnd, *pRedl, bCopyNext)));
         }
     }
-    if( !rSData.empty() && bDelRange )
+    if (!rSData.empty() && eDelRange != DelRange::Ignore)
     {
-        rRange.GetDoc()->getIDocumentRedlineAccess().DeleteRedline( rRange, false, USHRT_MAX );
+        rRange.GetDoc()->getIDocumentRedlineAccess().DeleteRedline(
+            rRange, false, USHRT_MAX, eDelRange == DelRange::DeleteNonJoining);
     }
     return !rSData.empty();
 }
diff --git a/sw/source/core/undo/unovwr.cxx b/sw/source/core/undo/unovwr.cxx
index e2fb76a19f63..6e6a64fbd52a 100644
--- a/sw/source/core/undo/unovwr.cxx
+++ b/sw/source/core/undo/unovwr.cxx
@@ -48,7 +48,7 @@ SwUndoOverwrite::SwUndoOverwrite( SwDoc* pDoc, SwPosition& rPos,
         SwPaM aPam( rPos.nNode, rPos.nContent.GetIndex(),
                     rPos.nNode, rPos.nContent.GetIndex()+1 );
         pRedlSaveData.reset( new SwRedlineSaveDatas );
-        if( !FillSaveData( aPam, *pRedlSaveData, false ))
+        if (!FillSaveData( aPam, *pRedlSaveData, SwUndo::DelRange::Ignore))
         {
             pRedlSaveData.reset();
         }
@@ -125,7 +125,7 @@ bool SwUndoOverwrite::CanGrouping( SwDoc* pDoc, SwPosition& rPos,
         SwPaM aPam( rPos.nNode, rPos.nContent.GetIndex(),
                     rPos.nNode, rPos.nContent.GetIndex()+1 );
 
-        const bool bSaved = FillSaveData( aPam, aTmpSav, false );
+        const bool bSaved = FillSaveData(aPam, aTmpSav, SwUndo::DelRange::Ignore);
 
         bool bOk = ( !pRedlSaveData && !bSaved ) ||
                    ( pRedlSaveData && bSaved &&
diff --git a/sw/source/core/undo/unredln.cxx b/sw/source/core/undo/unredln.cxx
index 58d2de808363..9bdad5c20299 100644
--- a/sw/source/core/undo/unredln.cxx
+++ b/sw/source/core/undo/unredln.cxx
@@ -58,7 +58,8 @@ SwUndoRedline::SwUndoRedline( SwUndoId nUsrId, const SwPaM& rRange )
     sal_uLong nEndExtra = rDoc.GetNodes().GetEndOfExtras().GetIndex();
 
     mpRedlSaveData.reset( new SwRedlineSaveDatas );
-    if( !FillSaveData( rRange, *mpRedlSaveData, false, SwUndoId::REJECT_REDLINE != mnUserId ))
+    if (!FillSaveData(rRange, *mpRedlSaveData, SwUndo::DelRange::Ignore,
+                      SwUndoId::REJECT_REDLINE != mnUserId))
     {
         mpRedlSaveData.reset();
     }
@@ -118,7 +119,8 @@ void SwUndoRedline::RedoImpl(::sw::UndoRedoContext & rContext)
     if( mpRedlSaveData && mbHiddenRedlines )
     {
         sal_uLong nEndExtra = rDoc.GetNodes().GetEndOfExtras().GetIndex();
-        FillSaveData(rPam, *mpRedlSaveData, false, SwUndoId::REJECT_REDLINE != mnUserId );
+        FillSaveData(rPam, *mpRedlSaveData, SwUndo::DelRange::Ignore,
+                SwUndoId::REJECT_REDLINE != mnUserId);
 
         nEndExtra -= rDoc.GetNodes().GetEndOfExtras().GetIndex();
         nSttNode -= nEndExtra;
@@ -397,7 +399,7 @@ SwUndoCompDoc::SwUndoCompDoc( const SwRangeRedline& rRedl )
     }
 
     pRedlSaveData.reset( new SwRedlineSaveDatas );
-    if( !FillSaveData( rRedl, *pRedlSaveData, false ))
+    if (!FillSaveData( rRedl, *pRedlSaveData, SwUndo::DelRange::Ignore))
     {
         pRedlSaveData.reset();
     }
diff --git a/sw/source/core/undo/unsect.cxx b/sw/source/core/undo/unsect.cxx
index f17cae630316..b225ae42235e 100644
--- a/sw/source/core/undo/unsect.cxx
+++ b/sw/source/core/undo/unsect.cxx
@@ -88,7 +88,7 @@ SwUndoInsSection::SwUndoInsSection(
         SetRedlineFlags( rDoc.getIDocumentRedlineAccess().GetRedlineFlags() );
     }
         m_pRedlineSaveData.reset( new SwRedlineSaveDatas );
-        if( !FillSaveData( rPam, *m_pRedlineSaveData, false ))
+        if (!FillSaveData( rPam, *m_pRedlineSaveData, SwUndo::DelRange::Ignore))
             m_pRedlineSaveData.reset( nullptr );
 
     if( !rPam.HasMark() )
commit cde7961abe8d1ce268292987a2d859c78a1efa8c
Author:     Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Wed Aug 22 12:56:33 2018 +0200
Commit:     Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Wed Aug 22 14:51:43 2018 +0200

    sw_redlinehide_2: SwContentNode::DelFrames()
    
    ... needs to remove extents when it's called when moving nodes to
    Undo-nodes-array.
    
    Change-Id: I32cf38074d9f3d614d5f854979be6b0135d53914

diff --git a/sw/source/core/docnode/node.cxx b/sw/source/core/docnode/node.cxx
index 9175a1b076be..1cfdb934672d 100644
--- a/sw/source/core/docnode/node.cxx
+++ b/sw/source/core/docnode/node.cxx
@@ -1320,7 +1320,7 @@ void SwContentNode::MakeFramesForAdjacentContentNode(SwContentNode& rNode)
  * Deletes all Views from the Doc for this Node.
  * The ContentFrames are removed from the corresponding Layout.
  */
-void SwContentNode::DelFrames(SwRootFrame const*const pLayout, bool const fromDtor)
+void SwContentNode::DelFrames(SwRootFrame const*const pLayout, bool const)
 {
     if( !HasWriterListeners() )
         return;
@@ -1339,24 +1339,27 @@ void SwContentNode::DelFrames(SwRootFrame const*const pLayout, bool const fromDt
             {
                 if (this != pMerged->pFirstNode)
                 {
-                    if (fromDtor)
+                    // pointer should have been updated to a different node
+                    assert(this != pMerged->pParaPropsNode);
+                    // SwNodes::RemoveNode iterates *backwards* - so
+                    // ensure there are no more extents pointing to this
+                    // node as SwFrame::InvalidatePage() will access them.
+                    // Note: cannot send via SwClientNotify from dtor
+                    // because that would access deleted wrong-lists
+                    sw::UpdateMergedParaForDelete(*pMerged, true,
+                            *static_cast<SwTextNode*>(this), 0, Len());
+                    if (this == pMerged->pLastNode)
                     {
-                        // pointer should have been updated to a different node
-                        assert(this != pMerged->pParaPropsNode);
-                        // manual update required i'm afraid...
-                        if (this == pMerged->pLastNode)
-                        {
-                            pMerged->pLastNode = GetNodes()[GetIndex()-1]->GetTextNode();
-                            // at first glance nothing guarantees this...
-                            // but the redline must end on a text-node...
-                            // so everything before this node that isn't a text
-                            // node should have been deleted already so that
-                            // there's a text node before.
-                            assert(pMerged->pLastNode->IsTextNode());
-                        }
-                        // avoid re-parenting mess (ModifyChangedHint)
-                        pMerged->listener.EndListening(this);
+                        pMerged->pLastNode = GetNodes()[GetIndex()-1]->GetTextNode();
+                        // at first glance nothing guarantees this...
+                        // but the redline must end on a text-node...
+                        // so everything before this node that isn't a text
+                        // node should have been deleted already so that
+                        // there's a text node before.
+                        assert(pMerged->pLastNode->IsTextNode());
                     }
+                    // avoid re-parenting mess (ModifyChangedHint)
+                    pMerged->listener.EndListening(this);
                     continue; // don't delete
                 }
             }
diff --git a/sw/source/core/inc/txtfrm.hxx b/sw/source/core/inc/txtfrm.hxx
index ef9f806d5710..7d677b74ab0f 100644
--- a/sw/source/core/inc/txtfrm.hxx
+++ b/sw/source/core/inc/txtfrm.hxx
@@ -102,6 +102,10 @@ std::unique_ptr<sw::MergedPara> CheckParaRedlineMerge(SwTextFrame & rFrame, SwTe
 
 bool FrameContainsNode(SwContentFrame const& rFrame, sal_uLong nNodeIndex);
 
+TextFrameIndex UpdateMergedParaForDelete(MergedPara & rMerged,
+        bool isRealDelete,
+        SwTextNode const& rNode, sal_Int32 nIndex, sal_Int32 nLen);
+
 } // namespace sw
 
 /// Represents the visualization of a paragraph. Typical upper is an
commit d0e4d782b5dab9c01eed16fe96dcc52919d9a3a2
Author:     Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Wed Aug 22 12:52:13 2018 +0200
Commit:     Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Wed Aug 22 12:52:13 2018 +0200

    sw_redlinehide_2: assert calls with wrong start node
    
    Change-Id: I132ea43397b8990c5759db66f62749df8aaa45d5

diff --git a/sw/source/core/text/redlnitr.cxx b/sw/source/core/text/redlnitr.cxx
index cd847938b2a3..3b28a0fbc16b 100644
--- a/sw/source/core/text/redlnitr.cxx
+++ b/sw/source/core/text/redlnitr.cxx
@@ -78,6 +78,7 @@ CheckParaRedlineMerge(SwTextFrame & rFrame, SwTextNode & rTextNode,
         SwPosition const*const pEnd(pRed->End());
         assert(*pStart != *pEnd); // empty delete allowed if shown ???
         bHaveRedlines = true;
+        assert(pNode != &rTextNode || &pStart->nNode.GetNode() == &rTextNode); // detect calls with wrong start node
         if (pStart->nContent != nLastEnd) // not 0 so we eliminate adjacent deletes
         {
             extents.emplace_back(pNode, nLastEnd, pStart->nContent.GetIndex());
commit 0da42642427297a691484bdaa4a6b904b2308324
Author:     Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Wed Aug 22 12:39:54 2018 +0200
Commit:     Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Wed Aug 22 12:42:30 2018 +0200

    sw: add a real create-no-frames flag to MakeCopy/MakeTextNode
    
    SwNodes::CopyNodes calling MakeCopy() and then immediately DelFrames()
    considered silly.
    
    Apparently SwOLENode/SwGrfNode don't actually create frames anyway since
    that is done via their SwFrameFormats, so they just ignore the parameter.
    
    Change-Id: I8a8f52da1d25bb5689345e956a33aebd727e8fc7

diff --git a/sw/inc/ndarr.hxx b/sw/inc/ndarr.hxx
index e9a3a7f11788..598397c43cf6 100644
--- a/sw/inc/ndarr.hxx
+++ b/sw/inc/ndarr.hxx
@@ -204,7 +204,8 @@ public:
 
     /// Implementations of "Make...Node" are in the given .cxx-files.
     SwTextNode *MakeTextNode( const SwNodeIndex & rWhere,
-                            SwTextFormatColl *pColl ); ///< in ndtxt.cxx
+                            SwTextFormatColl *pColl,
+                            bool bNewFrames = true); ///< in ndtxt.cxx
     SwStartNode* MakeTextSection( const SwNodeIndex & rWhere,
                             SwStartNodeType eSttNdTyp,
                             SwTextFormatColl *pColl );
diff --git a/sw/inc/ndgrf.hxx b/sw/inc/ndgrf.hxx
index 74c46f20b238..e822c729c31e 100644
--- a/sw/inc/ndgrf.hxx
+++ b/sw/inc/ndgrf.hxx
@@ -109,7 +109,7 @@ public:
     void SetScaleImageMap( bool b )      { bScaleImageMap = b; }
 
     /// in ndcopy.cxx
-    virtual SwContentNode* MakeCopy( SwDoc*, const SwNodeIndex& ) const override;
+    virtual SwContentNode* MakeCopy(SwDoc*, const SwNodeIndex&, bool bNewFrames) const override;
 
     /** Re-read in case graphic was not OK. The current one
        gets replaced by the new one. */
diff --git a/sw/inc/ndole.hxx b/sw/inc/ndole.hxx
index 93139c986526..21896f6f99c0 100644
--- a/sw/inc/ndole.hxx
+++ b/sw/inc/ndole.hxx
@@ -112,7 +112,7 @@ public:
     virtual ~SwOLENode() override;
 
     /// Is in ndcopy.cxx.
-    virtual SwContentNode* MakeCopy( SwDoc*, const SwNodeIndex& ) const override;
+    virtual SwContentNode* MakeCopy(SwDoc*, const SwNodeIndex&, bool bNewFrames) const override;
 
     virtual Size GetTwipSize() const override;
 
diff --git a/sw/inc/ndtxt.hxx b/sw/inc/ndtxt.hxx
index 82044796a5eb..79d5536088b5 100644
--- a/sw/inc/ndtxt.hxx
+++ b/sw/inc/ndtxt.hxx
@@ -669,7 +669,7 @@ public:
 
     /// in ndcopy.cxx
     bool IsSymbolAt(sal_Int32 nBegin) const; // In itratr.cxx.
-    virtual SwContentNode* MakeCopy( SwDoc*, const SwNodeIndex& ) const override;
+    virtual SwContentNode* MakeCopy(SwDoc*, const SwNodeIndex&, bool bNewFrames) const override;
 
     /// Interactive hyphenation: we find TextFrame and call its CalcHyph.
     bool Hyphenate( SwInterHyphInfo &rHyphInf );
diff --git a/sw/inc/node.hxx b/sw/inc/node.hxx
index ccded8e5eaf5..68d371926f42 100644
--- a/sw/inc/node.hxx
+++ b/sw/inc/node.hxx
@@ -423,7 +423,7 @@ public:
        There are differences between text node and formula node. */
     virtual sal_Int32 Len() const;
 
-    virtual SwContentNode* MakeCopy( SwDoc*, const SwNodeIndex& ) const = 0;
+    virtual SwContentNode* MakeCopy(SwDoc*, const SwNodeIndex&, bool bNewFrames) const = 0;
 
     /// Get information from Client.
     virtual bool GetInfo( SfxPoolItem& ) const override;
diff --git a/sw/source/core/doc/DocumentContentOperationsManager.cxx b/sw/source/core/doc/DocumentContentOperationsManager.cxx
index 58a4fe796c54..f6a2562983cd 100644
--- a/sw/source/core/doc/DocumentContentOperationsManager.cxx
+++ b/sw/source/core/doc/DocumentContentOperationsManager.cxx
@@ -4307,7 +4307,7 @@ bool DocumentContentOperationsManager::CopyImpl( SwPaM& rPam, SwPosition& rPos,
                             pDoc->getIDocumentStylePoolAccess().GetTextCollFromPool(RES_POOLCOLL_STANDARD));
                     else
                     {
-                        pDestTextNd = pSttTextNd->MakeCopy( pDoc, aInsPos )->GetTextNode();
+                        pDestTextNd = pSttTextNd->MakeCopy(pDoc, aInsPos, true)->GetTextNode();
                         bCopyOk = true;
                     }
                     aDestIdx.Assign( pDestTextNd, 0 );
diff --git a/sw/source/core/docnode/ndcopy.cxx b/sw/source/core/docnode/ndcopy.cxx
index 431a91e35055..5ec923298e7e 100644
--- a/sw/source/core/docnode/ndcopy.cxx
+++ b/sw/source/core/docnode/ndcopy.cxx
@@ -52,7 +52,7 @@ struct MapTableFrameFormat
 
 typedef std::vector<MapTableFrameFormat> MapTableFrameFormats;
 
-SwContentNode* SwTextNode::MakeCopy( SwDoc* pDoc, const SwNodeIndex& rIdx ) const
+SwContentNode* SwTextNode::MakeCopy(SwDoc* pDoc, const SwNodeIndex& rIdx, bool const bNewFrames) const
 {
     // the Copy-Textnode is the Node with the Text, the Copy-Attrnode is the
     // node with the collection and hard attributes. Normally is the same
@@ -75,7 +75,7 @@ SwContentNode* SwTextNode::MakeCopy( SwDoc* pDoc, const SwNodeIndex& rIdx ) cons
     if( !pColl )
         pColl = pDoc->CopyTextColl( *GetTextColl() );
 
-    SwTextNode* pTextNd = pDoc->GetNodes().MakeTextNode( rIdx, pColl );
+    SwTextNode* pTextNd = pDoc->GetNodes().MakeTextNode(rIdx, pColl, bNewFrames);
 
     // METADATA: register copy
     pTextNd->RegisterAsCopyOf(*pCpyTextNd);
diff --git a/sw/source/core/docnode/nodes.cxx b/sw/source/core/docnode/nodes.cxx
index 4aa473c4308e..aed8aafbdaeb 100644
--- a/sw/source/core/docnode/nodes.cxx
+++ b/sw/source/core/docnode/nodes.cxx
@@ -1858,11 +1858,8 @@ void SwNodes::CopyNodes( const SwNodeRange& rRange,
         case SwNodeType::Grf:
         case SwNodeType::Ole:
             {
-                SwContentNode* pNew = static_cast<SwContentNode*>(pCurrentNode)->MakeCopy(
-                                            pDoc, aInsPos );
-                // frames are always created as default, so delete if needed
-                if( !bNewFrames )
-                    pNew->DelFrames(nullptr);
+                 static_cast<SwContentNode*>(pCurrentNode)->MakeCopy(
+                                            pDoc, aInsPos, bNewFrames);
             }
             break;
 
diff --git a/sw/source/core/graphic/ndgrf.cxx b/sw/source/core/graphic/ndgrf.cxx
index 0ff3cd1889de..16a3b9e58214 100644
--- a/sw/source/core/graphic/ndgrf.cxx
+++ b/sw/source/core/graphic/ndgrf.cxx
@@ -705,7 +705,7 @@ void SwGrfNode::ScaleImageMap()
     }
 }
 
-SwContentNode* SwGrfNode::MakeCopy( SwDoc* pDoc, const SwNodeIndex& rIdx ) const
+SwContentNode* SwGrfNode::MakeCopy(SwDoc* pDoc, const SwNodeIndex& rIdx, bool) const
 {
     // copy formats into the other document
     SwGrfFormatColl* pColl = pDoc->CopyGrfColl( *GetGrfColl() );
diff --git a/sw/source/core/ole/ndole.cxx b/sw/source/core/ole/ndole.cxx
index 8d59c502817c..924a4db44904 100644
--- a/sw/source/core/ole/ndole.cxx
+++ b/sw/source/core/ole/ndole.cxx
@@ -407,7 +407,7 @@ Size SwOLENode::GetTwipSize() const
     return const_cast<SwOLENode*>(this)->maOLEObj.GetObject().GetSize( &aMapMode );
 }
 
-SwContentNode* SwOLENode::MakeCopy( SwDoc* pDoc, const SwNodeIndex& rIdx ) const
+SwContentNode* SwOLENode::MakeCopy( SwDoc* pDoc, const SwNodeIndex& rIdx, bool) const
 {
     // If there's already a SvPersist instance, we use it
     SfxObjectShell* pPersistShell = pDoc->GetPersist();
diff --git a/sw/source/core/txtnode/ndtxt.cxx b/sw/source/core/txtnode/ndtxt.cxx
index 8313a8498219..22a06fbbc32e 100644
--- a/sw/source/core/txtnode/ndtxt.cxx
+++ b/sw/source/core/txtnode/ndtxt.cxx
@@ -112,7 +112,7 @@ typedef std::vector<SwTextAttr*> SwpHts;
 #endif
 
 SwTextNode *SwNodes::MakeTextNode( const SwNodeIndex & rWhere,
-                                 SwTextFormatColl *pColl )
+                                 SwTextFormatColl *pColl, bool const bNewFrames)
 {
     OSL_ENSURE( pColl, "Collection pointer is 0." );
 
@@ -126,7 +126,8 @@ SwTextNode *SwNodes::MakeTextNode( const SwNodeIndex & rWhere,
 
     // if there is no layout or it is in a hidden section, MakeFrames is not needed
     const SwSectionNode* pSectNd;
-    if( !GetDoc()->getIDocumentLayoutAccess().GetCurrentViewShell() ||
+    if (!bNewFrames ||
+        !GetDoc()->getIDocumentLayoutAccess().GetCurrentViewShell() ||
         ( nullptr != (pSectNd = pNode->FindSectionNode()) &&
             pSectNd->GetSection().IsHiddenFlag() ))
         return pNode;
commit 3726e0012d9d9af83fd00126c8aeb7e66a2f530b
Author:     Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Tue Aug 21 15:42:26 2018 +0200
Commit:     Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Tue Aug 21 15:42:26 2018 +0200

    sw_redlinehide_2: tiny optimisation in SwTextFrame::SwClientNotify()
    
    If there are no items left that affect the frame (which is hard to
    predict for merged frames, nCount only refers to the incoming item set),
    skip calling SwContentFrame::Modify().
    
    Change-Id: I10bdb6420bcff9b89e73b6d57ebb762aa43a0648

diff --git a/sw/source/core/text/txtfrm.cxx b/sw/source/core/text/txtfrm.cxx
index f4c3200d3a1f..c8bdae109b06 100644
--- a/sw/source/core/text/txtfrm.cxx
+++ b/sw/source/core/text/txtfrm.cxx
@@ -2199,7 +2199,10 @@ void SwTextFrame::SwClientNotify(SwModify const& rModify, SfxHint const& rHint)
                         aOldSet.ClearItem( RES_PARATR_SPLIT );
                         aNewSet.ClearItem( RES_PARATR_SPLIT );
                     }
-                    SwContentFrame::Modify( &aOldSet, &aNewSet );
+                    if (aOldSet.Count() || aNewSet.Count())
+                    {
+                        SwContentFrame::Modify( &aOldSet, &aNewSet );
+                    }
                 }
                 else
                     SwContentFrame::Modify( pOld, pNew );
commit bbbb3eb97c8f55db6ed7db48ff630b366b208808
Author:     Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Tue Aug 21 15:37:51 2018 +0200
Commit:     Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Tue Aug 21 15:37:51 2018 +0200

    svl: fix SfxItemIter on empty item set
    
    The problem is that IsAtEnd { return m_nCurrent == m_nEnd; } is never
    true because of the odd initialisation with m_nEnd > m_nStart.
    
    Change-Id: I477b0f111e2c2f47fe093800710a9b28ca8a5925

diff --git a/svl/source/items/itemiter.cxx b/svl/source/items/itemiter.cxx
index 2cc6ae36212d..cbe0f2f8ed03 100644
--- a/svl/source/items/itemiter.cxx
+++ b/svl/source/items/itemiter.cxx
@@ -27,7 +27,7 @@ SfxItemIter::SfxItemIter( const SfxItemSet& rItemSet )
 {
     if (!m_rSet.m_nCount)
     {
-        m_nStart = 1;
+        m_nStart = 0;
         m_nEnd = 0;
     }
     else
commit ef5c193453474eb01c2042d0bb5c4238845a8d08
Author:     Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Mon Aug 20 17:24:18 2018 +0200
Commit:     Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Mon Aug 20 17:24:18 2018 +0200

    sw_redlinehide_2, can have 0-length inserts from redlines
    
    Change-Id: I2f3df32c51af15b1d624e1457cdf7f021a546a09

diff --git a/sw/source/core/text/txtfrm.cxx b/sw/source/core/text/txtfrm.cxx
index 79b5081812f4..f4c3200d3a1f 100644
--- a/sw/source/core/text/txtfrm.cxx
+++ b/sw/source/core/text/txtfrm.cxx
@@ -727,10 +727,14 @@ TextFrameIndex UpdateMergedParaForInsert(MergedPara & rMerged,
         bool const isRealInsert,
         SwTextNode const& rNode, sal_Int32 const nIndex, sal_Int32 const nLen)
 {
-    assert(nLen); // can 0 happen?
+    assert(!isRealInsert || nLen); // can 0 happen? yes, for redline in empty node
     assert(nIndex <= rNode.Len());
     assert(nIndex + nLen <= rNode.Len());
     assert(rMerged.pFirstNode->GetIndex() <= rNode.GetIndex() && rNode.GetIndex() <= rMerged.pLastNode->GetIndex());
+    if (!nLen)
+    {
+        return TextFrameIndex(0);
+    }
     OUStringBuffer text(rMerged.mergedText);
     sal_Int32 nTFIndex(0);
     sal_Int32 nInserted(0);
commit c96135fd15ff3932da1f82db1526ae7c9d13054c
Author:     Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Mon Aug 20 17:21:36 2018 +0200
Commit:     Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Mon Aug 20 17:21:36 2018 +0200

    sw: fix listener registration of sw::UnoCursorPointer
    
    Listening at one SwUnoCursor at a time is enough; this triggers
    asserts added in 1925a57dee73933ffbdb3b57349b757470a8218a from
    SwNavigationMgr.
    
    Change-Id: I791355533214daeb1779cd7d1a6aac7faa1a1472

diff --git a/sw/inc/unocrsr.hxx b/sw/inc/unocrsr.hxx
index fc03253a1109..15468a847743 100644
--- a/sw/inc/unocrsr.hxx
+++ b/sw/inc/unocrsr.hxx
@@ -146,6 +146,10 @@ namespace sw
                 { return *get(); }
             UnoCursorPointer& operator=(UnoCursorPointer aOther)
             {
+                if (m_pCursor)
+                {
+                    EndListening(m_pCursor->m_aNotifier);
+                }
                 if(aOther.m_pCursor)
                     StartListening(aOther.m_pCursor->m_aNotifier);
                 m_pCursor = aOther.m_pCursor;
@@ -157,7 +161,7 @@ namespace sw
             {
                 if(pNew)
                     StartListening(pNew->m_aNotifier);
-                else if(m_pCursor)
+                if (m_pCursor)
                     EndListening(m_pCursor->m_aNotifier);
                 m_pCursor = pNew;
             }


More information about the Libreoffice-commits mailing list