Rebased ref, commits from common ancestor: commit c537d043eb373d03a5f49b71d8552276720c01c5 Author: Michael Stahl <michael.st...@cib.de> AuthorDate: Thu Nov 1 19:27:34 2018 +0100 Commit: Michael Stahl <michael.st...@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.st...@cib.de> AuthorDate: Thu Nov 1 19:25:04 2018 +0100 Commit: Michael Stahl <michael.st...@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.st...@cib.de> AuthorDate: Thu Nov 1 19:23:46 2018 +0100 Commit: Michael Stahl <michael.st...@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.st...@cib.de> AuthorDate: Thu Nov 1 19:23:31 2018 +0100 Commit: Michael Stahl <michael.st...@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.st...@cib.de> AuthorDate: Tue Oct 30 19:12:39 2018 +0100 Commit: Michael Stahl <michael.st...@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 _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits