[Libreoffice-commits] core.git: Branch 'private/mst/sw_redlinehide_3' - 5 commits - sw/inc sw/source

Libreoffice Gerrit user logerrit at kemper.freedesktop.org
Thu Nov 1 18:32:17 UTC 2018


Rebased ref, commits from common ancestor:
commit c537d043eb373d03a5f49b71d8552276720c01c5
Author:     Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Thu Nov 1 19:27:34 2018 +0100
Commit:     Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Thu Nov 1 19:27:34 2018 +0100

    sw_redlinehide_3: SwTextNode::AddToList ignore Undo-array nodes
    
    The node is moved between undo-array and doc-array and each time
    AddToList is called; it doesn't make sense to add a node that is
    currently in undo-array to a list, and it leaks the mpNodeNum
    because IsInList will return false because the SwNodeNum lacks a
    parent, and it triggers some recently added asserts,
    so just don't do that.
    
    Change-Id: I75e51386806ce3845b7c61206020a59c092577fe

diff --git a/sw/source/core/txtnode/ndtxt.cxx b/sw/source/core/txtnode/ndtxt.cxx
index 97c89d2eae06..5cd2a795b2eb 100644
--- a/sw/source/core/txtnode/ndtxt.cxx
+++ b/sw/source/core/txtnode/ndtxt.cxx
@@ -4281,7 +4281,7 @@ void SwTextNode::AddToList()
     }
 
     SwList *const pList(FindList(this));
