diff options
author | Michael Stahl <Michael.Stahl@cib.de> | 2018-09-03 18:07:29 +0200 |
---|---|---|
committer | Michael Stahl <Michael.Stahl@cib.de> | 2018-09-19 10:18:29 +0200 |
commit | d258fc29560baa5ecae03ebc2740e11420643e27 (patch) | |
tree | b934fcbe96f5f433e05f365edc438499de63d671 | |
parent | f32075fd7404dba62ae844cff84fdb43a91ac600 (diff) |
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
-rw-r--r-- | sw/source/core/doc/DocumentContentOperationsManager.cxx | 6 | ||||
-rw-r--r-- | sw/source/core/doc/DocumentRedlineManager.cxx | 75 | ||||
-rw-r--r-- | sw/source/core/inc/txtfrm.hxx | 3 | ||||
-rw-r--r-- | sw/source/core/undo/unredln.cxx | 13 |
4 files changed, 96 insertions, 1 deletions
diff --git a/sw/source/core/doc/DocumentContentOperationsManager.cxx b/sw/source/core/doc/DocumentContentOperationsManager.cxx index 7b2b9aaeaf55..45010c29cd4f 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> @@ -3632,6 +3633,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 327ad96f2e64..631b35e9e925 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,74 @@ using namespace com::sun::star; #endif +namespace sw { + +void UpdateFramesForAddDeleteRedline(SwPaM const& rPam) +{ + 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()); + // clear old one first to avoid DelFrames confusing updates & asserts... + pFrame->SetMergedPara(nullptr); + 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()); + // clear old one first to avoid DelFrames confusing updates & asserts... + SwTextNode & rFirstNode(*pMergedPara->pFirstNode); + pFrame->SetMergedPara(nullptr); + pFrame->SetMergedPara(sw::CheckParaRedlineMerge( + *pFrame, rFirstNode, 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 +363,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 +379,6 @@ namespace { case nsRedlineType_t::REDLINE_INSERT: { - SwDoc& rDoc = *pRedl->GetDoc(); const SwPosition *pDelStt = nullptr, *pDelEnd = nullptr; bool bDelRedl = false; switch( eCmp ) @@ -390,6 +459,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 +544,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 3866e55cfe11..a2eaa3f6d72d 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 ) |