[Libreoffice-commits] core.git: Branch 'private/mst/sw_redlinehide_2' - 5 commits - sw/inc sw/source
Libreoffice Gerrit user
logerrit at kemper.freedesktop.org
Mon Sep 3 16:13:29 UTC 2018
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 <Michael.Stahl at cib.de>
AuthorDate: Mon Sep 3 18:07:29 2018 +0200
Commit: Michael Stahl <Michael.Stahl at cib.de>
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 <Michael.Stahl at cib.de>
AuthorDate: Mon Sep 3 17:20:37 2018 +0200
Commit: Michael Stahl <Michael.Stahl at cib.de>
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 <Michael.Stahl at cib.de>
AuthorDate: Mon Sep 3 15:12:29 2018 +0200
Commit: Michael Stahl <Michael.Stahl at cib.de>
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 <Michael.Stahl at cib.de>
AuthorDate: Mon Sep 3 12:18:25 2018 +0200
Commit: Michael Stahl <Michael.Stahl at cib.de>
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 <Michael.Stahl at cib.de>
AuthorDate: Fri Aug 31 19:14:58 2018 +0200
Commit: Michael Stahl <Michael.Stahl at cib.de>
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;
More information about the Libreoffice-commits
mailing list