-    if (pList)
+    if (pList && GetNodes().IsDocNodes()) // not for undo nodes
     {
         assert(!mpNodeNum);
         mpNodeNum = new SwNodeNum(this, false);
commit 4bbbcfd57e10521efd7fd1d2261679d9416ad843
Author:     Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Thu Nov 1 19:25:04 2018 +0100
Commit:     Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Thu Nov 1 19:25:04 2018 +0100

    sw_redlinehide_3: fix SwDoc::MoveParagraph copying of redlined text
    
    If redlining is enabled, the selection is copied and so delete redlines
    become insert redline; better to delete the delete redlines so the
    insert redline consists only of the visible text.
    
    Change-Id: I5f7da96dd957262ccc2b83d0abe6add258b7067f

diff --git a/sw/source/core/doc/docnum.cxx b/sw/source/core/doc/docnum.cxx
index 4ca782e48ec2..260f437affc1 100644
--- a/sw/source/core/doc/docnum.cxx
+++ b/sw/source/core/doc/docnum.cxx
@@ -2144,6 +2144,41 @@ bool SwDoc::MoveParagraphImpl(const SwPaM& rPam, long const nOffset,
             }
 
             getIDocumentContentOperations().CopyRange( aPam, aInsPos, /*bCopyAll=*/false, /*bCheckPos=*/true );
+
+#ifndef NDEBUG
+            size_t nRedlines(getIDocumentRedlineAccess().GetRedlineTable().size());
+#endif
+            if (nOffset > 0)
+                assert(aPam.End()->nNode.GetIndex() - aPam.Start()->nNode.GetIndex() + nOffset == aInsPos.nNode.GetIndex() - aPam.End()->nNode.GetIndex());
+            else
+                assert(aPam.Start()->nNode.GetIndex() - aPam.End()->nNode.GetIndex() + nOffset == aInsPos.nNode.GetIndex() - aPam.End()->nNode.GetIndex());
+            SwRedlineTable::size_type i;
+            getIDocumentRedlineAccess().GetRedline(*aPam.End(), &i);
+            for ( ; 0 < i; --i)
+            {   // iterate backwards to get easy constant index arithmetic
+                SwRangeRedline const*const pRedline = getIDocumentRedlineAccess().GetRedlineTable()[i - 1];
+                if (*pRedline->End() < *aPam.Start())
+                {
+                    break;
+                }
+                if (pRedline->GetType() == nsRedlineType_t::REDLINE_DELETE)
+                {
+                    assert(*aPam.Start() <= *pRedline->Start()); // caller's fault
+                    SwRangeRedline* pNewRedline;
+                    {
+                        SwPaM pam(*pRedline, nullptr);
+                        pam.GetPoint()->nNode += aInsPos.nNode.GetIndex() - aPam.End()->nNode.GetIndex();
+                        pam.GetPoint()->nContent.Assign(pam.GetPoint()->nNode.GetNode().GetContentNode(), pam.GetPoint()->nContent.GetIndex());
+                        pam.GetMark()->nNode += aInsPos.nNode.GetIndex() - aPam.End()->nNode.GetIndex();
+                        pam.GetMark()->nContent.Assign(pam.GetMark()->nNode.GetNode().GetContentNode(), pam.GetMark()->nContent.GetIndex());
+
+                        pNewRedline = new SwRangeRedline( nsRedlineType_t::REDLINE_DELETE, pam );
+                    }
+                    // note: effectively this will DeleteAndJoin the pam!
+                    getIDocumentRedlineAccess().AppendRedline(pNewRedline, true);
+                    assert(nRedlines == getIDocumentRedlineAccess().GetRedlineTable().size());
+                }
+            }
             if( bDelLastPara )
             {
                 // We need to remove the last empty Node again
commit ed4d20ca9480adbd34aaad7d637851a57743ba8e
Author:     Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Thu Nov 1 19:23:46 2018 +0100
Commit:     Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Thu Nov 1 19:23:46 2018 +0100

    avoid SwIndex assert
    
    Change-Id: I29644f2207880582f5712e41318381bbc7f1e043

diff --git a/sw/source/core/doc/docnum.cxx b/sw/source/core/doc/docnum.cxx
index 663e8c8ab08c..4ca782e48ec2 100644
--- a/sw/source/core/doc/docnum.cxx
+++ b/sw/source/core/doc/docnum.cxx
@@ -2204,7 +2204,10 @@ bool SwDoc::MoveParagraphImpl(const SwPaM& rPam, long const nOffset,
             aPam.GetBound(false).nContent.Assign( nullptr, 0 );
 
             getIDocumentRedlineAccess().AppendRedline( pNewRedline, true );
-            sw::UpdateFramesForAddDeleteRedline(*this, *pNewRedline);
+
+            aPam.GetBound().nContent.Assign(aPam.GetBound().nNode.GetNode().GetContentNode(), 0);
+            aPam.GetBound(false).nContent.Assign(aPam.GetBound(false).nNode.GetNode().GetContentNode(), 0);
+            sw::UpdateFramesForAddDeleteRedline(*this, aPam);
 
             // Still NEEDS to be optimized!
             getIDocumentRedlineAccess().SetRedlineFlags( eOld );
commit 5c05f0163c58d4b825e59d8ca883f0ccff13f089
Author:     Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Thu Nov 1 19:23:31 2018 +0100
Commit:     Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Thu Nov 1 19:23:31 2018 +0100

    avoid assert
    
    Change-Id: I064da9697f03143752a89149e921158f72a28e70

diff --git a/sw/source/core/doc/docnum.cxx b/sw/source/core/doc/docnum.cxx
index fa4b936c60b9..663e8c8ab08c 100644
--- a/sw/source/core/doc/docnum.cxx
+++ b/sw/source/core/doc/docnum.cxx
@@ -2114,6 +2114,7 @@ bool SwDoc::MoveParagraphImpl(const SwPaM& rPam, long const nOffset,
             SwPaM& rOrigPam = const_cast<SwPaM&>(rPam);
             rOrigPam.DeleteMark();
             rOrigPam.GetPoint()->nNode = aIdx.GetIndex() - 1;
+            rOrigPam.GetPoint()->nContent.Assign( rOrigPam.GetContentNode(), 0 );
 
             bool bDelLastPara = !aInsPos.nNode.GetNode().IsContentNode();
 
commit 2299e2e1224690ddc6fb411186dacc6fba08a49c
Author:     Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Tue Oct 30 19:12:39 2018 +0100
Commit:     Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Thu Nov 1 19:23:16 2018 +0100

    sw_redlinehide_3: SwDoc::MoveParagraph()
    
    Change-Id: Ic4157d14c2a3ee7c90f103561a376ac6f753a694

diff --git a/sw/inc/doc.hxx b/sw/inc/doc.hxx
index c4842f8af649..42b6b8869156 100644
--- a/sw/inc/doc.hxx
+++ b/sw/inc/doc.hxx
@@ -1118,6 +1118,7 @@ public:
     /** Move selected paragraphes (not only numberings)
      according to offsets. (if negative: go to doc start). */
     bool MoveParagraph( const SwPaM&, long nOffset, bool bIsOutlMv = false );
+    bool MoveParagraphImpl(const SwPaM&, long nOffset, bool bIsOutlMv, SwRootFrame const*);
 
     bool NumOrNoNum( const SwNodeIndex& rIdx, bool bDel = false);
 
diff --git a/sw/source/core/doc/docnum.cxx b/sw/source/core/doc/docnum.cxx
index c0f52537baa3..fa4b936c60b9 100644
--- a/sw/source/core/doc/docnum.cxx
+++ b/sw/source/core/doc/docnum.cxx
@@ -29,6 +29,7 @@
 #include <IDocumentState.hxx>
 #include <IDocumentStylePoolAccess.hxx>
 #include <pam.hxx>
+#include <unocrsr.hxx>
 #include <ndtxt.hxx>
 #include <doctxm.hxx>
 #include <poolfmt.hxx>
@@ -1792,7 +1793,123 @@ bool SwDoc::NumUpDown(const SwPaM& rPam, bool bDown, SwRootFrame const*const pLa
     return bRet;
 }
 
-bool SwDoc::MoveParagraph( const SwPaM& rPam, long nOffset, bool bIsOutlMv )
+// this function doesn't contain any numbering-related code, but it is
+// primarily called to move numbering-relevant paragraphs around, hence
+// it will expand its selection to include full SwTextFrames.
+bool SwDoc::MoveParagraph(const SwPaM& rPam, long nOffset, bool const bIsOutlMv)
+{
+    std::shared_ptr<SwUnoCursor> const pCursor(CreateUnoCursor(*rPam.GetMark()));
+    if (rPam.HasMark())
+    {
+        pCursor->SetMark();
+        *pCursor->GetPoint() = *rPam.GetPoint();
+    }
+    // sw_redlinehide: as long as a layout with Hide mode exists, only
+    // move nodes that have merged frames *completely*
+    SwRootFrame const* pLayout(nullptr);
+    for (SwRootFrame const*const pLay : GetAllLayouts())
+    {
+        if (pLay->IsHideRedlines())
+        {
+            pLayout = pLay;
+        }
+    }
+    if (pLayout)
+    {
+        std::pair<SwTextNode *, SwTextNode *> nodes(
+            sw::GetFirstAndLastNode(*pLayout, rPam.Start()->nNode));
+        if (nodes.first && nodes.first != &pCursor->Start()->nNode.GetNode())
+        {
+            assert(nodes.second);
+#if 0
+// correct inwards (if anything)
+// inwards if its' not a default-1-or--1 ? how to detect that?
+            if (nOffset < 0)
+            {
+                nOffset -= pCursor->Start()->nNode.GetIndex() - nodes.first->GetIndex();
+            }
+#endif
+            if (!pCursor->HasMark())
+            {
+                pCursor->SetMark();
+            }
+            assert(nodes.first->GetIndex() < pCursor->Start()->nNode.GetIndex());
+            pCursor->Start()->nNode = *nodes.first;
+            pCursor->Start()->nContent.Assign(nodes.first, 0);
+        }
+        nodes = sw::GetFirstAndLastNode(*pLayout, rPam.End()->nNode);
+        if (nodes.second && nodes.second != &pCursor->End()->nNode.GetNode())
+        {
+            assert(nodes.first);
+#if 0
+            if (nOffset > 0)
+            {
+                nOffset += nodes.second->GetIndex() - pCursor->End()->nNode.GetIndex();
+            }
+#endif
+            if (!pCursor->HasMark())
+            {
+                pCursor->SetMark();
+            }
+            assert(pCursor->End()->nNode.GetIndex() < nodes.second->GetIndex());
+            pCursor->End()->nNode = *nodes.second;
+            pCursor->End()->nContent.Assign(nodes.second, 0);
+        }
+
+        if (nOffset > 0)
+        {   // sw_redlinehide: avoid moving into delete redline, skip forward
+            if (GetNodes().GetEndOfContent().GetIndex() <= pCursor->End()->nNode.GetIndex() + nOffset)
+            {
+                return false; // can't move
+            }
+            SwNode const* pNode(GetNodes()[pCursor->End()->nNode.GetIndex() + nOffset + 1]);
+            if (   pNode->GetRedlineMergeFlag() != SwNode::Merge::None
+                && pNode->GetRedlineMergeFlag() != SwNode::Merge::First)
+            {
+                for ( ; ; ++nOffset)
+                {
+                    pNode = GetNodes()[pCursor->End()->nNode.GetIndex() + nOffset];
+                    if (pNode->IsTextNode())
+                    {
+                        nodes = GetFirstAndLastNode(*pLayout, *pNode->GetTextNode());
+                        assert(nodes.first && nodes.second);
+                        nOffset += nodes.second->GetIndex() - pNode->GetIndex();
+                        // on last; will be incremented below to behind-last
+                        break;
+                    }
+                }
+            }
+        }
+        else
+        {   // sw_redlinehide: avoid moving into delete redline, skip backward
+            if (pCursor->Start()->nNode.GetIndex() + nOffset < 1)
+            {
+                return false; // can't move
+            }
+            SwNode const* pNode(GetNodes()[pCursor->Start()->nNode.GetIndex() + nOffset]);
+            if (   pNode->GetRedlineMergeFlag() != SwNode::Merge::None
+                && pNode->GetRedlineMergeFlag() != SwNode::Merge::First)
+            {
+                for ( ; ; --nOffset)
+                {
+                    pNode = GetNodes()[pCursor->Start()->nNode.GetIndex() + nOffset];
+                    if (pNode->IsTextNode())
+                    {
+                        nodes = GetFirstAndLastNode(*pLayout, *pNode->GetTextNode());
+                        assert(nodes.first && nodes.second);
+                        nOffset -= pNode->GetIndex() - nodes.first->GetIndex();
+                        // on first
+                        break;
+                    }
+                }
+            }
+        }
+    }
+    return MoveParagraphImpl(*pCursor, nOffset, bIsOutlMv, pLayout);
+}
+
+bool SwDoc::MoveParagraphImpl(const SwPaM& rPam, long const nOffset,
+        bool const bIsOutlMv, SwRootFrame const*const pLayout)
 {
     const SwPosition *pStt = rPam.Start(), *pEnd = rPam.End();
 
@@ -2119,6 +2236,10 @@ bool SwDoc::MoveParagraph( const SwPaM& rPam, long nOffset, bool bIsOutlMv )
         nMoved = rPam.End()->nNode.GetIndex() - rPam.Start()->nNode.GetIndex() + 1;
     }
 
+    (void) pLayout; // note: move will insert between aIdx-1 and aIdx
+    assert(!pLayout // check not moving *into* delete redline (caller's fault)
+        || aIdx.GetNode().GetRedlineMergeFlag() == SwNode::Merge::None
+        || aIdx.GetNode().GetRedlineMergeFlag() == SwNode::Merge::First);
     getIDocumentContentOperations().MoveNodeRange( aMvRg, aIdx, SwMoveFlags::REDLINES );
 
     if( pUndo )
diff --git a/sw/source/core/edit/ednumber.cxx b/sw/source/core/edit/ednumber.cxx
index cf14f279b2e9..77e2f74eba27 100644
--- a/sw/source/core/edit/ednumber.cxx
+++ b/sw/source/core/edit/ednumber.cxx
@@ -460,6 +460,13 @@ bool SwEditShell::MoveNumParas( bool bUpperLower, bool bUpperLeft )
                 else
                 {
                     sal_uLong nStt = aPos.nNode.GetIndex(), nIdx = nStt - 1;
+
+                    if (SwTextNode const*const pStt = aPos.nNode.GetNode().GetTextNode())
+                    {
+                        std::pair<SwTextNode *, SwTextNode *> nodes(
+                            sw::GetFirstAndLastNode(*GetLayout(), *pStt));
+                        nIdx = nodes.first->GetIndex() - 1;
+                    }
                     while( nIdx && (
                         ( pNd = GetDoc()->GetNodes()[ nIdx ])->IsSectionNode() ||
                         ( pNd->IsEndNode() && pNd->StartOfSectionNode()->IsSectionNode())))
@@ -477,18 +484,38 @@ bool SwEditShell::MoveNumParas( bool bUpperLower, bool bUpperLeft )
                     pOrig == aCursor.GetNode().GetTextNode()->GetNumRule() )
                 {
                     sal_uLong nStt = aCursor.GetPoint()->nNode.GetIndex(), nIdx = nStt+1;
+                    if (SwTextNode const*const pStt = aCursor.GetPoint()->nNode.GetNode().GetTextNode())
+                    {
+                        std::pair<SwTextNode *, SwTextNode *> nodes(
+                            sw::GetFirstAndLastNode(*GetLayout(), *pStt));
+                        nIdx = nodes.second->GetIndex() + 1;
+                    }
 
                     while (nIdx < GetDoc()->GetNodes().Count()-1)
                     {
                         pNd = GetDoc()->GetNodes()[ nIdx ];
 
                         if (pNd->IsSectionNode() ||
-                            ( pNd->IsEndNode() && pNd->StartOfSectionNode()->IsSectionNode()) ||
-                            ( pNd->IsTextNode() && pOrig == static_cast<const SwTextNode*>(pNd)->GetNumRule() &&
-                              static_cast<const SwTextNode*>(pNd)->GetActualListLevel() > nUpperLevel ))
+                            (pNd->IsEndNode() && pNd->StartOfSectionNode()->IsSectionNode()))
                         {
                             ++nIdx;
                         }
+                        else if (pNd->IsTextNode())
+                        {
+                            SwTextNode const*const pTextNode =
+                                sw::GetParaPropsNode(*GetLayout(), SwNodeIndex(*pNd));
+                            if (pOrig == pTextNode->GetNumRule()
+                                && pTextNode->GetActualListLevel() > nUpperLevel)
+                            {
+                                std::pair<SwTextNode *, SwTextNode *> nodes(
+                                    sw::GetFirstAndLastNode(*GetLayout(), *pTextNode));
+                                nIdx = nodes.second->GetIndex() + 1;
+                            }
+                            else
+                            {
+                                break;
+                            }
+                        }
                         // #i57856#
                         else
                         {
diff --git a/sw/source/core/inc/txtfrm.hxx b/sw/source/core/inc/txtfrm.hxx
index d74f5d4dd2d0..6870d721e5a0 100644
--- a/sw/source/core/inc/txtfrm.hxx
+++ b/sw/source/core/inc/txtfrm.hxx
@@ -103,6 +103,8 @@ bool FrameContainsNode(SwContentFrame const& rFrame, sal_uLong nNodeIndex);
 bool IsParaPropsNode(SwRootFrame const& rLayout, SwTextNode const& rNode);
 SwTextNode * GetParaPropsNode(SwRootFrame const& rLayout, SwNodeIndex const& rNode);
 SwPosition GetParaPropsPos(SwRootFrame const& rLayout, SwPosition const& rPos);
+std::pair<SwTextNode *, SwTextNode *>
+GetFirstAndLastNode(SwRootFrame const& rLayout, SwNodeIndex const& rPos);
 
 TextFrameIndex UpdateMergedParaForDelete(MergedPara & rMerged,
         bool isRealDelete,
diff --git a/sw/source/core/text/txtfrm.cxx b/sw/source/core/text/txtfrm.cxx
index 24d6b5fdb347..07e7b3cfaac0 100644
--- a/sw/source/core/text/txtfrm.cxx
+++ b/sw/source/core/text/txtfrm.cxx
@@ -354,6 +354,23 @@ namespace sw {
         return pos;
     }
 
+    std::pair<SwTextNode *, SwTextNode *>
+    GetFirstAndLastNode(SwRootFrame const& rLayout, SwNodeIndex const& rPos)
+    {
+        SwTextNode *const pTextNode(rPos.GetNode().GetTextNode());
+        if (pTextNode && rLayout.IsHideRedlines())
+        {
+            if (SwTextFrame const*const pFrame = static_cast<SwTextFrame*>(pTextNode->getLayoutFrame(&rLayout)))
+            {
+                if (sw::MergedPara const*const pMerged = pFrame->GetMergedPara())
+                {
+                    return std::make_pair(pMerged->pFirstNode, const_cast<SwTextNode*>(pMerged->pLastNode));
+                }
+            }
+        }
+        return std::make_pair(pTextNode, pTextNode);
+    }
+
 } // namespace sw
 
 /// Switches width and height of the text frame


More information about the Libreoffice-commits mailing list