sw/inc/hints.hxx | 13 + sw/source/core/attr/hints.cxx | 5 sw/source/core/doc/DocumentContentOperationsManager.cxx | 151 ++++++++-------- sw/source/core/doc/DocumentRedlineManager.cxx | 73 +++++++ sw/source/core/inc/txtfrm.hxx | 3 sw/source/core/text/txtfrm.cxx | 95 +++++++++- sw/source/core/txtnode/ndtxt.cxx | 2 sw/source/core/undo/unredln.cxx | 13 + 8 files changed, 283 insertions(+), 72 deletions(-)
New commits: commit 62a030a71f267b65ca7b188cf97df21bd71d17bd Author: Michael Stahl <[email protected]> AuthorDate: Mon Sep 3 18:07:29 2018 +0200 Commit: Michael Stahl <[email protected]> CommitDate: Mon Sep 3 18:12:15 2018 +0200 sw_redlinehide_2: update frames on Redline ops When Delete redline is created, removed, accepted, rejected & undo/redo of all of these, update all the text frames so they're merged or not, as required. Change-Id: I08aa6aea270a50d19f4bda0caf016870a42a8dd3 diff --git a/sw/source/core/doc/DocumentContentOperationsManager.cxx b/sw/source/core/doc/DocumentContentOperationsManager.cxx index 11af40aaa469..1bb52e00e186 100644 --- a/sw/source/core/doc/DocumentContentOperationsManager.cxx +++ b/sw/source/core/doc/DocumentContentOperationsManager.cxx @@ -44,6 +44,7 @@ #include <fmtcnct.hxx> #include <SwStyleNameMapper.hxx> #include <redline.hxx> +#include <txtfrm.hxx> #include <unocrsr.hxx> #include <mvsave.hxx> #include <ndtxt.hxx> @@ -3619,6 +3620,11 @@ bool DocumentContentOperationsManager::DeleteAndJoinWithRedlineImpl( SwPaM & rPa m_rDoc.getIDocumentRedlineAccess().AppendRedline( new SwRangeRedline( nsRedlineType_t::REDLINE_DELETE, rPam ), true ); m_rDoc.getIDocumentState().SetModified(); + // sw_redlinehide: 2 reasons why this is needed: + // 1. it's the first redline in node => RedlineDelText was sent but ignored + // 2. redline spans multiple nodes => must merge text frames + sw::UpdateFramesForAddDeleteRedline(rPam); + if (pUndo) { m_rDoc.GetIDocumentUndoRedo().EndUndo( SwUndoId::EMPTY, nullptr ); diff --git a/sw/source/core/doc/DocumentRedlineManager.cxx b/sw/source/core/doc/DocumentRedlineManager.cxx index ad9c292810a1..4088a497f989 100644 --- a/sw/source/core/doc/DocumentRedlineManager.cxx +++ b/sw/source/core/doc/DocumentRedlineManager.cxx @@ -19,6 +19,7 @@ #include <DocumentRedlineManager.hxx> #include <frmfmt.hxx> #include <rootfrm.hxx> +#include <txtfrm.hxx> #include <doc.hxx> #include <IDocumentUndoRedo.hxx> #include <IDocumentState.hxx> @@ -113,6 +114,72 @@ using namespace com::sun::star; #endif +namespace sw { + +void UpdateFramesForAddDeleteRedline(SwPaM const& rPam) +{ + if (rPam.GetPoint()->nNode != rPam.GetMark()->nNode) + { + SwTextNode *const pStartNode(rPam.Start()->nNode.GetNode().GetTextNode()); + 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) + { + SwTextNode & rFirstNode(pFrame->GetMergedPara() + ? *pFrame->GetMergedPara()->pFirstNode + : *pStartNode); + assert(rFirstNode.GetIndex() <= pStartNode->GetIndex()); + pFrame->SetMergedPara(sw::CheckParaRedlineMerge( + *pFrame, rFirstNode, sw::FrameMode::Existing)); + } + } +} + +void UpdateFramesForRemoveDeleteRedline(SwDoc & rDoc, SwPaM const& rPam) +{ + if (rPam.GetPoint()->nNode != rPam.GetMark()->nNode) + { + // first, call CheckParaRedlineMerge on the first paragraph, + // to init flag on new merge range (if any) + 1st node post the merge + SwTextNode *const pStartNode(rPam.Start()->nNode.GetNode().GetTextNode()); + 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) + { + if (auto const pMergedPara = pFrame->GetMergedPara()) + { + assert(pMergedPara->pFirstNode->GetIndex() <= pStartNode->GetIndex()); + pFrame->SetMergedPara(sw::CheckParaRedlineMerge( + *pFrame, *pMergedPara->pFirstNode, sw::FrameMode::Existing)); + } + } + // now start node until end of merge + 1 has proper flags; MakeFrames + // should pick up from the next node in need of frames by checking flags + if (!frames.empty()) + { + SwNodeIndex const start(*pStartNode, +1); + SwNodeIndex const end(rPam.End()->nNode, +1); // end is exclusive + ::MakeFrames(&rDoc, start, end); + } + } +} + +} // namespace sw + namespace { inline bool IsPrevPos( const SwPosition & rPos1, const SwPosition & rPos2 ) @@ -294,6 +361,7 @@ namespace { bool bRet = true; SwRangeRedline* pRedl = rArr[ rPos ]; + SwDoc& rDoc = *pRedl->GetDoc(); SwPosition *pRStt = nullptr, *pREnd = nullptr; SwComparePosition eCmp = SwComparePosition::Outside; if( pSttRng && pEndRng ) @@ -309,7 +377,6 @@ namespace { case nsRedlineType_t::REDLINE_INSERT: { - SwDoc& rDoc = *pRedl->GetDoc(); const SwPosition *pDelStt = nullptr, *pDelEnd = nullptr; bool bDelRedl = false; switch( eCmp ) @@ -390,6 +457,8 @@ namespace { SwRangeRedline* pNew = nullptr; bool bCheck = false, bReplace = false; + SwPaM const updatePaM(pSttRng ? *pSttRng : *pRedl->Start(), + pEndRng ? *pEndRng : *pRedl->End()); switch( eCmp ) { @@ -473,6 +542,8 @@ namespace rArr.Remove( pRedl ); rArr.Insert( pRedl ); } + + sw::UpdateFramesForRemoveDeleteRedline(rDoc, updatePaM); } break; diff --git a/sw/source/core/inc/txtfrm.hxx b/sw/source/core/inc/txtfrm.hxx index 10bde328c903..a52bf0f14fa0 100644 --- a/sw/source/core/inc/txtfrm.hxx +++ b/sw/source/core/inc/txtfrm.hxx @@ -108,6 +108,9 @@ TextFrameIndex UpdateMergedParaForDelete(MergedPara & rMerged, void MoveDeletedPrevFrames(SwTextNode & rDeletedPrev, SwTextNode & rNode); void CheckResetRedlineMergeFlag(SwTextNode & rNode, bool bRecreateMerged); +void UpdateFramesForAddDeleteRedline(SwPaM const& rPam); +void UpdateFramesForRemoveDeleteRedline(SwDoc & rDoc, SwPaM const& rPam); + } // namespace sw /// Represents the visualization of a paragraph. Typical upper is an diff --git a/sw/source/core/undo/unredln.cxx b/sw/source/core/undo/unredln.cxx index 58d2de808363..fb1d30f9f953 100644 --- a/sw/source/core/undo/unredln.cxx +++ b/sw/source/core/undo/unredln.cxx @@ -25,6 +25,7 @@ #include <swundo.hxx> #include <pam.hxx> #include <ndtxt.hxx> +#include <txtfrm.hxx> #include <UndoCore.hxx> #include <UndoDelete.hxx> #include <strings.hrc> @@ -106,6 +107,17 @@ void SwUndoRedline::UndoImpl(::sw::UndoRedoContext & rContext) } SetPaM(rPam, true); } + + // update frames after calling SetSaveData + if (dynamic_cast<SwUndoRedlineDelete*>(this)) + { + sw::UpdateFramesForRemoveDeleteRedline(rDoc, rPam); + } + else if (dynamic_cast<SwUndoAcceptRedline*>(this) + || dynamic_cast<SwUndoRejectRedline*>(this)) + { // (can't check here if there's a delete redline being accepted) + sw::UpdateFramesForAddDeleteRedline(rPam); + } } void SwUndoRedline::RedoImpl(::sw::UndoRedoContext & rContext) @@ -191,6 +203,7 @@ void SwUndoRedlineDelete::RedoRedlineImpl(SwDoc & rDoc, SwPaM & rPam) { rDoc.getIDocumentRedlineAccess().AppendRedline( new SwRangeRedline(*mpRedlData, rPam), false ); } + sw::UpdateFramesForAddDeleteRedline(rPam); } bool SwUndoRedlineDelete::CanGrouping( const SwUndoRedlineDelete& rNext ) commit 9c47d5d4ad9e442edc5d459cfa0b442d930f188a Author: Michael Stahl <[email protected]> AuthorDate: Mon Sep 3 17:20:37 2018 +0200 Commit: Michael Stahl <[email protected]> CommitDate: Mon Sep 3 17:20:37 2018 +0200 incorrect call to lcl_SetWrong - must not move indexes for redline ops Change-Id: I965c60dad691128125ef9cdacdb388b30c9d52f3 diff --git a/sw/source/core/text/txtfrm.cxx b/sw/source/core/text/txtfrm.cxx index 9c1a6a0f0f55..58f28195010e 100644 --- a/sw/source/core/text/txtfrm.cxx +++ b/sw/source/core/text/txtfrm.cxx @@ -1838,7 +1838,7 @@ void SwTextFrame::SwClientNotify(SwModify const& rModify, SfxHint const& rHint) { InvalidateRange( SwCharRange(nPos, TextFrameIndex(1)), m ); } - lcl_SetWrong( *this, rNode, nNPos, m, true ); + lcl_SetWrong( *this, rNode, nNPos, m, false ); if (nLen) { lcl_SetScriptInval( *this, nPos ); @@ -1869,7 +1869,7 @@ void SwTextFrame::SwClientNotify(SwModify const& rModify, SfxHint const& rHint) else InvalidateRange_( SwCharRange( nPos, nLen ), nNLen ); } - lcl_SetWrong( *this, rNode, nNPos, nNLen, true ); + lcl_SetWrong( *this, rNode, nNPos, nNLen, false ); lcl_SetScriptInval( *this, nPos ); bSetFieldsDirty = true; if (HasFollow()) commit 488cddbc8c9b09f4243e91263d857efea30ddde7 Author: Michael Stahl <[email protected]> AuthorDate: Mon Sep 3 15:12:29 2018 +0200 Commit: Michael Stahl <[email protected]> CommitDate: Mon Sep 3 15:19:17 2018 +0200 sw_redlinehide_2: remove a pointless level of indentation Change-Id: I82893951b6e227ab1ed6423e08a0370561482cd8 diff --git a/sw/source/core/doc/DocumentContentOperationsManager.cxx b/sw/source/core/doc/DocumentContentOperationsManager.cxx index d9b9250d617a..11af40aaa469 100644 --- a/sw/source/core/doc/DocumentContentOperationsManager.cxx +++ b/sw/source/core/doc/DocumentContentOperationsManager.cxx @@ -3563,92 +3563,89 @@ DocumentContentOperationsManager::~DocumentContentOperationsManager() bool DocumentContentOperationsManager::DeleteAndJoinWithRedlineImpl( SwPaM & rPam, const bool ) { - OSL_ENSURE( m_rDoc.getIDocumentRedlineAccess().IsRedlineOn(), "DeleteAndJoinWithRedline: redline off" ); + assert(m_rDoc.getIDocumentRedlineAccess().IsRedlineOn()); - { - SwUndoRedlineDelete* pUndo = nullptr; - RedlineFlags eOld = m_rDoc.getIDocumentRedlineAccess().GetRedlineFlags(); - m_rDoc.GetDocumentRedlineManager().checkRedlining( eOld ); + SwUndoRedlineDelete* pUndo = nullptr; + RedlineFlags eOld = m_rDoc.getIDocumentRedlineAccess().GetRedlineFlags(); + m_rDoc.GetDocumentRedlineManager().checkRedlining( eOld ); - auto & rDMA(*m_rDoc.getIDocumentMarkAccess()); - std::vector<std::unique_ptr<SwUndo>> MarkUndos; - for (auto iter = rDMA.getAnnotationMarksBegin(); - iter != rDMA.getAnnotationMarksEnd(); ) + auto & rDMA(*m_rDoc.getIDocumentMarkAccess()); + std::vector<std::unique_ptr<SwUndo>> MarkUndos; + for (auto iter = rDMA.getAnnotationMarksBegin(); + iter != rDMA.getAnnotationMarksEnd(); ) + { + // tdf#111524 remove annotation marks that have their field + // characters deleted + SwPosition const& rEndPos((**iter).GetMarkEnd()); + if (*rPam.Start() < rEndPos && rEndPos <= *rPam.End()) { - // tdf#111524 remove annotation marks that have their field - // characters deleted - SwPosition const& rEndPos((**iter).GetMarkEnd()); - if (*rPam.Start() < rEndPos && rEndPos <= *rPam.End()) + if (m_rDoc.GetIDocumentUndoRedo().DoesUndo()) { - if (m_rDoc.GetIDocumentUndoRedo().DoesUndo()) - { - MarkUndos.emplace_back(o3tl::make_unique<SwUndoDeleteBookmark>(**iter)); - } - // iter is into annotation mark vector so must be dereferenced! - rDMA.deleteMark(&**iter); - // this invalidates iter, have to start over... - iter = rDMA.getAnnotationMarksBegin(); + MarkUndos.emplace_back(o3tl::make_unique<SwUndoDeleteBookmark>(**iter)); } - else - { // marks are sorted by start - if (*rPam.End() < (**iter).GetMarkStart()) - { - break; - } - ++iter; + // iter is into annotation mark vector so must be dereferenced! + rDMA.deleteMark(&**iter); + // this invalidates iter, have to start over... + iter = rDMA.getAnnotationMarksBegin(); + } + else + { // marks are sorted by start + if (*rPam.End() < (**iter).GetMarkStart()) + { + break; } + ++iter; } + } - if (m_rDoc.GetIDocumentUndoRedo().DoesUndo()) + if (m_rDoc.GetIDocumentUndoRedo().DoesUndo()) + { + /* please don't translate -- for cultural reasons this comment is protected + until the redline implementation is finally fixed some day */ + //JP 06.01.98: MUSS noch optimiert werden!!! + m_rDoc.getIDocumentRedlineAccess().SetRedlineFlags( + RedlineFlags::On | RedlineFlags::ShowInsert | RedlineFlags::ShowDelete); + pUndo = new SwUndoRedlineDelete( rPam, SwUndoId::DELETE ); + const SwRewriter aRewriter = pUndo->GetRewriter(); + m_rDoc.GetIDocumentUndoRedo().StartUndo( SwUndoId::DELETE, &aRewriter ); + for (auto& it : MarkUndos) { - - /* please don't translate -- for cultural reasons this comment is protected - until the redline implementation is finally fixed some day */ - //JP 06.01.98: MUSS noch optimiert werden!!! - m_rDoc.getIDocumentRedlineAccess().SetRedlineFlags( - RedlineFlags::On | RedlineFlags::ShowInsert | RedlineFlags::ShowDelete ); - pUndo = new SwUndoRedlineDelete( rPam, SwUndoId::DELETE ); - const SwRewriter aRewriter = pUndo->GetRewriter(); - m_rDoc.GetIDocumentUndoRedo().StartUndo( SwUndoId::DELETE, &aRewriter ); - for (auto& it : MarkUndos) - { - m_rDoc.GetIDocumentUndoRedo().AppendUndo(it.release()); - } - m_rDoc.GetIDocumentUndoRedo().AppendUndo( pUndo ); + m_rDoc.GetIDocumentUndoRedo().AppendUndo(it.release()); } + m_rDoc.GetIDocumentUndoRedo().AppendUndo( pUndo ); + } - if ( *rPam.GetPoint() != *rPam.GetMark() ) - m_rDoc.getIDocumentRedlineAccess().AppendRedline( new SwRangeRedline( nsRedlineType_t::REDLINE_DELETE, rPam ), true ); - m_rDoc.getIDocumentState().SetModified(); + if (*rPam.GetPoint() != *rPam.GetMark()) + m_rDoc.getIDocumentRedlineAccess().AppendRedline( new SwRangeRedline( nsRedlineType_t::REDLINE_DELETE, rPam ), true ); + m_rDoc.getIDocumentState().SetModified(); - if ( pUndo ) + if (pUndo) + { + m_rDoc.GetIDocumentUndoRedo().EndUndo( SwUndoId::EMPTY, nullptr ); + // ??? why the hell is the AppendUndo not below the + // CanGrouping, so this hideous cleanup wouldn't be necessary? + // bah, this is redlining, probably changing this would break it... + if (m_rDoc.GetIDocumentUndoRedo().DoesGroupUndo()) { - m_rDoc.GetIDocumentUndoRedo().EndUndo( SwUndoId::EMPTY, nullptr ); - // ??? why the hell is the AppendUndo not below the - // CanGrouping, so this hideous cleanup wouldn't be necessary? - // bah, this is redlining, probably changing this would break it... - if ( m_rDoc.GetIDocumentUndoRedo().DoesGroupUndo() ) + SwUndo * const pLastUndo( m_rDoc.GetUndoManager().GetLastUndo() ); + SwUndoRedlineDelete *const pUndoRedlineDel( dynamic_cast<SwUndoRedlineDelete*>(pLastUndo) ); + if (pUndoRedlineDel) { - SwUndo * const pLastUndo( m_rDoc.GetUndoManager().GetLastUndo() ); - SwUndoRedlineDelete * const pUndoRedlineDel( dynamic_cast< SwUndoRedlineDelete* >( pLastUndo ) ); - if ( pUndoRedlineDel ) + bool const bMerged = pUndoRedlineDel->CanGrouping( *pUndo ); + if (bMerged) { - bool const bMerged = pUndoRedlineDel->CanGrouping( *pUndo ); - if ( bMerged ) - { - ::sw::UndoGuard const undoGuard( m_rDoc.GetIDocumentUndoRedo() ); - SwUndo const* const pDeleted = m_rDoc.GetUndoManager().RemoveLastUndo(); - OSL_ENSURE( pDeleted == pUndo, "DeleteAndJoinWithRedlineImpl: " - "undo removed is not undo inserted?" ); - delete pDeleted; - } + ::sw::UndoGuard const undoGuard( m_rDoc.GetIDocumentUndoRedo() ); + SwUndo const*const pDeleted = m_rDoc.GetUndoManager().RemoveLastUndo(); + OSL_ENSURE( pDeleted == pUndo, "DeleteAndJoinWithRedlineImpl: " + "undo removed is not undo inserted?" ); + delete pDeleted; } } - //JP 06.01.98: MUSS noch optimiert werden!!! - m_rDoc.getIDocumentRedlineAccess().SetRedlineFlags( eOld ); } - return true; + //JP 06.01.98: MUSS noch optimiert werden!!! + m_rDoc.getIDocumentRedlineAccess().SetRedlineFlags( eOld ); } + return true; } bool DocumentContentOperationsManager::DeleteAndJoinImpl( SwPaM & rPam, commit 582ca30a29c5b2b7df2b5ae9826f071119a5b2aa Author: Michael Stahl <[email protected]> AuthorDate: Mon Sep 3 12:18:25 2018 +0200 Commit: Michael Stahl <[email protected]> CommitDate: Mon Sep 3 14:49:05 2018 +0200 sw_redlinehide_2: handle delete-without-redline inside of redline The problem is that the SwInsText/SwDelText do not transfer the "deleted-ness" of the text from one node to the other in the SwTextFrame, so add a new hint that is sent after SwInsText & before SwDelText to move the info that is in the extents vector. Change-Id: I32d8dbe52a18556d8dc2c50a47246a6600fdb355 diff --git a/sw/inc/hints.hxx b/sw/inc/hints.hxx index bee0ebb1c21a..bdf2eceaa8a6 100644 --- a/sw/inc/hints.hxx +++ b/sw/inc/hints.hxx @@ -31,6 +31,7 @@ class SwNodes; class SwPageFrame; class SwFrame; class SwHistory; +class SwTextNode; // Base class for all Message-Hints: // "Overhead" of SfxPoolItem is handled here @@ -95,6 +96,18 @@ public: namespace sw { +/// text is moved into pDestNode +class MoveText : public SfxHint +{ +public: + SwTextNode * pDestNode; + sal_Int32 nDestStart; + sal_Int32 nSourceStart; + sal_Int32 nLen; + + MoveText(SwTextNode *pD, sal_Int32 nD, sal_Int32 nS, sal_Int32 nL); +}; + /// new delete redline is created class RedlineDelText : public SfxHint { diff --git a/sw/source/core/attr/hints.cxx b/sw/source/core/attr/hints.cxx index 7c1ff2a40aec..7746058a7e1e 100644 --- a/sw/source/core/attr/hints.cxx +++ b/sw/source/core/attr/hints.cxx @@ -48,6 +48,11 @@ SwDelText::SwDelText( sal_Int32 nS, sal_Int32 nL ) namespace sw { +MoveText::MoveText(SwTextNode *const pD, sal_Int32 const nD, sal_Int32 const nS, sal_Int32 const nL) + : pDestNode(pD), nDestStart(nD), nSourceStart(nS), nLen(nL) +{ +} + RedlineDelText::RedlineDelText(sal_Int32 const nS, sal_Int32 const nL) : nStart(nS), nLen(nL) { diff --git a/sw/source/core/text/txtfrm.cxx b/sw/source/core/text/txtfrm.cxx index c8bdae109b06..9c1a6a0f0f55 100644 --- a/sw/source/core/text/txtfrm.cxx +++ b/sw/source/core/text/txtfrm.cxx @@ -1656,6 +1656,72 @@ static void lcl_ModifyOfst(SwTextFrame* pFrame, TextFrameIndex const nPos, TextF } } +namespace { + +void UpdateMergedParaForMove(sw::MergedPara & rMerged, + SwTextFrame & rTextFrame, + bool & o_rbRecalcFootnoteFlag, + SwTextNode const& rDestNode, + SwTextNode const& rNode, + sal_Int32 const nDestStart, + sal_Int32 const nSourceStart, + sal_Int32 const nLen) +{ + std::vector<std::pair<sal_Int32, sal_Int32>> deleted; + sal_Int32 const nSourceEnd(nSourceStart + nLen); + sal_Int32 nLastEnd(0); + for (auto it = rMerged.extents.begin(); it != rMerged.extents.end(); ++it) + { + if (it->pNode == &rNode) + { + sal_Int32 const nStart(std::max(nLastEnd, nSourceStart)); + sal_Int32 const nEnd(std::min(it->nStart, nSourceEnd)); + if (nStart < nEnd) + { + deleted.emplace_back(nStart, nEnd); + } + nLastEnd = it->nEnd; + if (nSourceEnd <= it->nEnd) + { + break; + } + } + else if (rNode.GetIndex() < it->pNode->GetIndex()) + { + break; + } + } + if (nLastEnd != rNode.Len() + nLen) // add nLen, string was removed already + { + assert(rNode.Len() == 0 || nLastEnd < nSourceEnd); + if (nLastEnd < nSourceEnd) + { + deleted.emplace_back(std::max(nLastEnd, nSourceStart), nSourceEnd); + } + } + if (!deleted.empty()) + { + o_rbRecalcFootnoteFlag = true; + for (auto it : deleted) + { + sal_Int32 const nStart(it.first - nSourceStart + nDestStart); + TextFrameIndex const nDeleted = UpdateMergedParaForDelete(rMerged, false, + rDestNode, nStart, it.second - it.first); + assert(nDeleted == it.second - it.first); + assert(nDeleted); + // InvalidateRange/lcl_SetScriptInval was called sufficiently for SwInsText + lcl_SetWrong(rTextFrame, rDestNode, nStart, -nDeleted, true); + if (rTextFrame.HasFollow()) + { + TextFrameIndex const nIndex(sw::MapModelToView(rMerged, &rDestNode, nStart)); + lcl_ModifyOfst(&rTextFrame, nIndex, nDeleted); // FIXME why positive? + } + } + } +} + +} // namespace + /** * Related: fdo#56031 filter out attribute changes that don't matter for * humans/a11y to stop flooding the destination mortal with useless noise @@ -1675,6 +1741,7 @@ void SwTextFrame::SwClientNotify(SwModify const& rModify, SfxHint const& rHint) { SfxPoolItem const* pOld(nullptr); SfxPoolItem const* pNew(nullptr); + sw::MoveText const* pMoveText(nullptr); sw::RedlineDelText const* pRedlineDelText(nullptr); sw::RedlineUnDelText const* pRedlineUnDelText(nullptr); @@ -1683,6 +1750,10 @@ void SwTextFrame::SwClientNotify(SwModify const& rModify, SfxHint const& rHint) pOld = pHint->m_pOld; pNew = pHint->m_pNew; } + else if (auto const pHt = dynamic_cast<sw::MoveText const*>(&rHint)) + { + pMoveText = pHt; + } else if (auto const pHynt = dynamic_cast<sw::RedlineDelText const*>(&rHint)) { pRedlineDelText = pHynt; @@ -1805,6 +1876,26 @@ void SwTextFrame::SwClientNotify(SwModify const& rModify, SfxHint const& rHint) lcl_ModifyOfst( this, nPos, nLen ); } } + else if (pMoveText) + { + if (m_pMergedPara + && m_pMergedPara->pFirstNode->GetIndex() <= pMoveText->pDestNode->GetIndex() + && pMoveText->pDestNode->GetIndex() <= m_pMergedPara->pLastNode->GetIndex()) + { // if it's not 2 nodes in merged frame, assume the target node doesn't have frames at all + assert(std::abs(static_cast<long>(rNode.GetIndex()) - static_cast<long>(pMoveText->pDestNode->GetIndex())) == 1); + UpdateMergedParaForMove(*m_pMergedPara, + *this, + bRecalcFootnoteFlag, + *pMoveText->pDestNode, rNode, + pMoveText->nDestStart, + pMoveText->nSourceStart, + pMoveText->nLen); + } + else + { + assert(!m_pMergedPara || !getRootFrame()->IsHideRedlines() || !pMoveText->pDestNode->getLayoutFrame(getRootFrame())); + } + } else switch (nWhich) { case RES_LINENUMBER: diff --git a/sw/source/core/txtnode/ndtxt.cxx b/sw/source/core/txtnode/ndtxt.cxx index b9e44c32cbc6..491eed4af7ff 100644 --- a/sw/source/core/txtnode/ndtxt.cxx +++ b/sw/source/core/txtnode/ndtxt.cxx @@ -2496,6 +2496,8 @@ void SwTextNode::CutImpl( SwTextNode * const pDest, const SwIndex & rDestStart, // want to find their anchor text frame in the follow chain SwInsText aInsHint( nDestStart, nLen ); pDest->ModifyNotification( nullptr, &aInsHint ); + sw::MoveText const moveHint(pDest, nDestStart, nTextStartIdx, nLen); + CallSwClientNotify(moveHint); SwDelText aDelHint( nTextStartIdx, nLen ); ModifyNotification( nullptr, &aDelHint ); commit 1ef0af94217ea3d79da496edf15a5fc5d4aff3a3 Author: Michael Stahl <[email protected]> AuthorDate: Fri Aug 31 19:14:58 2018 +0200 Commit: Michael Stahl <[email protected]> CommitDate: Fri Aug 31 19:14:58 2018 +0200 sw_redlinehide_2: call CompressRedlines later in DeleteRange* DocumentContentOperationsManager::DeleteRange* functions should call CompressRedlines after sw_JoinText, because otherwise if there's a join, the FillSaveData in SwUndoDelete ctor will split redlines that contain the selection into 2, and they won't be recombined although CanCombine is true for them. If you do 2 operations, then on Undo of the second, SetSaveData will restore the previous redlines and join them into 1, but then it will assert because it expects 2 redlines, pointlessly split. Change-Id: I1df3f2205b4f16904f66b5af1f3b9f0ccbaf24a0 diff --git a/sw/source/core/doc/DocumentContentOperationsManager.cxx b/sw/source/core/doc/DocumentContentOperationsManager.cxx index f6a2562983cd..d9b9250d617a 100644 --- a/sw/source/core/doc/DocumentContentOperationsManager.cxx +++ b/sw/source/core/doc/DocumentContentOperationsManager.cxx @@ -1763,6 +1763,12 @@ void DocumentContentOperationsManager::DeleteSection( SwNode *pNode ) void DocumentContentOperationsManager::DeleteRange( SwPaM & rPam ) { lcl_DoWithBreaks( *this, rPam, &DocumentContentOperationsManager::DeleteRangeImpl ); + + if (!m_rDoc.getIDocumentRedlineAccess().IsIgnoreRedline() + && !m_rDoc.getIDocumentRedlineAccess().GetRedlineTable().empty()) + { + m_rDoc.getIDocumentRedlineAccess().CompressRedlines(); + } } bool DocumentContentOperationsManager::DelFullPara( SwPaM& rPam ) @@ -3667,6 +3673,12 @@ bool DocumentContentOperationsManager::DeleteAndJoinImpl( SwPaM & rPam, ::sw_JoinText( rPam, bJoinPrev ); } + if (!m_rDoc.getIDocumentRedlineAccess().IsIgnoreRedline() + && !m_rDoc.getIDocumentRedlineAccess().GetRedlineTable().empty()) + { + m_rDoc.getIDocumentRedlineAccess().CompressRedlines(); + } + return true; } @@ -3859,8 +3871,6 @@ bool DocumentContentOperationsManager::DeleteRangeImplImpl(SwPaM & rPam) } while( false ); - if( !m_rDoc.getIDocumentRedlineAccess().IsIgnoreRedline() && !m_rDoc.getIDocumentRedlineAccess().GetRedlineTable().empty() ) - m_rDoc.getIDocumentRedlineAccess().CompressRedlines(); m_rDoc.getIDocumentState().SetModified(); return true; _______________________________________________ Libreoffice-commits mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
