summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Stahl <Michael.Stahl@cib.de>2018-09-03 18:07:29 +0200
committerMichael Stahl <Michael.Stahl@cib.de>2018-09-19 10:18:29 +0200
commitd258fc29560baa5ecae03ebc2740e11420643e27 (patch)
treeb934fcbe96f5f433e05f365edc438499de63d671
parentf32075fd7404dba62ae844cff84fdb43a91ac600 (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.cxx6
-rw-r--r--sw/source/core/doc/DocumentRedlineManager.cxx75
-rw-r--r--sw/source/core/inc/txtfrm.hxx3
-rw-r--r--sw/source/core/undo/unredln.cxx13
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 )