summaryrefslogtreecommitdiff
path: root/sw/source/core/doc/DocumentRedlineManager.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sw/source/core/doc/DocumentRedlineManager.cxx')
-rw-r--r--sw/source/core/doc/DocumentRedlineManager.cxx2761
1 files changed, 1679 insertions, 1082 deletions
diff --git a/sw/source/core/doc/DocumentRedlineManager.cxx b/sw/source/core/doc/DocumentRedlineManager.cxx
index 1c63619a8e1b..710baaf41b94 100644
--- a/sw/source/core/doc/DocumentRedlineManager.cxx
+++ b/sw/source/core/doc/DocumentRedlineManager.cxx
@@ -20,8 +20,10 @@
#include <frmfmt.hxx>
#include <rootfrm.hxx>
#include <txtfrm.hxx>
+#include <txtfld.hxx>
#include <doc.hxx>
#include <docsh.hxx>
+#include <wrtsh.hxx>
#include <fmtfld.hxx>
#include <frmtool.hxx>
#include <IDocumentUndoRedo.hxx>
@@ -38,6 +40,8 @@
#include <strings.hrc>
#include <swmodule.hxx>
#include <osl/diagnose.h>
+#include <editeng/prntitem.hxx>
+#include <comphelper/lok.hxx>
using namespace com::sun::star;
@@ -52,17 +56,17 @@ using namespace com::sun::star;
// 2. check that position is valid and doesn't point after text
void lcl_CheckPosition( const SwPosition* pPos )
{
- assert(dynamic_cast<SwIndexReg*>(&pPos->nNode.GetNode())
- == pPos->nContent.GetIdxReg());
+ assert(dynamic_cast<SwContentIndexReg*>(&pPos->GetNode())
+ == pPos->GetContentNode());
- SwTextNode* pTextNode = pPos->nNode.GetNode().GetTextNode();
+ SwTextNode* pTextNode = pPos->GetNode().GetTextNode();
if( pTextNode == nullptr )
{
- assert(pPos->nContent == 0);
+ assert(pPos->GetContentIndex() == 0);
}
else
{
- assert(pPos->nContent >= 0 && pPos->nContent <= pTextNode->Len());
+ assert(pPos->GetContentIndex() >= 0 && pPos->GetContentIndex() <= pTextNode->Len());
}
}
@@ -75,7 +79,7 @@ using namespace com::sun::star;
// check validity of the redline table. Checks redline bounds, and make
// sure the redlines are sorted and non-overlapping.
- void lcl_CheckRedline( IDocumentRedlineAccess& redlineAccess )
+ void lcl_CheckRedline( const IDocumentRedlineAccess& redlineAccess )
{
const SwRedlineTable& rTable = redlineAccess.GetRedlineTable();
@@ -91,7 +95,7 @@ using namespace com::sun::star;
OSL_ENSURE( ( *(j->GetPoint()) != *(j->GetMark()) ) ||
( j->GetContentIdx() != nullptr ),
ERROR_PREFIX "empty redline" );
- }
+ }
// verify proper redline sorting
for( size_t n = 1; n < rTable.size(); ++n )
@@ -144,22 +148,22 @@ void UpdateFramesForAddDeleteRedline(SwDoc & rDoc, SwPaM const& rPam)
}
// no need to call UpdateFootnoteNums for FTNNUM_PAGE:
// the AppendFootnote/RemoveFootnote will do it by itself!
- rDoc.GetFootnoteIdxs().UpdateFootnote(rPam.Start()->nNode);
+ rDoc.GetFootnoteIdxs().UpdateFootnote(rPam.Start()->GetNode());
SwPosition currentStart(*rPam.Start());
- SwTextNode * pStartNode(rPam.Start()->nNode.GetNode().GetTextNode());
+ SwTextNode * pStartNode(rPam.Start()->GetNode().GetTextNode());
while (!pStartNode)
{
// note: branch only taken for redlines, not fieldmarks
SwStartNode *const pTableOrSectionNode(
- currentStart.nNode.GetNode().IsTableNode()
- ? static_cast<SwStartNode*>(currentStart.nNode.GetNode().GetTableNode())
- : static_cast<SwStartNode*>(currentStart.nNode.GetNode().GetSectionNode()));
+ currentStart.GetNode().IsTableNode()
+ ? static_cast<SwStartNode*>(currentStart.GetNode().GetTableNode())
+ : static_cast<SwStartNode*>(currentStart.GetNode().GetSectionNode()));
if ( !pTableOrSectionNode )
{
SAL_WARN("sw.core", "UpdateFramesForAddDeleteRedline:: known pathology (or ChangesInRedline mode)");
return;
}
- for (sal_uLong j = pTableOrSectionNode->GetIndex(); j <= pTableOrSectionNode->EndOfSectionIndex(); ++j)
+ for (SwNodeOffset j = pTableOrSectionNode->GetIndex(); j <= pTableOrSectionNode->EndOfSectionIndex(); ++j)
{
pTableOrSectionNode->GetNodes()[j]->SetRedlineMergeFlag(SwNode::Merge::Hidden);
}
@@ -177,15 +181,20 @@ void UpdateFramesForAddDeleteRedline(SwDoc & rDoc, SwPaM const& rPam)
}
}
}
- currentStart.nNode = pTableOrSectionNode->EndOfSectionIndex() + 1;
- currentStart.nContent.Assign(currentStart.nNode.GetNode().GetContentNode(), 0);
- pStartNode = currentStart.nNode.GetNode().GetTextNode();
+ currentStart.Assign( pTableOrSectionNode->EndOfSectionIndex() + 1 );
+ pStartNode = currentStart.GetNode().GetTextNode();
}
if (currentStart < *rPam.End())
{
SwTextNode * pNode(pStartNode);
do
{
+ // deleted text node: remove it from "hidden" list
+ // to update numbering in Show Changes mode
+ SwPosition aPos( *pNode, pNode->Len() );
+ if ( pNode->GetNumRule() && aPos < *rPam.End() )
+ pNode->RemoveFromListRLHidden();
+
std::vector<SwTextFrame*> frames;
SwIterator<SwTextFrame, SwTextNode, sw::IteratorMode::UnwrapMulti> aIter(*pNode);
for (SwTextFrame * pFrame = aIter.First(); pFrame; pFrame = aIter.Next())
@@ -194,6 +203,8 @@ void UpdateFramesForAddDeleteRedline(SwDoc & rDoc, SwPaM const& rPam)
{
frames.push_back(pFrame);
}
+ // set anchored objects as deleted
+ pFrame->SetDrawObjsAsDeleted(true);
}
if (frames.empty())
{
@@ -229,9 +240,9 @@ void UpdateFramesForAddDeleteRedline(SwDoc & rDoc, SwPaM const& rPam)
}
SwNodeIndex tmp(*pLast);
// skip over hidden sections!
- pNode = static_cast<SwTextNode*>(pLast->GetNodes().GoNextSection(&tmp, /*bSkipHidden=*/true, /*bSkipProtect=*/false));
+ pNode = static_cast<SwTextNode*>(SwNodes::GoNextSection(&tmp, /*bSkipHidden=*/true, /*bSkipProtect=*/false));
}
- while (pNode && pNode->GetIndex() <= rPam.End()->nNode.GetIndex());
+ while (pNode && pNode->GetIndex() <= rPam.End()->GetNodeIndex());
}
// fields last - SwGetRefField::UpdateField requires up-to-date frames
UpdateFieldsForRedline(rDoc.getIDocumentFieldsAccess()); // after footnotes
@@ -243,23 +254,24 @@ void UpdateFramesForAddDeleteRedline(SwDoc & rDoc, SwPaM const& rPam)
void UpdateFramesForRemoveDeleteRedline(SwDoc & rDoc, SwPaM const& rPam)
{
- if (rDoc.IsClipBoard())
+ // tdf#147006 fieldmark command may be empty => do not call AppendAllObjs()
+ if (rDoc.IsClipBoard() || *rPam.GetPoint() == *rPam.GetMark())
{
return;
}
bool isAppendObjsCalled(false);
- rDoc.GetFootnoteIdxs().UpdateFootnote(rPam.Start()->nNode);
+ rDoc.GetFootnoteIdxs().UpdateFootnote(rPam.Start()->GetNode());
SwPosition currentStart(*rPam.Start());
- SwTextNode * pStartNode(rPam.Start()->nNode.GetNode().GetTextNode());
+ SwTextNode * pStartNode(rPam.Start()->GetNode().GetTextNode());
while (!pStartNode)
{
// note: branch only taken for redlines, not fieldmarks
- SwStartNode const*const pTableOrSectionNode(
- currentStart.nNode.GetNode().IsTableNode()
- ? static_cast<SwStartNode*>(currentStart.nNode.GetNode().GetTableNode())
- : static_cast<SwStartNode*>(currentStart.nNode.GetNode().GetSectionNode()));
+ SwStartNode *const pTableOrSectionNode(
+ currentStart.GetNode().IsTableNode()
+ ? static_cast<SwStartNode*>(currentStart.GetNode().GetTableNode())
+ : static_cast<SwStartNode*>(currentStart.GetNode().GetSectionNode()));
assert(pTableOrSectionNode); // known pathology
- for (sal_uLong j = pTableOrSectionNode->GetIndex(); j <= pTableOrSectionNode->EndOfSectionIndex(); ++j)
+ for (SwNodeOffset j = pTableOrSectionNode->GetIndex(); j <= pTableOrSectionNode->EndOfSectionIndex(); ++j)
{
pTableOrSectionNode->GetNodes()[j]->SetRedlineMergeFlag(SwNode::Merge::None);
}
@@ -267,19 +279,23 @@ void UpdateFramesForRemoveDeleteRedline(SwDoc & rDoc, SwPaM const& rPam)
{
// note: this will also create frames for all currently hidden flys
// because it calls AppendAllObjs
- SwNodeIndex const end(*pTableOrSectionNode->EndOfSectionNode());
- ::MakeFrames(&rDoc, currentStart.nNode, end);
+ ::MakeFrames(&rDoc, currentStart.GetNode(), *pTableOrSectionNode->EndOfSectionNode());
isAppendObjsCalled = true;
}
- currentStart.nNode = pTableOrSectionNode->EndOfSectionIndex() + 1;
- currentStart.nContent.Assign(currentStart.nNode.GetNode().GetContentNode(), 0);
- pStartNode = currentStart.nNode.GetNode().GetTextNode();
+ currentStart.Assign( pTableOrSectionNode->EndOfSectionIndex() + 1 );
+ pStartNode = currentStart.GetNode().GetTextNode();
}
if (currentStart < *rPam.End())
{
SwTextNode * pNode(pStartNode);
do
{
+ // undeleted text node: add it to the "hidden" list
+ // to update numbering in Show Changes mode
+ SwPosition aPos( *pNode, pNode->Len() );
+ if ( pNode->GetNumRule() && aPos < *rPam.End() )
+ pNode->AddToListRLHidden();
+
std::vector<SwTextFrame*> frames;
SwIterator<SwTextFrame, SwTextNode, sw::IteratorMode::UnwrapMulti> aIter(*pNode);
for (SwTextFrame * pFrame = aIter.First(); pFrame; pFrame = aIter.Next())
@@ -288,6 +304,8 @@ void UpdateFramesForRemoveDeleteRedline(SwDoc & rDoc, SwPaM const& rPam)
{
frames.push_back(pFrame);
}
+ // set anchored objects as not deleted
+ pFrame->SetDrawObjsAsDeleted(false);
}
if (frames.empty())
{
@@ -303,6 +321,12 @@ void UpdateFramesForRemoveDeleteRedline(SwDoc & rDoc, SwPaM const& rPam)
break;
}
+ // no nodes can be unmerged by this - skip MakeFrames() etc.
+ if (rPam.GetPoint()->GetNode() == rPam.GetMark()->GetNode())
+ {
+ break; // continue with AppendAllObjs()
+ }
+
// first, call CheckParaRedlineMerge on the first paragraph,
// to init flag on new merge range (if any) + 1st node post the merge
auto eMode(sw::FrameMode::Existing);
@@ -333,7 +357,7 @@ void UpdateFramesForRemoveDeleteRedline(SwDoc & rDoc, SwPaM const& rPam)
SwNodeIndex const end(*pLast, +1); // end is exclusive
// note: this will also create frames for all currently hidden flys
// both on first and non-first nodes because it calls AppendAllObjs
- ::MakeFrames(&rDoc, start, end);
+ ::MakeFrames(&rDoc, start.GetNode(), end.GetNode());
isAppendObjsCalled = true;
// re-use this to move flys that are now on the wrong frame, with end
// of redline as "second" node; the nodes between start and end should
@@ -342,9 +366,9 @@ void UpdateFramesForRemoveDeleteRedline(SwDoc & rDoc, SwPaM const& rPam)
}
SwNodeIndex tmp(*pLast);
// skip over hidden sections!
- pNode = static_cast<SwTextNode*>(pLast->GetNodes().GoNextSection(&tmp, /*bSkipHidden=*/true, /*bSkipProtect=*/false));
+ pNode = static_cast<SwTextNode*>(SwNodes::GoNextSection(&tmp, /*bSkipHidden=*/true, /*bSkipProtect=*/false));
}
- while (pNode && pNode->GetIndex() <= rPam.End()->nNode.GetIndex());
+ while (pNode && pNode->GetIndex() <= rPam.End()->GetNodeIndex());
}
if (!isAppendObjsCalled)
@@ -361,8 +385,14 @@ void UpdateFramesForRemoveDeleteRedline(SwDoc & rDoc, SwPaM const& rPam)
// fields last - SwGetRefField::UpdateField requires up-to-date frames
UpdateFieldsForRedline(rDoc.getIDocumentFieldsAccess()); // after footnotes
- // update SwPostItMgr / notes in the margin
- rDoc.GetDocShell()->Broadcast(
+ const SwTextNode *pTextNode = rPam.GetPointNode().GetTextNode();
+ SwTextAttr* pTextAttr = pTextNode ? pTextNode->GetFieldTextAttrAt(rPam.GetPoint()->GetContentIndex() - 1, ::sw::GetTextAttrMode::Default) : nullptr;
+ SwTextField *const pTextField(static_txtattr_cast<SwTextField*>(pTextAttr));
+ if (pTextField && comphelper::LibreOfficeKit::isActive() )
+ rDoc.GetDocShell()->Broadcast(
+ SwFormatFieldHint(&pTextField->GetFormatField(), SwFormatFieldHintWhich::INSERTED));
+ else
+ rDoc.GetDocShell()->Broadcast(
SwFormatFieldHint(nullptr, SwFormatFieldHintWhich::INSERTED) );
}
@@ -373,19 +403,19 @@ namespace
bool IsPrevPos( const SwPosition & rPos1, const SwPosition & rPos2 )
{
const SwContentNode* pCNd;
- if( 0 != rPos2.nContent.GetIndex() )
+ if( 0 != rPos2.GetContentIndex() )
return false;
- if( rPos2.nNode.GetIndex() - 1 != rPos1.nNode.GetIndex() )
+ if( rPos2.GetNodeIndex() - 1 != rPos1.GetNodeIndex() )
return false;
- pCNd = rPos1.nNode.GetNode().GetContentNode();
- return pCNd && rPos1.nContent.GetIndex() == pCNd->Len();
+ pCNd = rPos1.GetNode().GetContentNode();
+ return pCNd && rPos1.GetContentIndex() == pCNd->Len();
}
// copy style or return with SwRedlineExtra_FormatColl with reject data of the upcoming copy
SwRedlineExtraData_FormatColl* lcl_CopyStyle( const SwPosition & rFrom, const SwPosition & rTo, bool bCopy = true )
{
- SwTextNode* pToNode = rTo.nNode.GetNode().GetTextNode();
- SwTextNode* pFromNode = rFrom.nNode.GetNode().GetTextNode();
+ SwTextNode* pToNode = rTo.GetNode().GetTextNode();
+ SwTextNode* pFromNode = rFrom.GetNode().GetTextNode();
if (pToNode != nullptr && pFromNode != nullptr && pToNode != pFromNode)
{
const SwPaM aPam(*pToNode);
@@ -398,12 +428,11 @@ namespace
// using Undo, remove direct paragraph formatting of the "To" paragraph,
// and apply here direct paragraph formatting of the "From" paragraph
- SfxItemSet aTmp(
- rDoc.GetAttrPool(),
- svl::Items<
+ SfxItemSetFixed<
RES_PARATR_BEGIN, RES_PARATR_END - 3, // skip RSID and GRABBAG
RES_PARATR_LIST_BEGIN, RES_UL_SPACE, // skip PAGEDESC and BREAK
- RES_CNTNT, RES_FRMATR_END - 1>{});
+ RES_CNTNT, RES_FRMATR_END - 1>
+ aTmp(rDoc.GetAttrPool());
SfxItemSet aTmp2(aTmp);
pToNode->GetParaAttr(aTmp, 0, 0);
@@ -415,10 +444,10 @@ namespace
{
for( sal_uInt16 nItem = 0; nItem < aTmp.TotalCount(); ++nItem)
{
- sal_uInt16 nWhich = aTmp.GetWhichByPos(nItem);
+ sal_uInt16 nWhich = aTmp.GetWhichByOffset(nItem);
if( SfxItemState::SET == aTmp.GetItemState( nWhich, false ) &&
SfxItemState::SET != aTmp2.GetItemState( nWhich, false ) )
- aTmp2.Put( aTmp.GetPool()->GetDefaultItem(nWhich), nWhich );
+ aTmp2.Put( aTmp.GetPool()->GetUserOrPoolDefaultItem(nWhich) );
}
}
@@ -430,6 +459,105 @@ namespace
return nullptr;
}
+ // delete the empty tracked table row (i.e. if it's last tracked deletion was accepted)
+ void lcl_DeleteTrackedTableRow ( const SwPosition* pPos )
+ {
+ const SwTableBox* pBox = pPos->GetNode().GetTableBox();
+ if ( !pBox )
+ return;
+
+ // tracked column deletion
+
+ const SvxPrintItem *pHasBoxTextChangesOnlyProp =
+ pBox->GetFrameFormat()->GetAttrSet().GetItem<SvxPrintItem>(RES_PRINT);
+ // empty table cell with property "HasTextChangesOnly" = false
+ if ( pHasBoxTextChangesOnlyProp && !pHasBoxTextChangesOnlyProp->GetValue() )
+ {
+ SwCursor aCursor( *pPos, nullptr );
+ if ( pBox->IsEmpty() )
+ {
+ // tdf#155747 remove table cursor
+ pPos->GetDoc().GetDocShell()->GetWrtShell()->EnterStdMode();
+ // TODO check the other cells of the column
+ // before removing the column
+ pPos->GetDoc().DeleteCol( aCursor );
+ return;
+ }
+ else
+ {
+ SvxPrintItem aHasTextChangesOnly(RES_PRINT, false);
+ pPos->GetDoc().SetBoxAttr( aCursor, aHasTextChangesOnly );
+ }
+ }
+
+ // tracked row deletion
+
+ const SwTableLine* pLine = pBox->GetUpper();
+ const SvxPrintItem *pHasTextChangesOnlyProp =
+ pLine->GetFrameFormat()->GetAttrSet().GetItem<SvxPrintItem>(RES_PRINT);
+ // empty table row with property "HasTextChangesOnly" = false
+ if ( pHasTextChangesOnlyProp && !pHasTextChangesOnlyProp->GetValue() )
+ {
+ if ( pLine->IsEmpty() )
+ {
+ SwCursor aCursor( *pPos, nullptr );
+ pPos->GetDoc().DeleteRow( aCursor );
+ }
+ else
+ {
+ // update property "HasTextChangesOnly"
+ SwRedlineTable::size_type nPos = 0;
+ (void)pLine->UpdateTextChangesOnly(nPos);
+ }
+ }
+ }
+
+ // at rejection of a deletion in a table, remove the tracking of the table row
+ // (also at accepting the last redline insertion of a tracked table row insertion)
+ void lcl_RemoveTrackingOfTableRow( const SwPosition* pPos, bool bRejectDeletion )
+ {
+ const SwTableBox* pBox = pPos->GetNode().GetTableBox();
+ if ( !pBox )
+ return;
+
+ // tracked column deletion
+
+ const SvxPrintItem *pHasBoxTextChangesOnlyProp =
+ pBox->GetFrameFormat()->GetAttrSet().GetItem<SvxPrintItem>(RES_PRINT);
+ // table cell property "HasTextChangesOnly" is set and its value is false
+ if ( pHasBoxTextChangesOnlyProp && !pHasBoxTextChangesOnlyProp->GetValue() )
+ {
+ SvxPrintItem aUnsetTracking(RES_PRINT, true);
+ SwCursor aCursor( *pPos, nullptr );
+ pPos->GetDoc().SetBoxAttr( aCursor, aUnsetTracking );
+ }
+
+ // tracked row deletion
+
+ const SwTableLine* pLine = pBox->GetUpper();
+ const SvxPrintItem *pHasTextChangesOnlyProp =
+ pLine->GetFrameFormat()->GetAttrSet().GetItem<SvxPrintItem>(RES_PRINT);
+ // table row property "HasTextChangesOnly" is set and its value is false
+ if ( pHasTextChangesOnlyProp && !pHasTextChangesOnlyProp->GetValue() )
+ {
+ bool bNoMoreInsertion = false;
+ if ( !bRejectDeletion )
+ {
+ SwRedlineTable::size_type nPos = 0;
+ SwRedlineTable::size_type nInsert = pLine->UpdateTextChangesOnly(nPos, /*bUpdateProperty=*/false);
+
+ if ( SwRedlineTable::npos == nInsert )
+ bNoMoreInsertion = true;
+ }
+ if ( bRejectDeletion || bNoMoreInsertion )
+ {
+ SvxPrintItem aUnsetTracking(RES_PRINT, true);
+ SwCursor aCursor( *pPos, nullptr );
+ pPos->GetDoc().SetRowNotTracked( aCursor, aUnsetTracking );
+ }
+ }
+ }
+
bool lcl_AcceptRedline( SwRedlineTable& rArr, SwRedlineTable::size_type& rPos,
bool bCallDelete,
const SwPosition* pSttRng = nullptr,
@@ -485,7 +613,15 @@ namespace
case SwComparePosition::Outside:
case SwComparePosition::Equal:
- rArr.DeleteAndDestroy( rPos-- );
+ {
+ bool bInsert = RedlineType::Insert == pRedl->GetType();
+ SwPosition aPos(pRedl->Start()->GetNode());
+ rArr.DeleteAndDestroy( rPos-- );
+
+ // remove tracking of the table row, if needed
+ if ( bInsert )
+ lcl_RemoveTrackingOfTableRow( &aPos, /*bRejectDelete=*/false );
+ }
break;
default:
@@ -549,13 +685,13 @@ namespace
if( pDelStt && pDelEnd )
{
SwPaM aPam( *pDelStt, *pDelEnd );
- SwContentNode* pCSttNd = pDelStt->nNode.GetNode().GetContentNode();
- SwContentNode* pCEndNd = pDelEnd->nNode.GetNode().GetContentNode();
+ SwContentNode* pCSttNd = pDelStt->GetNode().GetContentNode();
+ SwContentNode* pCEndNd = pDelEnd->GetNode().GetContentNode();
pRStt = pRedl->Start();
pREnd = pRedl->End();
// keep style of the empty paragraph after deletion of wholly paragraphs
- if( pCSttNd && pCEndNd && pRStt && pREnd && pRStt->nContent == 0 )
+ if( pCSttNd && pCEndNd && pRStt && pREnd && pRStt->GetContentIndex() == 0 )
lcl_CopyStyle(*pREnd, *pRStt);
if( bDelRedl )
@@ -565,7 +701,10 @@ namespace
rDoc.getIDocumentRedlineAccess().SetRedlineFlags_intern( eOld & ~RedlineFlags(RedlineFlags::On | RedlineFlags::Ignore));
if( pCSttNd && pCEndNd )
+ {
rDoc.getIDocumentContentOperations().DeleteAndJoin( aPam );
+ lcl_DeleteTrackedTableRow( aPam.End() );
+ }
else if (pCSttNd && !pCEndNd)
{
aPam.GetBound().nContent.Assign( nullptr, 0 );
@@ -667,8 +806,8 @@ namespace
{
SwPaM aPam( *pDelStt, *pDelEnd );
- SwContentNode* pCSttNd = pDelStt->nNode.GetNode().GetContentNode();
- SwContentNode* pCEndNd = pDelEnd->nNode.GetNode().GetContentNode();
+ SwContentNode* pCSttNd = pDelStt->GetNode().GetContentNode();
+ SwContentNode* pCEndNd = pDelEnd->GetNode().GetContentNode();
if( bDelRedl )
delete pRedl;
@@ -677,16 +816,19 @@ namespace
rDoc.getIDocumentRedlineAccess().SetRedlineFlags_intern( eOld & ~RedlineFlags(RedlineFlags::On | RedlineFlags::Ignore));
if( pCSttNd && pCEndNd )
+ {
rDoc.getIDocumentContentOperations().DeleteAndJoin( aPam );
+ lcl_DeleteTrackedTableRow( aPam.End() );
+ }
else if (pCSttNd && !pCEndNd)
{
aPam.GetBound().nContent.Assign( nullptr, 0 );
aPam.GetBound( false ).nContent.Assign( nullptr, 0 );
- if (aPam.End()->nNode.GetNode().IsStartNode())
+ if (aPam.End()->GetNode().IsStartNode())
{ // end node will be deleted too! see nNodeDiff+1
- --aPam.End()->nNode;
+ aPam.End()->Adjust(SwNodeOffset(-1));
}
- assert(!aPam.End()->nNode.GetNode().IsStartNode());
+ assert(!aPam.End()->GetNode().IsStartNode());
rDoc.getIDocumentContentOperations().DelFullPara( aPam );
}
else
@@ -709,6 +851,9 @@ namespace
if( pRedl->GetExtraData() )
pRedl->GetExtraData()->Reject( *pRedl );
+ // remove tracking of the table row, if needed
+ lcl_RemoveTrackingOfTableRow( updatePaM.End(), /*bRejectDelete=*/true );
+
switch( eCmp )
{
case SwComparePosition::Inside:
@@ -815,7 +960,7 @@ namespace
// handle paragraph formatting changes
// (range is only a full paragraph or a part of it)
const SwPosition* pStt = pRedl->Start();
- SwTextNode* pTNd = pStt->nNode.GetNode().GetTextNode();
+ SwTextNode* pTNd = pStt->GetNode().GetTextNode();
if( pTNd )
{
// expand range to the whole paragraph
@@ -855,6 +1000,18 @@ namespace
return bRet;
}
+ bool lcl_AcceptInnerInsertRedline(SwRedlineTable& rArr, SwRedlineTable::size_type& rPos,
+ int nDepth)
+ {
+ SwRangeRedline* pRedl = rArr[rPos];
+ SwDoc& rDoc = pRedl->GetDoc();
+ SwPaM const updatePaM(*pRedl->Start(), *pRedl->End());
+
+ pRedl->PopAllDataAfter(nDepth);
+ sw::UpdateFramesForRemoveDeleteRedline(rDoc, updatePaM);
+ return true;
+ }
+
typedef bool (*Fn_AcceptReject)( SwRedlineTable& rArr, SwRedlineTable::size_type& rPos,
bool bCallDelete,
const SwPosition* pSttRng,
@@ -869,8 +1026,7 @@ namespace
int nCount = 0;
const SwPosition* pStt = rPam.Start(),
- * pEnd = pStt == rPam.GetPoint() ? rPam.GetMark()
- : rPam.GetPoint();
+ * pEnd = rPam.End();
const SwRangeRedline* pFnd = rArr.FindAtPosition( *pStt, n );
if( pFnd && // Is new a part of it?
( *pFnd->Start() != *pStt || *pFnd->End() > *pEnd ))
@@ -925,32 +1081,30 @@ namespace
// The Selection is only in the ContentSection. If there are Redlines
// to Non-ContentNodes before or after that, then the Selections
// expand to them.
- SwPosition* pStt = rPam.Start(),
- * pEnd = pStt == rPam.GetPoint() ? rPam.GetMark()
- : rPam.GetPoint();
+ auto [pStt, pEnd] = rPam.StartEnd(); // SwPosition*
SwDoc& rDoc = rPam.GetDoc();
- if( !pStt->nContent.GetIndex() &&
- !rDoc.GetNodes()[ pStt->nNode.GetIndex() - 1 ]->IsContentNode() )
+ if( !pStt->GetContentIndex() &&
+ !rDoc.GetNodes()[ pStt->GetNodeIndex() - 1 ]->IsContentNode() )
{
const SwRangeRedline* pRedl = rDoc.getIDocumentRedlineAccess().GetRedline( *pStt, nullptr );
if( pRedl )
{
const SwPosition* pRStt = pRedl->Start();
- if( !pRStt->nContent.GetIndex() && pRStt->nNode.GetIndex() ==
- pStt->nNode.GetIndex() - 1 )
+ if( !pRStt->GetContentIndex() && pRStt->GetNodeIndex() ==
+ pStt->GetNodeIndex() - 1 )
*pStt = *pRStt;
}
}
- if( pEnd->nNode.GetNode().IsContentNode() &&
- !rDoc.GetNodes()[ pEnd->nNode.GetIndex() + 1 ]->IsContentNode() &&
- pEnd->nContent.GetIndex() == pEnd->nNode.GetNode().GetContentNode()->Len() )
+ if( pEnd->GetNode().IsContentNode() &&
+ !rDoc.GetNodes()[ pEnd->GetNodeIndex() + 1 ]->IsContentNode() &&
+ pEnd->GetContentIndex() == pEnd->GetNode().GetContentNode()->Len() )
{
const SwRangeRedline* pRedl = rDoc.getIDocumentRedlineAccess().GetRedline( *pEnd, nullptr );
if( pRedl )
{
const SwPosition* pREnd = pRedl->End();
- if( !pREnd->nContent.GetIndex() && pREnd->nNode.GetIndex() ==
- pEnd->nNode.GetIndex() + 1 )
+ if( !pREnd->GetContentIndex() && pREnd->GetNodeIndex() ==
+ pEnd->GetNodeIndex() + 1 )
*pEnd = *pREnd;
}
}
@@ -972,9 +1126,9 @@ namespace
{
m_pCursor->SetMark();
*m_pCursor->GetMark() = *m_rRedline.GetMark();
- *m_rRedline.GetMark() = SwPosition(rDoc.GetNodes().GetEndOfContent());
+ m_rRedline.GetMark()->Assign(rDoc.GetNodes().GetEndOfContent());
}
- *m_rRedline.GetPoint() = SwPosition(rDoc.GetNodes().GetEndOfContent());
+ m_rRedline.GetPoint()->Assign(rDoc.GetNodes().GetEndOfContent());
}
~TemporaryRedlineUpdater()
{
@@ -989,8 +1143,6 @@ namespace sw
DocumentRedlineManager::DocumentRedlineManager(SwDoc& i_rSwdoc)
: m_rDoc(i_rSwdoc)
, meRedlineFlags(RedlineFlags::ShowInsert | RedlineFlags::ShowDelete)
- , mpRedlineTable(new SwRedlineTable)
- , mpExtraRedlineTable(new SwExtraRedlineTable)
, mbIsRedlineMove(false)
, mnAutoFormatRedlnCommentNo(0)
{
@@ -1051,12 +1203,12 @@ void DocumentRedlineManager::SetRedlineFlags( RedlineFlags eMode )
}
for (sal_uInt16 nLoop = 1; nLoop <= 2; ++nLoop)
- for (size_t i = 0; i < mpRedlineTable->size(); ++i)
+ for (size_t i = 0; i < maRedlineTable.size(); ++i)
{
- SwRangeRedline *const pRedline((*mpRedlineTable)[i]);
+ SwRangeRedline *const pRedline = maRedlineTable[i];
(pRedline->*pFnc)(nLoop, i, false);
- while (mpRedlineTable->size() <= i
- || (*mpRedlineTable)[i] != pRedline)
+ while (maRedlineTable.size() <= i
+ || maRedlineTable[i] != pRedline)
{ // ensure current position
--i; // a previous redline may have been deleted
}
@@ -1064,7 +1216,7 @@ void DocumentRedlineManager::SetRedlineFlags( RedlineFlags eMode )
//SwRangeRedline::MoveFromSection routinely changes
//the keys that mpRedlineTable is sorted by
- mpRedlineTable->Resort();
+ maRedlineTable.Resort();
CheckAnchoredFlyConsistency(m_rDoc);
CHECK_REDLINE( *this )
@@ -1099,31 +1251,29 @@ void DocumentRedlineManager::SetRedlineFlags_intern(RedlineFlags eMode)
const SwRedlineTable& DocumentRedlineManager::GetRedlineTable() const
{
- return *mpRedlineTable;
+ return maRedlineTable;
}
SwRedlineTable& DocumentRedlineManager::GetRedlineTable()
{
- return *mpRedlineTable;
+ return maRedlineTable;
}
const SwExtraRedlineTable& DocumentRedlineManager::GetExtraRedlineTable() const
{
- return *mpExtraRedlineTable;
+ return maExtraRedlineTable;
}
SwExtraRedlineTable& DocumentRedlineManager::GetExtraRedlineTable()
{
- return *mpExtraRedlineTable;
-}
-
-bool DocumentRedlineManager::HasExtraRedlineTable() const
-{
- return mpExtraRedlineTable != nullptr;
+ return maExtraRedlineTable;
}
bool DocumentRedlineManager::IsInRedlines(const SwNode & rNode) const
{
+ if (&rNode.GetNodes() != &m_rDoc.GetNodes())
+ return false;
+
SwPosition aPos(rNode);
SwNode & rEndOfRedlines = m_rDoc.GetNodes().GetEndOfRedlines();
SwPaM aPam(SwPosition(*rEndOfRedlines.StartOfSectionNode()),
@@ -1167,342 +1317,490 @@ Behaviour of Delete-Redline:
the Delete
*/
IDocumentRedlineAccess::AppendResult
-DocumentRedlineManager::AppendRedline(SwRangeRedline* pNewRedl, bool const bCallDelete)
+DocumentRedlineManager::AppendRedline(SwRangeRedline* pNewRedl, bool const bCallDelete,
+ sal_uInt32 nMoveIDToDelete)
{
- bool bMerged = false;
CHECK_REDLINE( *this )
- if (IsRedlineOn() && !IsShowOriginal(meRedlineFlags))
+ if (!IsRedlineOn() || IsShowOriginal(meRedlineFlags))
{
- pNewRedl->InvalidateRange(SwRangeRedline::Invalidation::Add);
+ if( bCallDelete && RedlineType::Delete == pNewRedl->GetType() )
+ {
+ RedlineFlags eOld = meRedlineFlags;
+ // Set to NONE, so that the Delete::Redo merges the Redline data correctly!
+ // The ShowMode needs to be retained!
+ meRedlineFlags = eOld & ~RedlineFlags(RedlineFlags::On | RedlineFlags::Ignore);
+ m_rDoc.getIDocumentContentOperations().DeleteAndJoin( *pNewRedl );
+ meRedlineFlags = eOld;
+ }
+ delete pNewRedl;
+ pNewRedl = nullptr;
+ CHECK_REDLINE( *this )
+ return AppendResult::IGNORED;
+ }
- if( m_rDoc.IsAutoFormatRedline() )
+ // Collect MoveID's of the redlines we delete.
+ // If there is only 1, then we should use its ID. (continuing the move)
+ std::set<sal_uInt32> deletedMoveIDs;
+
+ bool bMerged = false;
+
+ pNewRedl->InvalidateRange(SwRangeRedline::Invalidation::Add);
+
+ if( m_rDoc.IsAutoFormatRedline() )
+ {
+ pNewRedl->SetAutoFormat();
+ if( moAutoFormatRedlnComment && !moAutoFormatRedlnComment->isEmpty() )
{
- pNewRedl->SetAutoFormat();
- if( mpAutoFormatRedlnComment && !mpAutoFormatRedlnComment->isEmpty() )
- {
- pNewRedl->SetComment( *mpAutoFormatRedlnComment );
- pNewRedl->SetSeqNo( mnAutoFormatRedlnCommentNo );
- }
+ pNewRedl->SetComment( *moAutoFormatRedlnComment );
+ pNewRedl->SetSeqNo( mnAutoFormatRedlnCommentNo );
}
+ }
- SwPosition* pStt = pNewRedl->Start(),
- * pEnd = pStt == pNewRedl->GetPoint() ? pNewRedl->GetMark()
- : pNewRedl->GetPoint();
+ auto [pStt, pEnd] = pNewRedl->StartEnd(); // SwPosition*
+ {
+ SwTextNode* pTextNode = pStt->GetNode().GetTextNode();
+ if( pTextNode == nullptr )
{
- SwTextNode* pTextNode = pStt->nNode.GetNode().GetTextNode();
- if( pTextNode == nullptr )
+ if( pStt->GetContentIndex() > 0 )
{
- if( pStt->nContent > 0 )
- {
- OSL_ENSURE( false, "Redline start: non-text-node with content" );
- pStt->nContent = 0;
- }
+ OSL_ENSURE( false, "Redline start: non-text-node with content" );
+ pStt->SetContent( 0 );
}
- else
+ }
+ else
+ {
+ if( pStt->GetContentIndex() > pTextNode->Len() )
{
- if( pStt->nContent > pTextNode->Len() )
- {
- OSL_ENSURE( false, "Redline start: index after text" );
- pStt->nContent = pTextNode->Len();
- }
+ OSL_ENSURE( false, "Redline start: index after text" );
+ pStt->SetContent( pTextNode->Len() );
}
- pTextNode = pEnd->nNode.GetNode().GetTextNode();
- if( pTextNode == nullptr )
+ }
+ pTextNode = pEnd->GetNode().GetTextNode();
+ if( pTextNode == nullptr )
+ {
+ if( pEnd->GetContentIndex() > 0 )
{
- if( pEnd->nContent > 0 )
- {
- OSL_ENSURE( false, "Redline end: non-text-node with content" );
- pEnd->nContent = 0;
- }
+ OSL_ENSURE( false, "Redline end: non-text-node with content" );
+ pEnd->SetContent(0);
}
- else
+ }
+ else
+ {
+ if( pEnd->GetContentIndex() > pTextNode->Len() )
{
- if( pEnd->nContent > pTextNode->Len() )
- {
- OSL_ENSURE( false, "Redline end: index after text" );
- pEnd->nContent = pTextNode->Len();
- }
+ OSL_ENSURE( false, "Redline end: index after text" );
+ pEnd->SetContent( pTextNode->Len() );
}
}
- if( ( *pStt == *pEnd ) &&
- ( pNewRedl->GetContentIdx() == nullptr ) )
- { // Do not insert empty redlines
- delete pNewRedl;
- return AppendResult::IGNORED;
- }
- bool bCompress = false;
- SwRedlineTable::size_type n = 0;
- // look up the first Redline for the starting position
- if( !GetRedline( *pStt, &n ) && n )
- --n;
- bool bDec = false;
+ }
+ if( ( *pStt == *pEnd ) &&
+ ( pNewRedl->GetContentIdx() == nullptr ) )
+ { // Do not insert empty redlines
+ delete pNewRedl;
+ return AppendResult::IGNORED;
+ }
+ bool bCompress = false;
+ SwRedlineTable::size_type n = 0;
+ // look up the first Redline for the starting position
+ if( !GetRedline( *pStt, &n ) && n )
+ --n;
+ const SwRedlineTable::size_type nStartPos = n;
+ bool bDec = false;
- for( ; pNewRedl && n < mpRedlineTable->size(); bDec ? n : ++n )
- {
- bDec = false;
+ for( ; pNewRedl && n < maRedlineTable.size(); bDec ? n : ++n )
+ {
+ bDec = false;
- SwRangeRedline* pRedl = (*mpRedlineTable)[ n ];
- SwPosition* pRStt = pRedl->Start(),
- * pREnd = pRStt == pRedl->GetPoint() ? pRedl->GetMark()
- : pRedl->GetPoint();
+ SwRangeRedline* pRedl = maRedlineTable[ n ];
+ auto [pRStt, pREnd] = pRedl->StartEnd();
- // #i8518# remove empty redlines while we're at it
- if( ( *pRStt == *pREnd ) &&
- ( pRedl->GetContentIdx() == nullptr ) )
- {
- mpRedlineTable->DeleteAndDestroy(n);
- continue;
- }
+ // #i8518# remove empty redlines while we're at it
+ if( ( *pRStt == *pREnd ) &&
+ ( pRedl->GetContentIdx() == nullptr ) )
+ {
+ maRedlineTable.DeleteAndDestroy(n);
+ continue;
+ }
- SwComparePosition eCmpPos = ComparePosition( *pStt, *pEnd, *pRStt, *pREnd );
+ SwComparePosition eCmpPos = ComparePosition( *pStt, *pEnd, *pRStt, *pREnd );
- switch( pNewRedl->GetType() )
+ if ( SwComparePosition::Before == eCmpPos && !IsPrevPos( *pEnd, *pRStt ))
+ break;
+
+ switch( pNewRedl->GetType() )
+ {
+ case RedlineType::Insert:
+ switch( pRedl->GetType() )
{
case RedlineType::Insert:
- switch( pRedl->GetType() )
+ if( pRedl->IsOwnRedline( *pNewRedl ) &&
+ // don't join inserted characters with moved text
+ !pRedl->IsMoved() )
{
- case RedlineType::Insert:
- if( pRedl->IsOwnRedline( *pNewRedl ) )
- {
- bool bDelete = false;
-
- // Merge if applicable?
- if( (( SwComparePosition::Behind == eCmpPos &&
- IsPrevPos( *pREnd, *pStt ) ) ||
- ( SwComparePosition::CollideStart == eCmpPos ) ||
- ( SwComparePosition::OverlapBehind == eCmpPos ) ) &&
- pRedl->CanCombine( *pNewRedl ) &&
- ( n+1 >= mpRedlineTable->size() ||
- ( *(*mpRedlineTable)[ n+1 ]->Start() >= *pEnd &&
- *(*mpRedlineTable)[ n+1 ]->Start() != *pREnd ) ) )
- {
- pRedl->SetEnd( *pEnd, pREnd );
- if( !pRedl->HasValidRange() )
- {
- // re-insert
- mpRedlineTable->Remove( n );
- mpRedlineTable->Insert( pRedl );
- }
-
- bMerged = true;
- bDelete = true;
- }
- else if( (( SwComparePosition::Before == eCmpPos &&
- IsPrevPos( *pEnd, *pRStt ) ) ||
- ( SwComparePosition::CollideEnd == eCmpPos ) ||
- ( SwComparePosition::OverlapBefore == eCmpPos ) ) &&
- pRedl->CanCombine( *pNewRedl ) &&
- ( !n ||
- *(*mpRedlineTable)[ n-1 ]->End() != *pRStt ))
+ bool bDelete = false;
+ bool bMaybeNotify = false;
+
+ // Merge if applicable?
+ if( (( SwComparePosition::Behind == eCmpPos &&
+ IsPrevPos( *pREnd, *pStt ) ) ||
+ ( SwComparePosition::CollideStart == eCmpPos ) ||
+ ( SwComparePosition::OverlapBehind == eCmpPos ) ) &&
+ pRedl->CanCombine( *pNewRedl ) &&
+ ( n+1 >= maRedlineTable.size() ||
+ ( *maRedlineTable[ n+1 ]->Start() >= *pEnd &&
+ *maRedlineTable[ n+1 ]->Start() != *pREnd ) ) )
+ {
+ pRedl->SetEnd( *pEnd, pREnd );
+ if( !pRedl->HasValidRange() )
{
- pRedl->SetStart( *pStt, pRStt );
// re-insert
- mpRedlineTable->Remove( n );
- mpRedlineTable->Insert( pRedl );
-
- bMerged = true;
- bDelete = true;
+ maRedlineTable.Remove( n );
+ maRedlineTable.Insert( pRedl );
}
- else if ( SwComparePosition::Outside == eCmpPos )
- {
- // own insert-over-insert redlines:
- // just scrap the inside ones
- mpRedlineTable->DeleteAndDestroy( n );
- bDec = true;
- }
- else if( SwComparePosition::OverlapBehind == eCmpPos )
- {
- *pStt = *pREnd;
- if( ( *pStt == *pEnd ) &&
- ( pNewRedl->GetContentIdx() == nullptr ) )
- bDelete = true;
- }
- else if( SwComparePosition::OverlapBefore == eCmpPos )
- {
- *pEnd = *pRStt;
- if( ( *pStt == *pEnd ) &&
- ( pNewRedl->GetContentIdx() == nullptr ) )
- bDelete = true;
- }
- else if( SwComparePosition::Inside == eCmpPos )
- {
- bDelete = true;
- bMerged = true;
- }
- else if( SwComparePosition::Equal == eCmpPos )
- bDelete = true;
- if( bDelete )
- {
- delete pNewRedl;
- pNewRedl = nullptr;
- bCompress = true;
- }
+ bMerged = true;
+ bDelete = true;
}
- else if( SwComparePosition::Inside == eCmpPos )
+ else if( (( SwComparePosition::Before == eCmpPos &&
+ IsPrevPos( *pEnd, *pRStt ) ) ||
+ ( SwComparePosition::CollideEnd == eCmpPos ) ||
+ ( SwComparePosition::OverlapBefore == eCmpPos ) ) &&
+ pRedl->CanCombine( *pNewRedl ) &&
+ ( !n ||
+ *maRedlineTable[ n-1 ]->End() != *pRStt ))
{
- // split up
- if( *pEnd != *pREnd )
- {
- SwRangeRedline* pCpy = new SwRangeRedline( *pRedl );
- pCpy->SetStart( *pEnd );
- mpRedlineTable->Insert( pCpy );
- }
- pRedl->SetEnd( *pStt, pREnd );
- if( ( *pStt == *pRStt ) &&
- ( pRedl->GetContentIdx() == nullptr ) )
- {
- mpRedlineTable->DeleteAndDestroy( n );
- bDec = true;
- }
- else if( !pRedl->HasValidRange() )
- {
- // re-insert
- mpRedlineTable->Remove( n );
- mpRedlineTable->Insert( pRedl );
- }
+ pRedl->SetStart( *pStt, pRStt );
+ // re-insert
+ maRedlineTable.Remove( n );
+ maRedlineTable.Insert( pRedl );
+
+ bMerged = true;
+ bDelete = true;
}
else if ( SwComparePosition::Outside == eCmpPos )
{
- // handle overlapping redlines in broken documents
-
- // split up the new redline, since it covers the
- // existing redline. Insert the first part, and
- // progress with the remainder as usual
- SwRangeRedline* pSplit = new SwRangeRedline( *pNewRedl );
- pSplit->SetEnd( *pRStt );
- pNewRedl->SetStart( *pREnd );
- mpRedlineTable->Insert( pSplit );
- if( *pStt == *pEnd && pNewRedl->GetContentIdx() == nullptr )
- {
- delete pNewRedl;
- pNewRedl = nullptr;
- bCompress = true;
- }
+ // own insert-over-insert redlines:
+ // just scrap the inside ones
+ maRedlineTable.DeleteAndDestroy( n );
+ bDec = true;
}
- else if ( SwComparePosition::OverlapBehind == eCmpPos )
+ else if( SwComparePosition::OverlapBehind == eCmpPos )
{
- // handle overlapping redlines in broken documents
- pNewRedl->SetStart( *pREnd );
+ *pStt = *pREnd;
+ if( ( *pStt == *pEnd ) &&
+ ( pNewRedl->GetContentIdx() == nullptr ) )
+ bDelete = bMaybeNotify = true;
}
- else if ( SwComparePosition::OverlapBefore == eCmpPos )
+ else if( SwComparePosition::OverlapBefore == eCmpPos )
{
- // handle overlapping redlines in broken documents
*pEnd = *pRStt;
if( ( *pStt == *pEnd ) &&
( pNewRedl->GetContentIdx() == nullptr ) )
- {
- delete pNewRedl;
- pNewRedl = nullptr;
- bCompress = true;
- }
+ bDelete = bMaybeNotify = true;
+ }
+ else if( SwComparePosition::Inside == eCmpPos )
+ {
+ bDelete = bMaybeNotify = true;
+ bMerged = true;
+ }
+ else if( SwComparePosition::Equal == eCmpPos )
+ bDelete = bMaybeNotify = true;
+
+ if( bDelete )
+ {
+ delete pNewRedl;
+ pNewRedl = nullptr;
+ bCompress = true;
+
+ if (bMaybeNotify)
+ MaybeNotifyRedlineModification(*pRedl, m_rDoc);
+
+ // set IsMoved checking nearby redlines
+ if (n < maRedlineTable.size()) // in case above 're-insert' failed
+ maRedlineTable.isMoved(n);
+ }
+ }
+ else if( SwComparePosition::Inside == eCmpPos )
+ {
+ // split up
+ if( *pEnd != *pREnd )
+ {
+ SwRangeRedline* pCpy = new SwRangeRedline( *pRedl );
+ pCpy->SetStart( *pEnd );
+ maRedlineTable.Insert( pCpy );
+ }
+ pRedl->SetEnd( *pStt, pREnd );
+ if( ( *pStt == *pRStt ) &&
+ ( pRedl->GetContentIdx() == nullptr ) )
+ {
+ maRedlineTable.DeleteAndDestroy( n );
+ bDec = true;
+ }
+ else if( !pRedl->HasValidRange() )
+ {
+ // re-insert
+ maRedlineTable.Remove( n );
+ maRedlineTable.Insert( pRedl );
+ }
+ }
+ else if ( SwComparePosition::Outside == eCmpPos )
+ {
+ // handle overlapping redlines in broken documents
+
+ // split up the new redline, since it covers the
+ // existing redline. Insert the first part, and
+ // progress with the remainder as usual
+ SwRangeRedline* pSplit = new SwRangeRedline( *pNewRedl );
+ pSplit->SetEnd( *pRStt );
+ pNewRedl->SetStart( *pREnd );
+ maRedlineTable.Insert( pSplit );
+ if( *pStt == *pEnd && pNewRedl->GetContentIdx() == nullptr )
+ {
+ delete pNewRedl;
+ pNewRedl = nullptr;
+ bCompress = true;
+ }
+ }
+ else if ( SwComparePosition::OverlapBehind == eCmpPos )
+ {
+ // handle overlapping redlines in broken documents
+ pNewRedl->SetStart( *pREnd );
+ }
+ else if ( SwComparePosition::OverlapBefore == eCmpPos )
+ {
+ // handle overlapping redlines in broken documents
+ *pEnd = *pRStt;
+ if( ( *pStt == *pEnd ) &&
+ ( pNewRedl->GetContentIdx() == nullptr ) )
+ {
+ delete pNewRedl;
+ pNewRedl = nullptr;
+ bCompress = true;
+
+ MaybeNotifyRedlineModification(*pRedl, m_rDoc);
+ }
+ }
+ break;
+ case RedlineType::Delete:
+ if( SwComparePosition::Inside == eCmpPos )
+ {
+ // split up
+ if( *pEnd != *pREnd )
+ {
+ SwRangeRedline* pCpy = new SwRangeRedline( *pRedl );
+ pCpy->SetStart( *pEnd );
+ maRedlineTable.Insert( pCpy );
+ }
+ pRedl->SetEnd( *pStt, pREnd );
+ if( ( *pStt == *pRStt ) &&
+ ( pRedl->GetContentIdx() == nullptr ) )
+ {
+ maRedlineTable.DeleteAndDestroy( n );
+ bDec = true;
+ }
+ else if( !pRedl->HasValidRange() )
+ {
+ // re-insert
+ maRedlineTable.Remove( n );
+ maRedlineTable.Insert( pRedl, n );
+ }
+ }
+ else if ( SwComparePosition::Outside == eCmpPos )
+ {
+ // handle overlapping redlines in broken documents
+
+ // split up the new redline, since it covers the
+ // existing redline. Insert the first part, and
+ // progress with the remainder as usual
+ SwRangeRedline* pSplit = new SwRangeRedline( *pNewRedl );
+ pSplit->SetEnd( *pRStt );
+ pNewRedl->SetStart( *pREnd );
+ maRedlineTable.Insert( pSplit );
+ if( *pStt == *pEnd && pNewRedl->GetContentIdx() == nullptr )
+ {
+ delete pNewRedl;
+ pNewRedl = nullptr;
+ bCompress = true;
+ }
+ }
+ else if ( SwComparePosition::Equal == eCmpPos )
+ {
+ // handle identical redlines in broken documents
+ // delete old (delete) redline
+ maRedlineTable.DeleteAndDestroy( n );
+ bDec = true;
+ }
+ else if ( SwComparePosition::OverlapBehind == eCmpPos )
+ { // Another workaround for broken redlines
+ pNewRedl->SetStart( *pREnd );
+ }
+ break;
+ case RedlineType::Format:
+ switch( eCmpPos )
+ {
+ case SwComparePosition::OverlapBefore:
+ pRedl->SetStart( *pEnd, pRStt );
+ // re-insert
+ maRedlineTable.Remove( n );
+ maRedlineTable.Insert( pRedl, n );
+ bDec = true;
+ break;
+
+ case SwComparePosition::OverlapBehind:
+ pRedl->SetEnd( *pStt, pREnd );
+ if( *pStt == *pRStt && pRedl->GetContentIdx() == nullptr )
+ {
+ maRedlineTable.DeleteAndDestroy( n );
+ bDec = true;
}
break;
- case RedlineType::Delete:
- if( SwComparePosition::Inside == eCmpPos )
+
+ case SwComparePosition::Equal:
+ case SwComparePosition::Outside:
+ // Overlaps the current one completely or has the
+ // same dimension, delete the old one
+ maRedlineTable.DeleteAndDestroy( n );
+ bDec = true;
+ break;
+
+ case SwComparePosition::Inside:
+ // Overlaps the current one completely,
+ // split or shorten the new one
+ if( *pEnd != *pREnd )
{
- // split up
- if( *pEnd != *pREnd )
+ if( *pEnd != *pRStt )
{
- SwRangeRedline* pCpy = new SwRangeRedline( *pRedl );
- pCpy->SetStart( *pEnd );
- mpRedlineTable->Insert( pCpy );
+ SwRangeRedline* pNew = new SwRangeRedline( *pRedl );
+ pNew->SetStart( *pEnd );
+ pRedl->SetEnd( *pStt, pREnd );
+ if( *pStt == *pRStt && pRedl->GetContentIdx() == nullptr )
+ maRedlineTable.DeleteAndDestroy( n );
+ AppendRedline( pNew, bCallDelete );
+ n = 0; // re-initialize
+ bDec = true;
}
+ }
+ else
pRedl->SetEnd( *pStt, pREnd );
- if( ( *pStt == *pRStt ) &&
- ( pRedl->GetContentIdx() == nullptr ) )
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case RedlineType::Delete:
+ switch( pRedl->GetType() )
+ {
+ case RedlineType::Delete:
+ switch( eCmpPos )
+ {
+ case SwComparePosition::Outside:
+ {
+ // Overlaps the current one completely,
+ // split the new one
+ if (*pEnd == *pREnd)
{
- mpRedlineTable->DeleteAndDestroy( n );
- bDec = true;
+ pNewRedl->SetEnd(*pRStt, pEnd);
}
- else if( !pRedl->HasValidRange() )
+ else if (*pStt == *pRStt)
{
- // re-insert
- mpRedlineTable->Remove( n );
- mpRedlineTable->Insert( pRedl, n );
+ pNewRedl->SetStart(*pREnd, pStt);
}
- }
- else if ( SwComparePosition::Outside == eCmpPos )
- {
- // handle overlapping redlines in broken documents
-
- // split up the new redline, since it covers the
- // existing redline. Insert the first part, and
- // progress with the remainder as usual
- SwRangeRedline* pSplit = new SwRangeRedline( *pNewRedl );
- pSplit->SetEnd( *pRStt );
- pNewRedl->SetStart( *pREnd );
- mpRedlineTable->Insert( pSplit );
- if( *pStt == *pEnd && pNewRedl->GetContentIdx() == nullptr )
+ else
{
- delete pNewRedl;
- pNewRedl = nullptr;
- bCompress = true;
+ SwRangeRedline* pNew = new SwRangeRedline( *pNewRedl );
+ pNew->SetStart( *pREnd );
+ pNewRedl->SetEnd( *pRStt, pEnd );
+ AppendRedline( pNew, bCallDelete );
+ n = 0; // re-initialize
+ bDec = true;
}
}
- else if ( SwComparePosition::Equal == eCmpPos )
+ break;
+
+ case SwComparePosition::Inside:
+ case SwComparePosition::Equal:
+ delete pNewRedl;
+ pNewRedl = nullptr;
+ bCompress = true;
+
+ MaybeNotifyRedlineModification(*pRedl, m_rDoc);
+ break;
+
+ case SwComparePosition::OverlapBefore:
+ case SwComparePosition::OverlapBehind:
+ if( pRedl->IsOwnRedline( *pNewRedl ) &&
+ pRedl->CanCombine( *pNewRedl ))
{
- // handle identical redlines in broken documents
- // delete old (delete) redline
- mpRedlineTable->DeleteAndDestroy( n );
+ // If that's the case we can merge it, meaning
+ // the new one covers this well
+ if( SwComparePosition::OverlapBehind == eCmpPos )
+ pNewRedl->SetStart( *pRStt, pStt );
+ else
+ pNewRedl->SetEnd( *pREnd, pEnd );
+ maRedlineTable.DeleteAndDestroy( n );
bDec = true;
}
- else if ( SwComparePosition::OverlapBehind == eCmpPos )
- { // Another workaround for broken redlines
- pNewRedl->SetStart( *pREnd );
- }
+ else if( SwComparePosition::OverlapBehind == eCmpPos )
+ pNewRedl->SetStart( *pREnd, pStt );
+ else
+ pNewRedl->SetEnd( *pRStt, pEnd );
break;
- case RedlineType::Format:
- switch( eCmpPos )
- {
- case SwComparePosition::OverlapBefore:
- pRedl->SetStart( *pEnd, pRStt );
- // re-insert
- mpRedlineTable->Remove( n );
- mpRedlineTable->Insert( pRedl, n );
- bDec = true;
- break;
- case SwComparePosition::OverlapBehind:
- pRedl->SetEnd( *pStt, pREnd );
- if( *pStt == *pRStt && pRedl->GetContentIdx() == nullptr )
+ case SwComparePosition::CollideEnd:
+ if (pRStt->GetContentIndex() != 0
+ && pRStt->GetNode() != pREnd->GetNode())
+ { // tdf#147466 HACK: don't combine in this case to avoid the tdf#119571 code from *undeleting* section nodes
+ break;
+ }
+ [[fallthrough]];
+ case SwComparePosition::CollideStart:
+ if( pRedl->IsOwnRedline( *pNewRedl ) &&
+ pRedl->CanCombine( *pNewRedl ) )
+ {
+ if( IsHideChanges( meRedlineFlags ))
{
- mpRedlineTable->DeleteAndDestroy( n );
- bDec = true;
+ // Before we can merge, we make it visible!
+ // We insert temporarily so that pNew is
+ // also dealt with when moving the indices.
+ maRedlineTable.Insert(pNewRedl);
+ pRedl->Show(0, maRedlineTable.GetPos(pRedl));
+ maRedlineTable.Remove( pNewRedl );
+ pRStt = pRedl->Start();
+ pREnd = pRedl->End();
}
- break;
- case SwComparePosition::Equal:
- case SwComparePosition::Outside:
- // Overlaps the current one completely or has the
- // same dimension, delete the old one
- mpRedlineTable->DeleteAndDestroy( n );
+ // If that's the case we can merge it, meaning
+ // the new one covers this well
+ if( SwComparePosition::CollideStart == eCmpPos )
+ pNewRedl->SetStart( *pRStt, pStt );
+ else
+ pNewRedl->SetEnd( *pREnd, pEnd );
+
+ // delete current (below), and restart process with
+ // previous
+ SwRedlineTable::size_type nToBeDeleted = n;
bDec = true;
- break;
- case SwComparePosition::Inside:
- // Overlaps the current one completely,
- // split or shorten the new one
- if( *pEnd != *pREnd )
+ if( *(pNewRedl->Start()) <= *pREnd )
{
- if( *pEnd != *pRStt )
- {
- SwRangeRedline* pNew = new SwRangeRedline( *pRedl );
- pNew->SetStart( *pEnd );
- pRedl->SetEnd( *pStt, pREnd );
- if( *pStt == *pRStt && pRedl->GetContentIdx() == nullptr )
- mpRedlineTable->DeleteAndDestroy( n );
- AppendRedline( pNew, bCallDelete );
- n = 0; // re-initialize
- bDec = true;
- }
+ // Whoooah, we just extended the new 'redline'
+ // beyond previous redlines, so better start
+ // again. Of course this is not supposed to
+ // happen, and in an ideal world it doesn't,
+ // but unfortunately this code is buggy and
+ // totally rotten so it does happen and we
+ // better fix it.
+ n = 0;
+ bDec = true;
}
- else
- pRedl->SetEnd( *pStt, pREnd );
- break;
- default:
- break;
+
+ maRedlineTable.DeleteAndDestroy( nToBeDeleted );
}
break;
default:
@@ -1510,699 +1808,661 @@ DocumentRedlineManager::AppendRedline(SwRangeRedline* pNewRedl, bool const bCall
}
break;
- case RedlineType::Delete:
- switch( pRedl->GetType() )
+ case RedlineType::Insert:
+ {
+ // b62341295: Do not throw away redlines
+ // even if they are not allowed to be combined
+ RedlineFlags eOld = meRedlineFlags;
+ if( !( eOld & RedlineFlags::DontCombineRedlines ) &&
+ pRedl->IsOwnRedline( *pNewRedl ) &&
+ // tdf#116084 tdf#121176 don't combine anonymized deletion
+ // and anonymized insertion, i.e. with the same dummy timestamp
+ !pRedl->GetRedlineData(0).IsAnonymized() )
{
- case RedlineType::Delete:
+ // Collect MoveID's of the redlines we delete.
+ if (nMoveIDToDelete > 1 && maRedlineTable[n]->GetMoved() > 0
+ && (eCmpPos == SwComparePosition::Equal
+ || eCmpPos == SwComparePosition::Inside
+ || eCmpPos == SwComparePosition::Outside
+ || eCmpPos == SwComparePosition::OverlapBefore
+ || eCmpPos == SwComparePosition::OverlapBehind))
+ {
+ deletedMoveIDs.insert(maRedlineTable[n]->GetMoved());
+ }
+
+ // Set to NONE, so that the Delete::Redo merges the Redline data correctly!
+ // The ShowMode needs to be retained!
+ meRedlineFlags = eOld & ~RedlineFlags(RedlineFlags::On | RedlineFlags::Ignore);
switch( eCmpPos )
{
- case SwComparePosition::Outside:
+ case SwComparePosition::Equal:
+ bCompress = true;
+ maRedlineTable.DeleteAndDestroy( n );
+ bDec = true;
+ [[fallthrough]];
+
+ case SwComparePosition::Inside:
+ if( bCallDelete )
{
- // Overlaps the current one completely,
- // split the new one
- if (*pEnd == *pREnd)
- {
- pNewRedl->SetEnd(*pRStt, pEnd);
- }
- else if (*pStt == *pRStt)
+ // DeleteAndJoin does not yield the
+ // desired result if there is no paragraph to
+ // join with, i.e. at the end of the document.
+ // For this case, we completely delete the
+ // paragraphs (if, of course, we also start on
+ // a paragraph boundary).
+ if( (pStt->GetContentIndex() == 0) &&
+ pEnd->GetNode().IsEndNode() )
{
- pNewRedl->SetStart(*pREnd, pStt);
+ pEnd->Adjust(SwNodeOffset(-1));
+ m_rDoc.getIDocumentContentOperations().DelFullPara( *pNewRedl );
}
else
+ m_rDoc.getIDocumentContentOperations().DeleteAndJoin( *pNewRedl );
+
+ bCompress = true;
+ }
+ delete pNewRedl;
+ pNewRedl = nullptr;
+
+ // No need to call MaybeNotifyRedlineModification, because a notification
+ // was already sent in DocumentRedlineManager::DeleteRedline
+ break;
+
+ case SwComparePosition::Outside:
+ {
+ maRedlineTable.Remove( n );
+ bDec = true;
+ if( bCallDelete )
{
- SwRangeRedline* pNew = new SwRangeRedline( *pNewRedl );
- pNew->SetStart( *pREnd );
- pNewRedl->SetEnd( *pRStt, pEnd );
- AppendRedline( pNew, bCallDelete );
+ TemporaryRedlineUpdater const u(m_rDoc, *pNewRedl);
+ m_rDoc.getIDocumentContentOperations().DeleteAndJoin( *pRedl );
n = 0; // re-initialize
- bDec = true;
}
+ delete pRedl;
}
break;
- case SwComparePosition::Inside:
- case SwComparePosition::Equal:
- delete pNewRedl;
- pNewRedl = nullptr;
- bCompress = true;
- break;
-
case SwComparePosition::OverlapBefore:
- case SwComparePosition::OverlapBehind:
- if( pRedl->IsOwnRedline( *pNewRedl ) &&
- pRedl->CanCombine( *pNewRedl ))
{
- // If that's the case we can merge it, meaning
- // the new one covers this well
- if( SwComparePosition::OverlapBehind == eCmpPos )
- pNewRedl->SetStart( *pRStt, pStt );
+ SwPaM aPam( *pRStt, *pEnd );
+
+ if( *pEnd == *pREnd )
+ maRedlineTable.DeleteAndDestroy( n );
else
- pNewRedl->SetEnd( *pREnd, pEnd );
- mpRedlineTable->DeleteAndDestroy( n );
+ {
+ pRedl->SetStart( *pEnd, pRStt );
+ // re-insert
+ maRedlineTable.Remove( n );
+ maRedlineTable.Insert( pRedl, n );
+ }
+
+ if( bCallDelete )
+ {
+ TemporaryRedlineUpdater const u(m_rDoc, *pNewRedl);
+ m_rDoc.getIDocumentContentOperations().DeleteAndJoin( aPam );
+ n = 0; // re-initialize
+ }
bDec = true;
}
- else if( SwComparePosition::OverlapBehind == eCmpPos )
- pNewRedl->SetStart( *pREnd, pStt );
- else
- pNewRedl->SetEnd( *pRStt, pEnd );
break;
- case SwComparePosition::CollideStart:
- case SwComparePosition::CollideEnd:
- if( pRedl->IsOwnRedline( *pNewRedl ) &&
- pRedl->CanCombine( *pNewRedl ) )
+ case SwComparePosition::OverlapBehind:
{
- if( IsHideChanges( meRedlineFlags ))
+ SwPaM aPam( *pStt, *pREnd );
+
+ if( *pStt == *pRStt )
{
- // Before we can merge, we make it visible!
- // We insert temporarily so that pNew is
- // also dealt with when moving the indices.
- mpRedlineTable->Insert(pNewRedl);
- pRedl->Show(0, mpRedlineTable->GetPos(pRedl));
- mpRedlineTable->Remove( pNewRedl );
- pRStt = pRedl->Start();
- pREnd = pRedl->End();
+ maRedlineTable.DeleteAndDestroy( n );
+ bDec = true;
}
-
- // If that's the case we can merge it, meaning
- // the new one covers this well
- if( SwComparePosition::CollideStart == eCmpPos )
- pNewRedl->SetStart( *pRStt, pStt );
else
- pNewRedl->SetEnd( *pREnd, pEnd );
-
- // delete current (below), and restart process with
- // previous
- SwRedlineTable::size_type nToBeDeleted = n;
- bDec = true;
+ pRedl->SetEnd( *pStt, pREnd );
- if( *(pNewRedl->Start()) <= *pREnd )
+ if( bCallDelete )
{
- // Whoooah, we just extended the new 'redline'
- // beyond previous redlines, so better start
- // again. Of course this is not supposed to
- // happen, and in an ideal world it doesn't,
- // but unfortunately this code is buggy and
- // totally rotten so it does happen and we
- // better fix it.
- n = 0;
+ TemporaryRedlineUpdater const u(m_rDoc, *pNewRedl);
+ m_rDoc.getIDocumentContentOperations().DeleteAndJoin( aPam );
+ n = 0; // re-initialize
bDec = true;
}
-
- mpRedlineTable->DeleteAndDestroy( nToBeDeleted );
}
break;
default:
break;
}
- break;
- case RedlineType::Insert:
+ meRedlineFlags = eOld;
+ }
+ else
{
- // b62341295: Do not throw away redlines
- // even if they are not allowed to be combined
- RedlineFlags eOld = meRedlineFlags;
- if( !( eOld & RedlineFlags::DontCombineRedlines ) &&
- pRedl->IsOwnRedline( *pNewRedl ) )
- {
+ // it may be necessary to split the existing redline in
+ // two. In this case, pRedl will be changed to cover
+ // only part of its former range, and pNew will cover
+ // the remainder.
+ SwRangeRedline* pNew = nullptr;
- // Set to NONE, so that the Delete::Redo merges the Redline data correctly!
- // The ShowMode needs to be retained!
- meRedlineFlags = eOld & ~RedlineFlags(RedlineFlags::On | RedlineFlags::Ignore);
- switch( eCmpPos )
+ switch( eCmpPos )
+ {
+ case SwComparePosition::Equal:
{
- case SwComparePosition::Equal:
- bCompress = true;
- mpRedlineTable->DeleteAndDestroy( n );
- bDec = true;
- [[fallthrough]];
-
- case SwComparePosition::Inside:
- if( bCallDelete )
- {
- // DeleteAndJoin does not yield the
- // desired result if there is no paragraph to
- // join with, i.e. at the end of the document.
- // For this case, we completely delete the
- // paragraphs (if, of course, we also start on
- // a paragraph boundary).
- if( (pStt->nContent == 0) &&
- pEnd->nNode.GetNode().IsEndNode() )
- {
- pEnd->nNode--;
- pEnd->nContent.Assign(
- pEnd->nNode.GetNode().GetTextNode(), 0);
- m_rDoc.getIDocumentContentOperations().DelFullPara( *pNewRedl );
- }
- else
- m_rDoc.getIDocumentContentOperations().DeleteAndJoin( *pNewRedl );
-
- bCompress = true;
- }
- if( !bCallDelete && !bDec && *pEnd == *pREnd )
- {
- m_rDoc.getIDocumentContentOperations().DeleteAndJoin( *pNewRedl );
- bCompress = true;
- }
- else if ( bCallDelete || !bDec )
+ pRedl->PushData( *pNewRedl );
+ delete pNewRedl;
+ pNewRedl = nullptr;
+ if( IsHideChanges( meRedlineFlags ))
{
- // delete new redline, except in some cases of fallthrough from previous
- // case ::Equal (eg. same portion w:del in w:ins in OOXML import)
- delete pNewRedl;
- pNewRedl = nullptr;
+ pRedl->Hide(0, maRedlineTable.GetPos(pRedl));
}
- break;
+ bCompress = true;
- case SwComparePosition::Outside:
- {
- mpRedlineTable->Remove( n );
- bDec = true;
- if( bCallDelete )
- {
- TemporaryRedlineUpdater const u(m_rDoc, *pNewRedl);
- m_rDoc.getIDocumentContentOperations().DeleteAndJoin( *pRedl );
- n = 0; // re-initialize
- }
- delete pRedl;
- }
- break;
+ // set IsMoved checking nearby redlines
+ SwRedlineTable::size_type nRIdx = maRedlineTable.GetPos(pRedl);
+ if (nRIdx < maRedlineTable.size()) // in case above 're-insert' failed
+ maRedlineTable.isMoved(nRIdx);
- case SwComparePosition::OverlapBefore:
- {
- SwPaM aPam( *pRStt, *pEnd );
+ }
+ break;
- if( *pEnd == *pREnd )
- mpRedlineTable->DeleteAndDestroy( n );
- else
+ case SwComparePosition::Inside:
+ {
+ if( *pRStt == *pStt )
+ {
+ // #i97421#
+ // redline w/out extent loops
+ if (*pStt != *pEnd)
{
+ pNewRedl->PushData( *pRedl, false );
pRedl->SetStart( *pEnd, pRStt );
// re-insert
- mpRedlineTable->Remove( n );
- mpRedlineTable->Insert( pRedl, n );
- }
-
- if( bCallDelete )
- {
- TemporaryRedlineUpdater const u(m_rDoc, *pNewRedl);
- m_rDoc.getIDocumentContentOperations().DeleteAndJoin( aPam );
- n = 0; // re-initialize
+ maRedlineTable.Remove( n );
+ maRedlineTable.Insert( pRedl, n );
+ bDec = true;
}
- bDec = true;
}
- break;
-
- case SwComparePosition::OverlapBehind:
+ else
{
- SwPaM aPam( *pStt, *pREnd );
-
- if( *pStt == *pRStt )
+ pNewRedl->PushData( *pRedl, false );
+ if( *pREnd != *pEnd )
{
- mpRedlineTable->DeleteAndDestroy( n );
- bDec = true;
+ pNew = new SwRangeRedline( *pRedl );
+ pNew->SetStart( *pEnd );
}
- else
- pRedl->SetEnd( *pStt, pREnd );
-
- if( bCallDelete )
+ pRedl->SetEnd( *pStt, pREnd );
+ if( !pRedl->HasValidRange() )
{
- TemporaryRedlineUpdater const u(m_rDoc, *pNewRedl);
- m_rDoc.getIDocumentContentOperations().DeleteAndJoin( aPam );
- n = 0; // re-initialize
- bDec = true;
+ // re-insert
+ maRedlineTable.Remove( n );
+ maRedlineTable.Insert( pRedl, n );
}
}
- break;
- default:
- break;
}
+ break;
- meRedlineFlags = eOld;
- }
- else
- {
- // it may be necessary to split the existing redline in
- // two. In this case, pRedl will be changed to cover
- // only part of its former range, and pNew will cover
- // the remainder.
- SwRangeRedline* pNew = nullptr;
+ case SwComparePosition::Outside:
+ {
+ pRedl->PushData( *pNewRedl );
+ if( *pEnd == *pREnd )
+ {
+ pNewRedl->SetEnd( *pRStt, pEnd );
+ }
+ else if (*pStt == *pRStt)
+ {
+ pNewRedl->SetStart(*pREnd, pStt);
+ }
+ else
+ {
+ pNew = new SwRangeRedline( *pNewRedl );
+ pNew->SetEnd( *pRStt );
+ pNewRedl->SetStart( *pREnd, pStt );
+ }
+ bCompress = true;
+ }
+ break;
- switch( eCmpPos )
+ case SwComparePosition::OverlapBefore:
{
- case SwComparePosition::Equal:
+ if( *pEnd == *pREnd )
{
pRedl->PushData( *pNewRedl );
- delete pNewRedl;
- pNewRedl = nullptr;
+ pNewRedl->SetEnd( *pRStt, pEnd );
if( IsHideChanges( meRedlineFlags ))
{
- pRedl->Hide(0, mpRedlineTable->GetPos(pRedl));
+ maRedlineTable.Insert(pNewRedl);
+ pRedl->Hide(0, maRedlineTable.GetPos(pRedl));
+ maRedlineTable.Remove( pNewRedl );
}
- bCompress = true;
}
- break;
-
- case SwComparePosition::Inside:
+ else
{
- if( *pRStt == *pStt )
- {
- // #i97421#
- // redline w/out extent loops
- if (*pStt != *pEnd)
- {
- pNewRedl->PushData( *pRedl, false );
- pRedl->SetStart( *pEnd, pRStt );
- // re-insert
- mpRedlineTable->Remove( n );
- mpRedlineTable->Insert( pRedl, n );
- bDec = true;
- }
- }
- else
- {
- pNewRedl->PushData( *pRedl, false );
- if( *pREnd != *pEnd )
- {
- pNew = new SwRangeRedline( *pRedl );
- pNew->SetStart( *pEnd );
- }
- pRedl->SetEnd( *pStt, pREnd );
- if( !pRedl->HasValidRange() )
- {
- // re-insert
- mpRedlineTable->Remove( n );
- mpRedlineTable->Insert( pRedl, n );
- }
- }
+ pNew = new SwRangeRedline( *pRedl );
+ pNew->PushData( *pNewRedl );
+ pNew->SetEnd( *pEnd );
+ pNewRedl->SetEnd( *pRStt, pEnd );
+ pRedl->SetStart( *pNew->End(), pRStt ) ;
+ // re-insert
+ maRedlineTable.Remove( n );
+ maRedlineTable.Insert( pRedl );
+ bDec = true;
}
- break;
+ }
+ break;
- case SwComparePosition::Outside:
+ case SwComparePosition::OverlapBehind:
+ {
+ if( *pStt == *pRStt )
{
pRedl->PushData( *pNewRedl );
- if( *pEnd == *pREnd )
- {
- pNewRedl->SetEnd( *pRStt, pEnd );
- }
- else if (*pStt == *pRStt)
- {
- pNewRedl->SetStart(*pREnd, pStt);
- }
- else
+ pNewRedl->SetStart( *pREnd, pStt );
+ if( IsHideChanges( meRedlineFlags ))
{
- pNew = new SwRangeRedline( *pNewRedl );
- pNew->SetEnd( *pRStt );
- pNewRedl->SetStart( *pREnd, pStt );
+ maRedlineTable.Insert( pNewRedl );
+ pRedl->Hide(0, maRedlineTable.GetPos(pRedl));
+ maRedlineTable.Remove( pNewRedl );
}
- bCompress = true;
}
- break;
-
- case SwComparePosition::OverlapBefore:
+ else
{
- if( *pEnd == *pREnd )
- {
- pRedl->PushData( *pNewRedl );
- pNewRedl->SetEnd( *pRStt, pEnd );
- if( IsHideChanges( meRedlineFlags ))
- {
- mpRedlineTable->Insert(pNewRedl);
- pRedl->Hide(0, mpRedlineTable->GetPos(pRedl));
- mpRedlineTable->Remove( pNewRedl );
- }
- }
- else
+ pNew = new SwRangeRedline( *pRedl );
+ pNew->PushData( *pNewRedl );
+ pNew->SetStart( *pStt );
+ pNewRedl->SetStart( *pREnd, pStt );
+ pRedl->SetEnd( *pNew->Start(), pREnd );
+ if( !pRedl->HasValidRange() )
{
- pNew = new SwRangeRedline( *pRedl );
- pNew->PushData( *pNewRedl );
- pNew->SetEnd( *pEnd );
- pNewRedl->SetEnd( *pRStt, pEnd );
- pRedl->SetStart( *pNew->End(), pRStt ) ;
// re-insert
- mpRedlineTable->Remove( n );
- mpRedlineTable->Insert( pRedl );
- bDec = true;
- }
- }
- break;
-
- case SwComparePosition::OverlapBehind:
- {
- if( *pStt == *pRStt )
- {
- pRedl->PushData( *pNewRedl );
- pNewRedl->SetStart( *pREnd, pStt );
- if( IsHideChanges( meRedlineFlags ))
- {
- mpRedlineTable->Insert( pNewRedl );
- pRedl->Hide(0, mpRedlineTable->GetPos(pRedl));
- mpRedlineTable->Remove( pNewRedl );
- }
- }
- else
- {
- pNew = new SwRangeRedline( *pRedl );
- pNew->PushData( *pNewRedl );
- pNew->SetStart( *pStt );
- pNewRedl->SetStart( *pREnd, pStt );
- pRedl->SetEnd( *pNew->Start(), pREnd );
- if( !pRedl->HasValidRange() )
- {
- // re-insert
- mpRedlineTable->Remove( n );
- mpRedlineTable->Insert( pRedl );
- }
+ maRedlineTable.Remove( n );
+ maRedlineTable.Insert( pRedl );
}
}
- break;
- default:
- break;
}
+ break;
+ default:
+ break;
+ }
- // insert the pNew part (if it exists)
- if( pNew )
- {
- mpRedlineTable->Insert( pNew );
+ // insert the pNew part (if it exists)
+ if( pNew )
+ {
+ maRedlineTable.Insert( pNew );
- // pNew must be deleted if Insert() wasn't
- // successful. But that can't happen, since pNew is
- // part of the original pRedl redline.
- // OSL_ENSURE( bRet, "Can't insert existing redline?" );
+ // pNew must be deleted if Insert() wasn't
+ // successful. But that can't happen, since pNew is
+ // part of the original pRedl redline.
+ // OSL_ENSURE( bRet, "Can't insert existing redline?" );
- // restart (now with pRedl being split up)
- n = 0;
- bDec = true;
- }
+ // restart (now with pRedl being split up)
+ n = 0;
+ bDec = true;
}
}
- break;
+ }
+ break;
- case RedlineType::Format:
- switch( eCmpPos )
- {
- case SwComparePosition::OverlapBefore:
- pRedl->SetStart( *pEnd, pRStt );
- // re-insert
- mpRedlineTable->Remove( n );
- mpRedlineTable->Insert( pRedl, n );
- bDec = true;
- break;
+ case RedlineType::Format:
+ switch( eCmpPos )
+ {
+ case SwComparePosition::OverlapBefore:
+ pRedl->SetStart( *pEnd, pRStt );
+ // re-insert
+ maRedlineTable.Remove( n );
+ maRedlineTable.Insert( pRedl, n );
+ bDec = true;
+ break;
- case SwComparePosition::OverlapBehind:
- pRedl->SetEnd( *pStt, pREnd );
- break;
+ case SwComparePosition::OverlapBehind:
+ pRedl->SetEnd( *pStt, pREnd );
+ break;
- case SwComparePosition::Equal:
- case SwComparePosition::Outside:
- // Overlaps the current one completely or has the
- // same dimension, delete the old one
- mpRedlineTable->DeleteAndDestroy( n );
- bDec = true;
- break;
+ case SwComparePosition::Equal:
+ case SwComparePosition::Outside:
+ // Overlaps the current one completely or has the
+ // same dimension, delete the old one
+ maRedlineTable.DeleteAndDestroy( n );
+ bDec = true;
+ break;
- case SwComparePosition::Inside:
- // Overlaps the current one completely,
- // split or shorten the new one
- if( *pEnd != *pREnd )
+ case SwComparePosition::Inside:
+ // Overlaps the current one completely,
+ // split or shorten the new one
+ if( *pEnd != *pREnd )
+ {
+ if( *pEnd != *pRStt )
{
- if( *pEnd != *pRStt )
- {
- SwRangeRedline* pNew = new SwRangeRedline( *pRedl );
- pNew->SetStart( *pEnd );
- pRedl->SetEnd( *pStt, pREnd );
- if( ( *pStt == *pRStt ) &&
- ( pRedl->GetContentIdx() == nullptr ) )
- mpRedlineTable->DeleteAndDestroy( n );
- AppendRedline( pNew, bCallDelete );
- n = 0; // re-initialize
- bDec = true;
- }
- }
- else
+ SwRangeRedline* pNew = new SwRangeRedline( *pRedl );
+ pNew->SetStart( *pEnd );
pRedl->SetEnd( *pStt, pREnd );
- break;
- default:
- break;
+ if( ( *pStt == *pRStt ) &&
+ ( pRedl->GetContentIdx() == nullptr ) )
+ maRedlineTable.DeleteAndDestroy( n );
+ AppendRedline( pNew, bCallDelete );
+ n = 0; // re-initialize
+ bDec = true;
+ }
}
+ else
+ pRedl->SetEnd( *pStt, pREnd );
break;
default:
break;
}
break;
+ default:
+ break;
+ }
+ break;
- case RedlineType::Format:
- switch( pRedl->GetType() )
+ case RedlineType::Format:
+ switch( pRedl->GetType() )
+ {
+ case RedlineType::Insert:
+ case RedlineType::Delete:
+ switch( eCmpPos )
{
- case RedlineType::Insert:
- case RedlineType::Delete:
- switch( eCmpPos )
+ case SwComparePosition::OverlapBefore:
+ pNewRedl->SetEnd( *pRStt, pEnd );
+ break;
+
+ case SwComparePosition::OverlapBehind:
+ pNewRedl->SetStart( *pREnd, pStt );
+ break;
+
+ case SwComparePosition::Equal:
+ case SwComparePosition::Inside:
+ delete pNewRedl;
+ pNewRedl = nullptr;
+
+ MaybeNotifyRedlineModification(*pRedl, m_rDoc);
+ break;
+
+ case SwComparePosition::Outside:
+ // Overlaps the current one completely,
+ // split or shorten the new one
+ if (*pEnd == *pREnd)
{
- case SwComparePosition::OverlapBefore:
+ pNewRedl->SetEnd(*pRStt, pEnd);
+ }
+ else if (*pStt == *pRStt)
+ {
+ pNewRedl->SetStart(*pREnd, pStt);
+ }
+ else
+ {
+ SwRangeRedline* pNew = new SwRangeRedline( *pNewRedl );
+ pNew->SetStart( *pREnd );
pNewRedl->SetEnd( *pRStt, pEnd );
- break;
-
- case SwComparePosition::OverlapBehind:
- pNewRedl->SetStart( *pREnd, pStt );
- break;
+ AppendRedline( pNew, bCallDelete );
+ n = 0; // re-initialize
+ bDec = true;
+ }
+ break;
+ default:
+ break;
+ }
+ break;
+ case RedlineType::Format:
+ switch( eCmpPos )
+ {
+ case SwComparePosition::Outside:
+ case SwComparePosition::Equal:
+ {
+ // Overlaps the current one completely or has the
+ // same dimension, delete the old one
+ maRedlineTable.DeleteAndDestroy( n );
+ bDec = true;
+ }
+ break;
- case SwComparePosition::Equal:
- case SwComparePosition::Inside:
+ case SwComparePosition::Inside:
+ if( pRedl->IsOwnRedline( *pNewRedl ) &&
+ pRedl->CanCombine( *pNewRedl ))
+ {
+ // own one can be ignored completely
delete pNewRedl;
pNewRedl = nullptr;
- break;
- case SwComparePosition::Outside:
- // Overlaps the current one completely,
- // split or shorten the new one
- if (*pEnd == *pREnd)
- {
- pNewRedl->SetEnd(*pRStt, pEnd);
- }
- else if (*pStt == *pRStt)
- {
- pNewRedl->SetStart(*pREnd, pStt);
- }
- else
- {
- SwRangeRedline* pNew = new SwRangeRedline( *pNewRedl );
- pNew->SetStart( *pREnd );
- pNewRedl->SetEnd( *pRStt, pEnd );
- AppendRedline( pNew, bCallDelete );
- n = 0; // re-initialize
- bDec = true;
- }
- break;
- default:
- break;
+ MaybeNotifyRedlineModification(*pRedl, m_rDoc);
}
- break;
- case RedlineType::Format:
- switch( eCmpPos )
+ else if( *pREnd == *pEnd )
+ // or else only shorten the current one
+ pRedl->SetEnd( *pStt, pREnd );
+ else if( *pRStt == *pStt )
{
- case SwComparePosition::Outside:
- case SwComparePosition::Equal:
- {
- // Overlaps the current one completely or has the
- // same dimension, delete the old one
- mpRedlineTable->DeleteAndDestroy( n );
- bDec = true;
- }
- break;
-
- case SwComparePosition::Inside:
- if( pRedl->IsOwnRedline( *pNewRedl ) &&
- pRedl->CanCombine( *pNewRedl ))
- {
- // own one can be ignored completely
- delete pNewRedl;
- pNewRedl = nullptr;
- }
- else if( *pREnd == *pEnd )
- // or else only shorten the current one
- pRedl->SetEnd( *pStt, pREnd );
- else if( *pRStt == *pStt )
- {
- // or else only shorten the current one
- pRedl->SetStart( *pEnd, pRStt );
- // re-insert
- mpRedlineTable->Remove( n );
- mpRedlineTable->Insert( pRedl, n );
- bDec = true;
- }
- else
- {
- // If it lies completely within the current one
- // we need to split it
- SwRangeRedline* pNew = new SwRangeRedline( *pRedl );
- pNew->SetStart( *pEnd );
- pRedl->SetEnd( *pStt, pREnd );
- AppendRedline( pNew, bCallDelete );
- n = 0; // re-initialize
- bDec = true;
- }
- break;
+ // or else only shorten the current one
+ pRedl->SetStart( *pEnd, pRStt );
+ // re-insert
+ maRedlineTable.Remove( n );
+ maRedlineTable.Insert( pRedl, n );
+ bDec = true;
+ }
+ else
+ {
+ // If it lies completely within the current one
+ // we need to split it
+ SwRangeRedline* pNew = new SwRangeRedline( *pRedl );
+ pNew->SetStart( *pEnd );
+ pRedl->SetEnd( *pStt, pREnd );
+ AppendRedline( pNew, bCallDelete );
+ n = 0; // re-initialize
+ bDec = true;
+ }
+ break;
- case SwComparePosition::OverlapBefore:
- case SwComparePosition::OverlapBehind:
- if( pRedl->IsOwnRedline( *pNewRedl ) &&
- pRedl->CanCombine( *pNewRedl ))
- {
- // If that's the case we can merge it, meaning
- // the new one covers this well
- if( SwComparePosition::OverlapBehind == eCmpPos )
- pNewRedl->SetStart( *pRStt, pStt );
- else
- pNewRedl->SetEnd( *pREnd, pEnd );
- mpRedlineTable->DeleteAndDestroy( n );
- bDec = false;
- }
- else if( SwComparePosition::OverlapBehind == eCmpPos )
- pNewRedl->SetStart( *pREnd, pStt );
+ case SwComparePosition::OverlapBefore:
+ case SwComparePosition::OverlapBehind:
+ if( pRedl->IsOwnRedline( *pNewRedl ) &&
+ pRedl->CanCombine( *pNewRedl ))
+ {
+ // If that's the case we can merge it, meaning
+ // the new one covers this well
+ if( SwComparePosition::OverlapBehind == eCmpPos )
+ pNewRedl->SetStart( *pRStt, pStt );
else
- pNewRedl->SetEnd( *pRStt, pEnd );
- break;
-
- case SwComparePosition::CollideEnd:
- if( pRedl->IsOwnRedline( *pNewRedl ) &&
- pRedl->CanCombine( *pNewRedl ) && n &&
- *(*mpRedlineTable)[ n-1 ]->End() < *pStt )
- {
- // If that's the case we can merge it, meaning
- // the new one covers this well
pNewRedl->SetEnd( *pREnd, pEnd );
- mpRedlineTable->DeleteAndDestroy( n );
- bDec = true;
- }
- break;
- case SwComparePosition::CollideStart:
- if( pRedl->IsOwnRedline( *pNewRedl ) &&
- pRedl->CanCombine( *pNewRedl ) &&
- n+1 < mpRedlineTable->size() &&
- *(*mpRedlineTable)[ n+1 ]->Start() < *pEnd )
- {
- // If that's the case we can merge it, meaning
- // the new one covers this well
- pNewRedl->SetStart( *pRStt, pStt );
- mpRedlineTable->DeleteAndDestroy( n );
- bDec = true;
- }
- break;
- default:
- break;
+ maRedlineTable.DeleteAndDestroy( n );
+ bDec = false;
+ }
+ else if( SwComparePosition::OverlapBehind == eCmpPos )
+ pNewRedl->SetStart( *pREnd, pStt );
+ else
+ pNewRedl->SetEnd( *pRStt, pEnd );
+ break;
+
+ case SwComparePosition::CollideEnd:
+ if( pRedl->IsOwnRedline( *pNewRedl ) &&
+ pRedl->CanCombine( *pNewRedl ) &&
+ (n == 0 || *maRedlineTable[ n-1 ]->End() < *pStt))
+ {
+ // If that's the case we can merge it, meaning
+ // the new one covers this well
+ pNewRedl->SetEnd( *pREnd, pEnd );
+ maRedlineTable.DeleteAndDestroy( n );
+ bDec = true;
+ }
+ break;
+ case SwComparePosition::CollideStart:
+ if( pRedl->IsOwnRedline( *pNewRedl ) &&
+ pRedl->CanCombine( *pNewRedl ) &&
+ (n+1 >= maRedlineTable.size() ||
+ (*maRedlineTable[ n+1 ]->Start() >= *pEnd &&
+ *maRedlineTable[ n+1 ]->Start() != *pREnd)))
+ {
+ // If that's the case we can merge it, meaning
+ // the new one covers this well
+ pNewRedl->SetStart( *pRStt, pStt );
+ maRedlineTable.DeleteAndDestroy( n );
+ bDec = true;
}
break;
default:
break;
}
break;
-
- case RedlineType::FmtColl:
- // How should we behave here?
- // insert as is
- break;
default:
break;
}
+ break;
+
+ case RedlineType::FmtColl:
+ // How should we behave here?
+ // insert as is
+ break;
+ default:
+ break;
}
+ }
- if( pNewRedl )
+ if( pNewRedl )
+ {
+ if( ( *pStt == *pEnd ) &&
+ ( pNewRedl->GetContentIdx() == nullptr ) )
+ { // Do not insert empty redlines
+ delete pNewRedl;
+ pNewRedl = nullptr;
+ }
+ else
{
- if( ( *pStt == *pEnd ) &&
- ( pNewRedl->GetContentIdx() == nullptr ) )
- { // Do not insert empty redlines
- delete pNewRedl;
- pNewRedl = nullptr;
- }
- else
+ if ( bCallDelete && RedlineType::Delete == pNewRedl->GetType() )
{
- if ( bCallDelete && RedlineType::Delete == pNewRedl->GetType() )
+ if ( pStt->GetContentIndex() != 0 )
{
- if ( pStt->nContent != 0 )
- {
- // tdf#119571 update the style of the joined paragraph
- // after a partially deleted paragraph to show its correct style
- // in "Show changes" mode, too. All removed paragraphs
- // get the style of the first (partially deleted) paragraph
- // to avoid text insertion with bad style in the deleted
- // area later.
-
- SwContentNode* pDelNd = pStt->nNode.GetNode().GetContentNode();
- SwContentNode* pTextNd = pEnd->nNode.GetNode().GetContentNode();
- SwTextNode* pDelNode = pStt->nNode.GetNode().GetTextNode();
- SwTextNode* pTextNode;
- SwNodeIndex aIdx( pEnd->nNode.GetNode() );
- bool bFirst = true;
-
- while (pDelNode != nullptr && pTextNd != nullptr && pDelNd->GetIndex() < pTextNd->GetIndex())
+ // tdf#119571 update the style of the joined paragraph
+ // after a partially deleted paragraph to show its correct style
+ // in "Show changes" mode, too. All removed paragraphs
+ // get the style of the first (partially deleted) paragraph
+ // to avoid text insertion with bad style in the deleted
+ // area later (except paragraphs of the removed tables).
+
+ SwContentNode* pDelNd = pStt->GetNode().GetContentNode();
+ // start copying the style of the first paragraph from the end of the range
+ SwContentNode* pTextNd = pEnd->GetNode().GetContentNode();
+ SwNodeIndex aIdx( pEnd->GetNode() );
+ bool bFirst = true;
+
+ while (pTextNd != nullptr && pDelNd->GetIndex() < pTextNd->GetIndex())
+ {
+ if( pTextNd->IsTextNode() )
{
- pTextNode = pTextNd->GetTextNode();
- if (pTextNode && pDelNode != pTextNode )
+ SwPosition aPos(aIdx);
+
+ if (m_rDoc.GetIDocumentUndoRedo().DoesUndo())
{
- SwPosition aPos(aIdx);
+ bCompress = true;
- if (m_rDoc.GetIDocumentUndoRedo().DoesUndo())
+ // split redline to store ExtraData per paragraphs
+ SwRangeRedline* pPar = new SwRangeRedline( *pNewRedl );
+ pPar->SetStart( aPos );
+ pNewRedl->SetEnd( aPos );
+
+ // get extradata for reset formatting of the modified paragraph
+ SwRedlineExtraData_FormatColl* pExtraData = lcl_CopyStyle(aPos, *pStt, false);
+ if (pExtraData)
{
- bCompress = true;
+ std::unique_ptr<SwRedlineExtraData_FormatColl> xRedlineExtraData;
+ if (!bFirst)
+ pExtraData->SetFormatAll(false);
+ xRedlineExtraData.reset(pExtraData);
+ pPar->SetExtraData( xRedlineExtraData.get() );
+ }
- // split redline to store ExtraData per paragraphs
- SwRangeRedline* pPar = new SwRangeRedline( *pNewRedl );
- pPar->SetStart( aPos );
- pNewRedl->SetEnd( aPos );
+ // skip empty redlines without ExtraData
+ // FIXME: maybe checking pExtraData is redundant here
+ if ( pExtraData || *pPar->Start() != *pPar->End() )
+ maRedlineTable.Insert( pPar );
+ else
+ delete pPar;
+ }
+
+ // modify paragraph formatting
+ lcl_CopyStyle(*pStt, aPos);
+ }
- // get extradata for reset formatting of the modified paragraph
- SwRedlineExtraData_FormatColl* pExtraData = lcl_CopyStyle(aPos, *pStt, false);
- if (pExtraData)
+ if (bFirst)
+ bFirst = false;
+
+ // Jump to the previous paragraph and if needed, skip paragraphs of
+ // the removed table(s) in the range to avoid leaving empty tables
+ // because of the non-continuous redline range over the table.
+ // FIXME: this is not enough for tables with inner redlines, where
+ // tracked deletion of the text containing such a table leaves an
+ // empty table at the place of the table (a problem inherited from OOo).
+ pTextNd = nullptr;
+ while( --aIdx > *pDelNd && !aIdx.GetNode().IsContentNode() )
+ {
+ // possible table end
+ if( aIdx.GetNode().IsEndNode() && aIdx.GetNode().FindTableNode() )
+ {
+ SwNodeIndex aIdx2 = aIdx;
+ // search table start and skip table paragraphs
+ while ( pDelNd->GetIndex() < aIdx2.GetIndex() )
+ {
+ SwTableNode* pTable = aIdx2.GetNode().GetTableNode();
+ if( pTable &&
+ pTable->EndOfSectionNode()->GetIndex() == aIdx.GetIndex() )
{
- std::unique_ptr<SwRedlineExtraData_FormatColl> xRedlineExtraData;
- if (!bFirst)
- pExtraData->SetFormatAll(false);
- xRedlineExtraData.reset(pExtraData);
- pPar->SetExtraData( xRedlineExtraData.get() );
+ aIdx = aIdx2;
+ break;
}
-
- // skip empty redlines without ExtraData
- // FIXME: maybe checking pExtraData is redundant here
- if ( pExtraData || *pPar->Start() != *pPar->End() )
- mpRedlineTable->Insert( pPar );
- else
- delete pPar;
+ --aIdx2;
}
-
- // modify paragraph formatting
- lcl_CopyStyle(*pStt, aPos);
}
- pTextNd = SwNodes::GoPrevious( &aIdx );
-
- if (bFirst)
- bFirst = false;
}
+
+ if (aIdx.GetNode().IsContentNode())
+ pTextNd = aIdx.GetNode().GetContentNode();
}
}
- bool const ret = mpRedlineTable->Insert( pNewRedl );
- assert(ret || !pNewRedl);
- if (ret && !pNewRedl)
+
+ // delete tables of the deletion explicitly, to avoid
+ // remaining empty tables after accepting the rejection
+ // and visible empty tables in Hide Changes mode
+ // (this was the case, if tables have already contained
+ // other tracked changes)
+ // FIXME: because of recursive nature of AppendRedline,
+ // this doesn't work for selections with multiple tables
+ if ( m_rDoc.GetIDocumentUndoRedo().DoesUndo() )
{
- bMerged = true; // treat InsertWithValidRanges as "merge"
+ SwNodeIndex aSttIdx( pStt->GetNode() );
+ SwNodeIndex aEndIdx( pEnd->GetNode() );
+ while ( aSttIdx < aEndIdx )
+ {
+ if ( aSttIdx.GetNode().IsTableNode() )
+ {
+ SvxPrintItem aHasTextChangesOnly(RES_PRINT, false);
+ SwCursor aCursor( SwPosition(aSttIdx), nullptr );
+ m_rDoc.SetRowNotTracked( aCursor, aHasTextChangesOnly, /*bAll=*/true );
+ }
+ ++aSttIdx;
+ }
}
}
+ bool const ret = maRedlineTable.Insert( pNewRedl );
+ assert(ret || !pNewRedl);
+ if (ret && !pNewRedl)
+ {
+ bMerged = true; // treat InsertWithValidRanges as "merge"
+ }
}
-
- if( bCompress )
- CompressRedlines();
}
- else
+
+ // If we deleted moved redlines, and there was only 1 MoveID, then we should use that
+ // We overwrite those that was given right now, so it cannot be deeper under other redline
+ if (nMoveIDToDelete > 1 && deletedMoveIDs.size() == 1)
{
- if( bCallDelete && RedlineType::Delete == pNewRedl->GetType() )
+ sal_uInt32 nNewMoveID = *(deletedMoveIDs.begin());
+ if (nNewMoveID > 1) // MoveID==1 is for old, unrecognised moves, leave them alone
{
- RedlineFlags eOld = meRedlineFlags;
- // Set to NONE, so that the Delete::Redo merges the Redline data correctly!
- // The ShowMode needs to be retained!
- meRedlineFlags = eOld & ~RedlineFlags(RedlineFlags::On | RedlineFlags::Ignore);
- m_rDoc.getIDocumentContentOperations().DeleteAndJoin( *pNewRedl );
- meRedlineFlags = eOld;
+ for (n = 0; n < maRedlineTable.size(); ++n)
+ {
+ if (maRedlineTable[n]->GetMoved() == nMoveIDToDelete)
+ {
+ maRedlineTable[n]->SetMoved(nNewMoveID);
+ }
+ }
}
- delete pNewRedl;
- pNewRedl = nullptr;
}
+
+ if( bCompress )
+ CompressRedlines(nStartPos);
+
CHECK_REDLINE( *this )
return (nullptr != pNewRedl)
@@ -2226,7 +2486,7 @@ bool DocumentRedlineManager::AppendTableRowRedline( SwTableRowRedline* pNewRedl
// Make equivalent of 'AppendRedline' checks inside here too
- mpExtraRedlineTable->Insert( pNewRedl );
+ maExtraRedlineTable.Insert( pNewRedl );
}
else
{
@@ -2268,7 +2528,7 @@ bool DocumentRedlineManager::AppendTableCellRedline( SwTableCellRedline* pNewRed
// Make equivalent of 'AppendRedline' checks inside here too
- mpExtraRedlineTable->Insert( pNewRedl );
+ maExtraRedlineTable.Insert( pNewRedl );
}
else
{
@@ -2294,7 +2554,7 @@ bool DocumentRedlineManager::AppendTableCellRedline( SwTableCellRedline* pNewRed
return nullptr != pNewRedl;
}
-void DocumentRedlineManager::CompressRedlines()
+void DocumentRedlineManager::CompressRedlines(size_t nStartIndex)
{
CHECK_REDLINE( *this )
@@ -2306,20 +2566,19 @@ void DocumentRedlineManager::CompressRedlines()
pFnc = &SwRangeRedline::Hide;
// Try to merge identical ones
- for( SwRedlineTable::size_type n = 1; n < mpRedlineTable->size(); ++n )
- {
- SwRangeRedline* pPrev = (*mpRedlineTable)[ n-1 ],
- * pCur = (*mpRedlineTable)[ n ];
- const SwPosition* pPrevStt = pPrev->Start(),
- * pPrevEnd = pPrevStt == pPrev->GetPoint()
- ? pPrev->GetMark() : pPrev->GetPoint();
- const SwPosition* pCurStt = pCur->Start(),
- * pCurEnd = pCurStt == pCur->GetPoint()
- ? pCur->GetMark() : pCur->GetPoint();
+ if (nStartIndex == 0)
+ nStartIndex = 1;
+ for( SwRedlineTable::size_type n = nStartIndex; n < maRedlineTable.size(); ++n )
+ {
+ SwRangeRedline* pPrev = maRedlineTable[ n-1 ],
+ * pCur = maRedlineTable[ n ];
+ auto [pPrevStt,pPrevEnd] = pPrev->StartEnd();
+ auto [pCurStt, pCurEnd] = pCur->StartEnd();
+
if( *pPrevEnd == *pCurStt && pPrev->CanCombine( *pCur ) &&
- pPrevStt->nNode.GetNode().StartOfSectionNode() ==
- pCurEnd->nNode.GetNode().StartOfSectionNode() &&
- !pCurEnd->nNode.GetNode().StartOfSectionNode()->IsTableNode() )
+ pPrevStt->GetNode().StartOfSectionNode() ==
+ pCurEnd->GetNode().StartOfSectionNode() &&
+ !pCurEnd->GetNode().StartOfSectionNode()->IsTableNode() )
{
// we then can merge them
SwRedlineTable::size_type nPrevIndex = n-1;
@@ -2327,7 +2586,7 @@ void DocumentRedlineManager::CompressRedlines()
pCur->Show(0, n);
pPrev->SetEnd( *pCur->End() );
- mpRedlineTable->DeleteAndDestroy( n );
+ maRedlineTable.DeleteAndDestroy( n );
--n;
if( pFnc )
(pPrev->*pFnc)(0, nPrevIndex, false);
@@ -2341,17 +2600,14 @@ void DocumentRedlineManager::CompressRedlines()
bool DocumentRedlineManager::SplitRedline( const SwPaM& rRange )
{
bool bChg = false;
+ auto [pStt, pEnd] = rRange.StartEnd(); // SwPosition*
SwRedlineTable::size_type n = 0;
- const SwPosition* pStt = rRange.Start();
- const SwPosition* pEnd = rRange.End();
- GetRedline( *pStt, &n );
- for ( ; n < mpRedlineTable->size(); ++n)
+ //FIXME overlapping problem GetRedline( *pStt, &n );
+ for ( ; n < maRedlineTable.size(); ++n)
{
- SwRangeRedline * pRedline = (*mpRedlineTable)[ n ];
- SwPosition *const pRedlineStart = pRedline->Start();
- SwPosition *const pRedlineEnd = pRedline->End();
- if (*pRedlineStart <= *pStt && *pStt <= *pRedlineEnd &&
- *pRedlineStart <= *pEnd && *pEnd <= *pRedlineEnd)
+ SwRangeRedline * pRedline = maRedlineTable[ n ];
+ auto [pRedlineStart, pRedlineEnd] = pRedline->StartEnd();
+ if (*pRedlineStart <= *pStt && *pEnd <= *pRedlineEnd)
{
bChg = true;
int nn = 0;
@@ -2379,18 +2635,18 @@ bool DocumentRedlineManager::SplitRedline( const SwPaM& rRange )
case 3:
pRedline->InvalidateRange(SwRangeRedline::Invalidation::Remove);
- mpRedlineTable->DeleteAndDestroy( n-- );
+ maRedlineTable.DeleteAndDestroy( n-- );
pRedline = nullptr;
break;
}
if (pRedline && !pRedline->HasValidRange())
{
// re-insert
- mpRedlineTable->Remove( n );
- mpRedlineTable->Insert( pRedline, n );
+ maRedlineTable.Remove( n );
+ maRedlineTable.Insert( pRedline, n );
}
if( pNew )
- mpRedlineTable->Insert( pNew, n );
+ maRedlineTable.Insert( pNew, n );
}
else if (*pEnd < *pRedlineStart)
break;
@@ -2417,26 +2673,22 @@ bool DocumentRedlineManager::DeleteRedline( const SwPaM& rRange, bool bSaveInUnd
}
}
- const SwPosition* pStt = rRange.Start(),
- * pEnd = pStt == rRange.GetPoint() ? rRange.GetMark()
- : rRange.GetPoint();
+ auto [pStt, pEnd] = rRange.StartEnd(); // SwPosition*
SwRedlineTable::size_type n = 0;
GetRedline( *pStt, &n );
- for( ; n < mpRedlineTable->size() ; ++n )
+ for( ; n < maRedlineTable.size() ; ++n )
{
- SwRangeRedline* pRedl = (*mpRedlineTable)[ n ];
+ SwRangeRedline* pRedl = maRedlineTable[ n ];
if( RedlineType::Any != nDelType && nDelType != pRedl->GetType() )
continue;
- SwPosition* pRStt = pRedl->Start(),
- * pREnd = pRStt == pRedl->GetPoint() ? pRedl->GetMark()
- : pRedl->GetPoint();
+ auto [pRStt, pREnd] = pRedl->StartEnd(); // SwPosition*
switch( ComparePosition( *pStt, *pEnd, *pRStt, *pREnd ) )
{
case SwComparePosition::Equal:
case SwComparePosition::Outside:
pRedl->InvalidateRange(SwRangeRedline::Invalidation::Remove);
- mpRedlineTable->DeleteAndDestroy( n-- );
+ maRedlineTable.DeleteAndDestroy( n-- );
bChg = true;
break;
@@ -2445,8 +2697,8 @@ bool DocumentRedlineManager::DeleteRedline( const SwPaM& rRange, bool bSaveInUnd
pRedl->SetStart( *pEnd, pRStt );
pRedl->InvalidateRange(SwRangeRedline::Invalidation::Add);
// re-insert
- mpRedlineTable->Remove( n );
- mpRedlineTable->Insert( pRedl );
+ maRedlineTable.Remove( n );
+ maRedlineTable.Insert( pRedl );
--n;
break;
@@ -2457,8 +2709,8 @@ bool DocumentRedlineManager::DeleteRedline( const SwPaM& rRange, bool bSaveInUnd
if( !pRedl->HasValidRange() )
{
// re-insert
- mpRedlineTable->Remove( n );
- mpRedlineTable->Insert( pRedl );
+ maRedlineTable.Remove( n );
+ maRedlineTable.Insert( pRedl );
--n;
}
break;
@@ -2472,8 +2724,8 @@ bool DocumentRedlineManager::DeleteRedline( const SwPaM& rRange, bool bSaveInUnd
pRedl->SetStart( *pEnd, pRStt );
pRedl->InvalidateRange(SwRangeRedline::Invalidation::Add);
// re-insert
- mpRedlineTable->Remove( n );
- mpRedlineTable->Insert( pRedl );
+ maRedlineTable.Remove( n );
+ maRedlineTable.Insert( pRedl );
--n;
}
else
@@ -2492,12 +2744,12 @@ bool DocumentRedlineManager::DeleteRedline( const SwPaM& rRange, bool bSaveInUnd
if( !pRedl->HasValidRange() )
{
// re-insert
- mpRedlineTable->Remove( n );
- mpRedlineTable->Insert( pRedl );
+ maRedlineTable.Remove( n );
+ maRedlineTable.Insert( pRedl );
--n;
}
if( pCpy )
- mpRedlineTable->Insert( pCpy );
+ maRedlineTable.Insert( pCpy );
}
}
break;
@@ -2508,14 +2760,14 @@ bool DocumentRedlineManager::DeleteRedline( const SwPaM& rRange, bool bSaveInUnd
if ( pRedl->HasMark() && *pRedl->GetMark() == *pRedl->GetPoint() )
{
pRedl->InvalidateRange(SwRangeRedline::Invalidation::Remove);
- mpRedlineTable->DeleteAndDestroy( n-- );
+ maRedlineTable.DeleteAndDestroy( n-- );
bChg = true;
break;
}
[[fallthrough]];
case SwComparePosition::Before:
- n = mpRedlineTable->size();
+ n = maRedlineTable.size();
break;
default:
break;
@@ -2539,38 +2791,114 @@ bool DocumentRedlineManager::DeleteRedline( const SwStartNode& rNode, bool bSave
SwRedlineTable::size_type DocumentRedlineManager::GetRedlinePos( const SwNode& rNd, RedlineType nType ) const
{
- const sal_uLong nNdIdx = rNd.GetIndex();
- for( SwRedlineTable::size_type n = 0; n < mpRedlineTable->size() ; ++n )
+ const SwNodeOffset nNdIdx = rNd.GetIndex();
+ // if the table only contains good (i.e. non-overlapping) data, we can do a binary search
+ if (!maRedlineTable.HasOverlappingElements())
{
- const SwRangeRedline* pTmp = (*mpRedlineTable)[ n ];
- sal_uLong nPt = pTmp->GetPoint()->nNode.GetIndex(),
- nMk = pTmp->GetMark()->nNode.GetIndex();
- if( nPt < nMk ) { tools::Long nTmp = nMk; nMk = nPt; nPt = nTmp; }
+ // binary search to the first redline with end >= the needle
+ auto it = std::lower_bound(maRedlineTable.begin(), maRedlineTable.end(), rNd,
+ [&nNdIdx](const SwRangeRedline* lhs, const SwNode& /*rhs*/)
+ {
+ return lhs->End()->GetNodeIndex() < nNdIdx;
+ });
+ for( ; it != maRedlineTable.end(); ++it)
+ {
+ const SwRangeRedline* pTmp = *it;
+ auto [pStart, pEnd] = pTmp->StartEnd(); // SwPosition*
+ SwNodeOffset nStart = pStart->GetNodeIndex(),
+ nEnd = pEnd->GetNodeIndex();
- if( ( RedlineType::Any == nType || nType == pTmp->GetType()) &&
- nMk <= nNdIdx && nNdIdx <= nPt )
- return n;
+ if( ( RedlineType::Any == nType || nType == pTmp->GetType()) &&
+ nStart <= nNdIdx && nNdIdx <= nEnd )
+ return std::distance(maRedlineTable.begin(), it);
- if( nMk > nNdIdx )
- break;
+ if( nStart > nNdIdx )
+ break;
+ }
+ }
+ else
+ {
+ for( SwRedlineTable::size_type n = 0; n < maRedlineTable.size() ; ++n )
+ {
+ const SwRangeRedline* pTmp = maRedlineTable[ n ];
+ SwNodeOffset nPt = pTmp->GetPoint()->GetNodeIndex(),
+ nMk = pTmp->GetMark()->GetNodeIndex();
+ if( nPt < nMk )
+ std::swap( nMk, nPt );
+
+ if( ( RedlineType::Any == nType || nType == pTmp->GetType()) &&
+ nMk <= nNdIdx && nNdIdx <= nPt )
+ return n;
+
+ if( nMk > nNdIdx )
+ break;
+ }
}
return SwRedlineTable::npos;
// #TODO - add 'SwExtraRedlineTable' also ?
}
+SwRedlineTable::size_type
+DocumentRedlineManager::GetRedlineEndPos(SwRedlineTable::size_type nStartPos, const SwNode& rNd,
+ RedlineType nType) const
+{
+ //if the start is already invalid
+ if (nStartPos >= maRedlineTable.size())
+ return nStartPos;
+
+ const SwNodeOffset nNdIdx = rNd.GetIndex();
+ SwRedlineTable::size_type nEndPos = nStartPos;
+ SwRedlineTable::size_type nEndPosTry = nEndPos + 1;
+
+ while (nEndPosTry < maRedlineTable.size()
+ && maRedlineTable[nEndPosTry]->Start()->GetNodeIndex() <= nNdIdx)
+ {
+ if (RedlineType::Any == nType || nType == maRedlineTable[nEndPosTry]->GetType())
+ {
+ nEndPos = nEndPosTry;
+ }
+ nEndPosTry++;
+ }
+ return nEndPos;
+}
+
+void DocumentRedlineManager::UpdateRedlineContentNode(SwRedlineTable::size_type nStartPos,
+ SwRedlineTable::size_type nEndPos) const
+{
+ for (SwRedlineTable::size_type n = nStartPos; n <= nEndPos; ++n)
+ {
+ //just in case we got wrong input
+ if (n >= maRedlineTable.size())
+ return;
+
+ SwPosition* pStart = maRedlineTable[n]->Start();
+ SwPosition* pEnd = maRedlineTable[n]->End();
+ SwContentNode* pCont = pStart->GetNode().GetContentNode();
+ if (pCont)
+ {
+ pStart->nContent.Assign(pCont, pStart->nContent.GetIndex());
+ }
+ pCont = pEnd->GetNode().GetContentNode();
+ if (pCont)
+ {
+ pEnd->nContent.Assign(pCont, pEnd->nContent.GetIndex());
+ }
+ }
+}
+
bool DocumentRedlineManager::HasRedline( const SwPaM& rPam, RedlineType nType, bool bStartOrEndInRange ) const
{
SwPosition currentStart(*rPam.Start());
SwPosition currentEnd(*rPam.End());
- SwNodeIndex pEndNodeIndex(currentEnd.nNode.GetNode());
+ const SwNode& rEndNode(currentEnd.GetNode());
- for( SwRedlineTable::size_type n = GetRedlinePos( rPam.Start()->nNode.GetNode(), nType );
- n < mpRedlineTable->size(); ++n )
+ for( SwRedlineTable::size_type n = GetRedlinePos( rPam.Start()->GetNode(), nType );
+ n < maRedlineTable.size(); ++n )
{
- const SwRangeRedline* pTmp = (*mpRedlineTable)[ n ];
+ const SwRangeRedline* pTmp = maRedlineTable[ n ];
- if ( pTmp->Start()->nNode > pEndNodeIndex )
+ if ( pTmp->Start()->GetNode() > rEndNode )
break;
if( RedlineType::Any != nType && nType != pTmp->GetType() )
@@ -2591,27 +2919,24 @@ bool DocumentRedlineManager::HasRedline( const SwPaM& rPam, RedlineType nType, b
const SwRangeRedline* DocumentRedlineManager::GetRedline( const SwPosition& rPos,
SwRedlineTable::size_type* pFndPos ) const
{
- SwRedlineTable::size_type nO = mpRedlineTable->size(), nM, nU = 0;
+ SwRedlineTable::size_type nO = maRedlineTable.size(), nM, nU = 0;
if( nO > 0 )
{
nO--;
while( nU <= nO )
{
nM = nU + ( nO - nU ) / 2;
- const SwRangeRedline* pRedl = (*mpRedlineTable)[ nM ];
- const SwPosition* pStt = pRedl->Start();
- const SwPosition* pEnd = pStt == pRedl->GetPoint()
- ? pRedl->GetMark()
- : pRedl->GetPoint();
+ const SwRangeRedline* pRedl = maRedlineTable[ nM ];
+ auto [pStt, pEnd] = pRedl->StartEnd();
if( pEnd == pStt
? *pStt == rPos
: ( *pStt <= rPos && rPos < *pEnd ) )
{
- while( nM && rPos == *(*mpRedlineTable)[ nM - 1 ]->End() &&
- rPos == *(*mpRedlineTable)[ nM - 1 ]->Start() )
+ while( nM && rPos == *maRedlineTable[ nM - 1 ]->End() &&
+ rPos == *maRedlineTable[ nM - 1 ]->Start() )
{
--nM;
- pRedl = (*mpRedlineTable)[ nM ];
+ pRedl = maRedlineTable[ nM ];
}
// if there are format and insert changes in the same position
// show insert change first.
@@ -2619,19 +2944,19 @@ const SwRangeRedline* DocumentRedlineManager::GetRedline( const SwPosition& rPos
// before and after the current redline
if( RedlineType::Format == pRedl->GetType() )
{
- if( nM && rPos >= *(*mpRedlineTable)[ nM - 1 ]->Start() &&
- rPos <= *(*mpRedlineTable)[ nM - 1 ]->End() &&
- ( RedlineType::Insert == (*mpRedlineTable)[ nM - 1 ]->GetType() ) )
+ if( nM && rPos >= *maRedlineTable[ nM - 1 ]->Start() &&
+ rPos <= *maRedlineTable[ nM - 1 ]->End() &&
+ ( RedlineType::Insert == maRedlineTable[ nM - 1 ]->GetType() ) )
{
--nM;
- pRedl = (*mpRedlineTable)[ nM ];
+ pRedl = maRedlineTable[ nM ];
}
- else if( ( nM + 1 ) <= nO && rPos >= *(*mpRedlineTable)[ nM + 1 ]->Start() &&
- rPos <= *(*mpRedlineTable)[ nM + 1 ]->End() &&
- ( RedlineType::Insert == (*mpRedlineTable)[ nM + 1 ]->GetType() ) )
+ else if( ( nM + 1 ) <= nO && rPos >= *maRedlineTable[ nM + 1 ]->Start() &&
+ rPos <= *maRedlineTable[ nM + 1 ]->End() &&
+ ( RedlineType::Insert == maRedlineTable[ nM + 1 ]->GetType() ) )
{
++nM;
- pRedl = (*mpRedlineTable)[ nM ];
+ pRedl = maRedlineTable[ nM ];
}
}
@@ -2658,7 +2983,100 @@ const SwRangeRedline* DocumentRedlineManager::GetRedline( const SwPosition& rPos
// #TODO - add 'SwExtraRedlineTable' also ?
}
-bool DocumentRedlineManager::AcceptRedline( SwRedlineTable::size_type nPos, bool bCallDelete )
+bool DocumentRedlineManager::AcceptRedlineRange(SwRedlineTable::size_type nPosOrigin,
+ SwRedlineTable::size_type& nPosStart,
+ SwRedlineTable::size_type& nPosEnd,
+ bool bCallDelete)
+{
+ bool bRet = false;
+
+ SwRangeRedline* pTmp = maRedlineTable[nPosOrigin];
+ SwRedlineTable::size_type nRdlIdx = nPosEnd + 1;
+ SwRedlineData aOrigData = pTmp->GetRedlineData(0);
+
+ SwNodeOffset nPamStartNI = maRedlineTable[nPosStart]->Start()->GetNodeIndex();
+ sal_Int32 nPamStartCI = maRedlineTable[nPosStart]->Start()->GetContentIndex();
+ SwNodeOffset nPamEndtNI = maRedlineTable[nPosEnd]->End()->GetNodeIndex();
+ sal_Int32 nPamEndCI = maRedlineTable[nPosEnd]->End()->GetContentIndex();
+ do
+ {
+ nRdlIdx--;
+ pTmp = maRedlineTable[nRdlIdx];
+ if (pTmp->Start()->GetNodeIndex() < nPamStartNI
+ || (pTmp->Start()->GetNodeIndex() == nPamStartNI
+ && pTmp->Start()->GetContentIndex() < nPamStartCI))
+ break;
+
+ if (pTmp->End()->GetNodeIndex() > nPamEndtNI
+ || (pTmp->End()->GetNodeIndex() == nPamEndtNI
+ && pTmp->End()->GetContentIndex() > nPamEndCI))
+ {
+ }
+ else if (pTmp->GetRedlineData(0).CanCombineForAcceptReject(aOrigData))
+ {
+ if (m_rDoc.GetIDocumentUndoRedo().DoesUndo())
+ {
+ m_rDoc.GetIDocumentUndoRedo().AppendUndo(
+ std::make_unique<SwUndoAcceptRedline>(*pTmp));
+ }
+ nPamEndtNI = pTmp->Start()->GetNodeIndex();
+ nPamEndCI = pTmp->Start()->GetContentIndex();
+ bRet |= lcl_AcceptRedline(maRedlineTable, nRdlIdx, bCallDelete);
+ nRdlIdx++; //we will decrease it in the loop anyway.
+ }
+ else if (aOrigData.GetType() == RedlineType::Insert
+ && pTmp->GetType() == RedlineType::Delete && pTmp->GetStackCount() > 1
+ && pTmp->GetType(1) == RedlineType::Insert
+ && pTmp->GetRedlineData(1).CanCombineForAcceptReject(aOrigData))
+ {
+ // The Insert redline we want to accept has a deletion redline too
+ // we should leave the deletion redline, and only accept the inner insert.
+ if (m_rDoc.GetIDocumentUndoRedo().DoesUndo())
+ {
+ m_rDoc.GetIDocumentUndoRedo().AppendUndo(
+ std::make_unique<SwUndoAcceptRedline>(*pTmp, 1));
+ }
+ nPamEndtNI = pTmp->Start()->GetNodeIndex();
+ nPamEndCI = pTmp->Start()->GetContentIndex();
+ bRet |= lcl_AcceptInnerInsertRedline(maRedlineTable, nRdlIdx, 1);
+ nRdlIdx++; //we will decrease it in the loop anyway.
+ }
+ } while (nRdlIdx > 0);
+ return bRet;
+}
+
+bool DocumentRedlineManager::AcceptMovedRedlines(sal_uInt32 nMovedID, bool bCallDelete)
+{
+ assert(nMovedID > 1); // 0, and 1 is reserved
+ bool bRet = false;
+ SwRedlineTable::size_type nRdlIdx = maRedlineTable.size();
+
+ while (nRdlIdx > 0)
+ {
+ nRdlIdx--;
+ SwRangeRedline* pTmp = maRedlineTable[nRdlIdx];
+ if (pTmp->GetMoved(0) == nMovedID
+ || (pTmp->GetStackCount() > 1 && pTmp->GetMoved(1) == nMovedID))
+ {
+ if (m_rDoc.GetIDocumentUndoRedo().DoesUndo())
+ {
+ m_rDoc.GetIDocumentUndoRedo().AppendUndo(
+ std::make_unique<SwUndoAcceptRedline>(*pTmp));
+ }
+
+ if (pTmp->GetMoved(0) == nMovedID)
+ bRet |= lcl_AcceptRedline(maRedlineTable, nRdlIdx, bCallDelete);
+ else
+ bRet |= lcl_AcceptInnerInsertRedline(maRedlineTable, nRdlIdx, 1);
+
+ nRdlIdx++; //we will decrease it in the loop anyway.
+ }
+ }
+ return bRet;
+}
+
+bool DocumentRedlineManager::AcceptRedline(SwRedlineTable::size_type nPos, bool bCallDelete,
+ bool bRange)
{
bool bRet = false;
@@ -2667,9 +3085,11 @@ bool DocumentRedlineManager::AcceptRedline( SwRedlineTable::size_type nPos, bool
(RedlineFlags::ShowMask & meRedlineFlags) )
SetRedlineFlags( RedlineFlags::ShowInsert | RedlineFlags::ShowDelete | meRedlineFlags );
- SwRangeRedline* pTmp = (*mpRedlineTable)[ nPos ];
- pTmp->Show(0, mpRedlineTable->GetPos(pTmp), /*bForced=*/true);
- pTmp->Show(1, mpRedlineTable->GetPos(pTmp), /*bForced=*/true);
+ SwRangeRedline* pTmp = maRedlineTable[ nPos ];
+ bool bAnonym = pTmp->GetRedlineData(0).IsAnonymized();
+
+ pTmp->Show(0, maRedlineTable.GetPos(pTmp), /*bForced=*/true);
+ pTmp->Show(1, maRedlineTable.GetPos(pTmp), /*bForced=*/true);
if( pTmp->HasMark() && pTmp->IsVisible() )
{
if (m_rDoc.GetIDocumentUndoRedo().DoesUndo())
@@ -2683,7 +3103,28 @@ bool DocumentRedlineManager::AcceptRedline( SwRedlineTable::size_type nPos, bool
int nLoopCnt = 2;
sal_uInt16 nSeqNo = pTmp->GetSeqNo();
- do {
+ if (bRange && !nSeqNo && !bAnonym
+ && !pTmp->Start()->GetNode().StartOfSectionNode()->IsTableNode())
+ {
+ sal_uInt32 nMovedID = pTmp->GetMoved(0);
+ if (nMovedID > 1)
+ {
+ // Accept all redlineData with this unique move id
+ bRet |= AcceptMovedRedlines(nMovedID, bCallDelete);
+ }
+ else
+ {
+ SwRedlineTable::size_type nPosStart = nPos;
+ SwRedlineTable::size_type nPosEnd = nPos;
+
+ maRedlineTable.getConnectedArea(nPos, nPosStart, nPosEnd, true);
+
+ // Accept redlines between pPamStart-pPamEnd.
+ // but only those that can be combined with the selected.
+ bRet |= AcceptRedlineRange(nPos, nPosStart, nPosEnd, bCallDelete);
+ }
+ }
+ else do {
if (m_rDoc.GetIDocumentUndoRedo().DoesUndo())
{
@@ -2691,21 +3132,21 @@ bool DocumentRedlineManager::AcceptRedline( SwRedlineTable::size_type nPos, bool
std::make_unique<SwUndoAcceptRedline>(*pTmp) );
}
- bRet |= lcl_AcceptRedline( *mpRedlineTable, nPos, bCallDelete );
+ bRet |= lcl_AcceptRedline( maRedlineTable, nPos, bCallDelete );
if( nSeqNo )
{
if( SwRedlineTable::npos == nPos )
nPos = 0;
SwRedlineTable::size_type nFndPos = 2 == nLoopCnt
- ? mpRedlineTable->FindNextSeqNo( nSeqNo, nPos )
- : mpRedlineTable->FindPrevSeqNo( nSeqNo, nPos );
+ ? maRedlineTable.FindNextSeqNo( nSeqNo, nPos )
+ : maRedlineTable.FindPrevSeqNo( nSeqNo, nPos );
if( SwRedlineTable::npos != nFndPos || ( 0 != ( --nLoopCnt ) &&
SwRedlineTable::npos != ( nFndPos =
- mpRedlineTable->FindPrevSeqNo( nSeqNo, nPos ))) )
+ maRedlineTable.FindPrevSeqNo( nSeqNo, nPos ))) )
{
nPos = nFndPos;
- pTmp = (*mpRedlineTable)[ nPos ];
+ pTmp = maRedlineTable[ nPos ];
}
else
nLoopCnt = 0;
@@ -2713,7 +3154,7 @@ bool DocumentRedlineManager::AcceptRedline( SwRedlineTable::size_type nPos, bool
else
nLoopCnt = 0;
- } while( nLoopCnt );
+ } while (nLoopCnt);
if( bRet )
{
@@ -2731,7 +3172,7 @@ bool DocumentRedlineManager::AcceptRedline( SwRedlineTable::size_type nPos, bool
// #TODO - add 'SwExtraRedlineTable' also ?
}
-bool DocumentRedlineManager::AcceptRedline( const SwPaM& rPam, bool bCallDelete )
+bool DocumentRedlineManager::AcceptRedline( const SwPaM& rPam, bool bCallDelete, sal_Int8 nDepth )
{
// Switch to visible in any case
if( (RedlineFlags::ShowInsert | RedlineFlags::ShowDelete) !=
@@ -2741,17 +3182,34 @@ bool DocumentRedlineManager::AcceptRedline( const SwPaM& rPam, bool bCallDelete
// The Selection is only in the ContentSection. If there are Redlines
// to Non-ContentNodes before or after that, then the Selections
// expand to them.
- SwPaM aPam( *rPam.GetMark(), *rPam.GetPoint() );
- lcl_AdjustRedlineRange( aPam );
+ std::shared_ptr<SwUnoCursor> const pPam(m_rDoc.CreateUnoCursor(*rPam.GetPoint(), false));
+ if (rPam.HasMark())
+ {
+ pPam->SetMark();
+ *pPam->GetMark() = *rPam.GetMark();
+ }
+ lcl_AdjustRedlineRange(*pPam);
if (m_rDoc.GetIDocumentUndoRedo().DoesUndo())
{
m_rDoc.GetIDocumentUndoRedo().StartUndo( SwUndoId::ACCEPT_REDLINE, nullptr );
- m_rDoc.GetIDocumentUndoRedo().AppendUndo( std::make_unique<SwUndoAcceptRedline>( aPam ));
+ m_rDoc.GetIDocumentUndoRedo().AppendUndo(
+ std::make_unique<SwUndoAcceptRedline>(*pPam, nDepth));
}
- int nRet = lcl_AcceptRejectRedl( lcl_AcceptRedline, *mpRedlineTable,
- bCallDelete, aPam );
+ int nRet = 0;
+ if (nDepth == 0)
+ {
+ nRet = lcl_AcceptRejectRedl(lcl_AcceptRedline, maRedlineTable, bCallDelete, *pPam);
+ }
+ else
+ {
+ // For now it is called only if it is an Insert redline in a delete redline.
+ SwRedlineTable::size_type nRdlIdx = 0;
+ maRedlineTable.FindAtPosition(*rPam.Start(), nRdlIdx);
+ if (lcl_AcceptInnerInsertRedline(maRedlineTable, nRdlIdx, 1))
+ nRet = 1;
+ }
if( nRet > 0 )
{
CompressRedlines();
@@ -2779,19 +3237,18 @@ bool DocumentRedlineManager::AcceptRedline( const SwPaM& rPam, bool bCallDelete
void DocumentRedlineManager::AcceptRedlineParagraphFormatting( const SwPaM &rPam )
{
- const SwPosition* pStt = rPam.Start(),
- * pEnd = pStt == rPam.GetPoint() ? rPam.GetMark()
- : rPam.GetPoint();
+ auto [pStt, pEnd] = rPam.StartEnd(); // SwPosition*
- const sal_uLong nSttIdx = pStt->nNode.GetIndex();
- const sal_uLong nEndIdx = pEnd->nNode.GetIndex();
+ const SwNodeOffset nSttIdx = pStt->GetNodeIndex();
+ const SwNodeOffset nEndIdx = pEnd->GetNodeIndex();
- for( SwRedlineTable::size_type n = 0; n < mpRedlineTable->size() ; ++n )
+ for( SwRedlineTable::size_type n = 0; n < maRedlineTable.size() ; ++n )
{
- const SwRangeRedline* pTmp = (*mpRedlineTable)[ n ];
- sal_uLong nPt = pTmp->GetPoint()->nNode.GetIndex(),
- nMk = pTmp->GetMark()->nNode.GetIndex();
- if( nPt < nMk ) { tools::Long nTmp = nMk; nMk = nPt; nPt = nTmp; }
+ const SwRangeRedline* pTmp = maRedlineTable[ n ];
+ SwNodeOffset nPt = pTmp->GetPoint()->GetNodeIndex(),
+ nMk = pTmp->GetMark()->GetNodeIndex();
+ if( nPt < nMk )
+ std::swap( nMk, nPt );
if( RedlineType::ParagraphFormat == pTmp->GetType() &&
( (nSttIdx <= nMk && nMk <= nEndIdx) || (nSttIdx <= nPt && nPt <= nEndIdx) ) )
@@ -2802,7 +3259,114 @@ void DocumentRedlineManager::AcceptRedlineParagraphFormatting( const SwPaM &rPam
}
}
-bool DocumentRedlineManager::RejectRedline( SwRedlineTable::size_type nPos, bool bCallDelete )
+bool DocumentRedlineManager::RejectRedlineRange(SwRedlineTable::size_type nPosOrigin,
+ SwRedlineTable::size_type& nPosStart,
+ SwRedlineTable::size_type& nPosEnd,
+ bool bCallDelete)
+{
+ bool bRet = false;
+
+ SwRangeRedline* pTmp = maRedlineTable[nPosOrigin];
+ SwRedlineTable::size_type nRdlIdx = nPosEnd + 1;
+ SwRedlineData aOrigData = pTmp->GetRedlineData(0);
+
+ SwNodeOffset nPamStartNI = maRedlineTable[nPosStart]->Start()->GetNodeIndex();
+ sal_Int32 nPamStartCI = maRedlineTable[nPosStart]->Start()->GetContentIndex();
+ SwNodeOffset nPamEndtNI = maRedlineTable[nPosEnd]->End()->GetNodeIndex();
+ sal_Int32 nPamEndCI = maRedlineTable[nPosEnd]->End()->GetContentIndex();
+ do
+ {
+ nRdlIdx--;
+ pTmp = maRedlineTable[nRdlIdx];
+ if (pTmp->Start()->GetNodeIndex() < nPamStartNI
+ || (pTmp->Start()->GetNodeIndex() == nPamStartNI
+ && pTmp->Start()->GetContentIndex() < nPamStartCI))
+ break;
+
+ if (pTmp->End()->GetNodeIndex() > nPamEndtNI
+ || (pTmp->End()->GetNodeIndex() == nPamEndtNI
+ && pTmp->End()->GetContentIndex() > nPamEndCI))
+ {
+ }
+ else if (pTmp->GetRedlineData(0).CanCombineForAcceptReject(aOrigData))
+ {
+ if (m_rDoc.GetIDocumentUndoRedo().DoesUndo())
+ {
+ std::unique_ptr<SwUndoRejectRedline> pUndoRdl
+ = std::make_unique<SwUndoRejectRedline>(*pTmp);
+#if OSL_DEBUG_LEVEL > 0
+ pUndoRdl->SetRedlineCountDontCheck(true);
+#endif
+ m_rDoc.GetIDocumentUndoRedo().AppendUndo(std::move(pUndoRdl));
+ }
+ nPamEndtNI = pTmp->Start()->GetNodeIndex();
+ nPamEndCI = pTmp->Start()->GetContentIndex();
+ bRet |= lcl_RejectRedline(maRedlineTable, nRdlIdx, bCallDelete);
+ nRdlIdx++; //we will decrease it in the loop anyway.
+ }
+ else if (aOrigData.GetType() == RedlineType::Insert
+ && pTmp->GetType() == RedlineType::Delete && pTmp->GetStackCount() > 1
+ && pTmp->GetType(1) == RedlineType::Insert
+ && pTmp->GetRedlineData(1).CanCombineForAcceptReject(aOrigData))
+ {
+ // The Insert redline we want to reject has a deletion redline too
+ // without the insert, the delete is meaningless
+ // so we rather just accept the deletion redline
+ if (m_rDoc.GetIDocumentUndoRedo().DoesUndo())
+ {
+ std::unique_ptr<SwUndoRejectRedline> pUndoRdl
+ = std::make_unique<SwUndoRejectRedline>(*pTmp, 1);
+#if OSL_DEBUG_LEVEL > 0
+ pUndoRdl->SetRedlineCountDontCheck(true);
+#endif
+ m_rDoc.GetIDocumentUndoRedo().AppendUndo(std::move(pUndoRdl));
+ }
+ nPamEndtNI = pTmp->Start()->GetNodeIndex();
+ nPamEndCI = pTmp->Start()->GetContentIndex();
+ bRet |= lcl_AcceptRedline(maRedlineTable, nRdlIdx, bCallDelete);
+ nRdlIdx++; //we will decrease it in the loop anyway.
+ }
+
+ } while (nRdlIdx > 0);
+ return bRet;
+}
+
+bool DocumentRedlineManager::RejectMovedRedlines(sal_uInt32 nMovedID, bool bCallDelete)
+{
+ assert(nMovedID > 1); // 0, and 1 is reserved
+ bool bRet = false;
+ SwRedlineTable::size_type nRdlIdx = maRedlineTable.size();
+
+ while (nRdlIdx > 0)
+ {
+ nRdlIdx--;
+ SwRangeRedline* pTmp = maRedlineTable[nRdlIdx];
+ if (pTmp->GetMoved(0) == nMovedID
+ || (pTmp->GetStackCount() > 1 && pTmp->GetMoved(1) == nMovedID))
+ {
+ if (m_rDoc.GetIDocumentUndoRedo().DoesUndo())
+ {
+ std::unique_ptr<SwUndoRejectRedline> pUndoRdl
+ = std::make_unique<SwUndoRejectRedline>(*pTmp);
+#if OSL_DEBUG_LEVEL > 0
+ pUndoRdl->SetRedlineCountDontCheck(true);
+#endif
+ m_rDoc.GetIDocumentUndoRedo().AppendUndo(std::move(pUndoRdl));
+ }
+
+ if (pTmp->GetMoved(0) == nMovedID)
+ bRet |= lcl_RejectRedline(maRedlineTable, nRdlIdx, bCallDelete);
+ else
+ bRet |= lcl_AcceptRedline(maRedlineTable, nRdlIdx, bCallDelete);
+
+ nRdlIdx++; //we will decrease it in the loop anyway.
+ }
+ }
+ return bRet;
+}
+
+bool DocumentRedlineManager::RejectRedline(SwRedlineTable::size_type nPos,
+ bool bCallDelete, bool bRange)
{
bool bRet = false;
@@ -2811,9 +3375,11 @@ bool DocumentRedlineManager::RejectRedline( SwRedlineTable::size_type nPos, bool
(RedlineFlags::ShowMask & meRedlineFlags) )
SetRedlineFlags( RedlineFlags::ShowInsert | RedlineFlags::ShowDelete | meRedlineFlags );
- SwRangeRedline* pTmp = (*mpRedlineTable)[ nPos ];
- pTmp->Show(0, mpRedlineTable->GetPos(pTmp), /*bForced=*/true);
- pTmp->Show(1, mpRedlineTable->GetPos(pTmp), /*bForced=*/true);
+ SwRangeRedline* pTmp = maRedlineTable[ nPos ];
+ bool bAnonym = pTmp->GetRedlineData(0).IsAnonymized();
+
+ pTmp->Show(0, maRedlineTable.GetPos(pTmp), /*bForced=*/true);
+ pTmp->Show(1, maRedlineTable.GetPos(pTmp), /*bForced=*/true);
if( pTmp->HasMark() && pTmp->IsVisible() )
{
if (m_rDoc.GetIDocumentUndoRedo().DoesUndo())
@@ -2827,7 +3393,28 @@ bool DocumentRedlineManager::RejectRedline( SwRedlineTable::size_type nPos, bool
int nLoopCnt = 2;
sal_uInt16 nSeqNo = pTmp->GetSeqNo();
- do {
+ if (bRange && !nSeqNo && !bAnonym
+ && !pTmp->Start()->GetNode().StartOfSectionNode()->IsTableNode())
+ {
+ sal_uInt32 nMovedID = pTmp->GetMoved(0);
+ if (nMovedID > 1)
+ {
+ // Reject all redlineData with this unique move id
+ bRet |= RejectMovedRedlines(nMovedID, bCallDelete);
+ }
+ else
+ {
+ SwRedlineTable::size_type nPosStart = nPos;
+ SwRedlineTable::size_type nPosEnd = nPos;
+ maRedlineTable.getConnectedArea(nPos, nPosStart, nPosEnd, true);
+
+ // Reject items between pPamStart-pPamEnd
+ // but only those that can be combined with the selected.
+
+ bRet |= RejectRedlineRange(nPos, nPosStart, nPosEnd, bCallDelete);
+ }
+ }
+ else do {
if (m_rDoc.GetIDocumentUndoRedo().DoesUndo())
{
@@ -2835,21 +3422,21 @@ bool DocumentRedlineManager::RejectRedline( SwRedlineTable::size_type nPos, bool
std::make_unique<SwUndoRejectRedline>( *pTmp ) );
}
- bRet |= lcl_RejectRedline( *mpRedlineTable, nPos, bCallDelete );
+ bRet |= lcl_RejectRedline( maRedlineTable, nPos, bCallDelete );
if( nSeqNo )
{
if( SwRedlineTable::npos == nPos )
nPos = 0;
SwRedlineTable::size_type nFndPos = 2 == nLoopCnt
- ? mpRedlineTable->FindNextSeqNo( nSeqNo, nPos )
- : mpRedlineTable->FindPrevSeqNo( nSeqNo, nPos );
+ ? maRedlineTable.FindNextSeqNo( nSeqNo, nPos )
+ : maRedlineTable.FindPrevSeqNo( nSeqNo, nPos );
if( SwRedlineTable::npos != nFndPos || ( 0 != ( --nLoopCnt ) &&
SwRedlineTable::npos != ( nFndPos =
- mpRedlineTable->FindPrevSeqNo( nSeqNo, nPos ))) )
+ maRedlineTable.FindPrevSeqNo( nSeqNo, nPos ))) )
{
nPos = nFndPos;
- pTmp = (*mpRedlineTable)[ nPos ];
+ pTmp = maRedlineTable[ nPos ];
}
else
nLoopCnt = 0;
@@ -2857,7 +3444,7 @@ bool DocumentRedlineManager::RejectRedline( SwRedlineTable::size_type nPos, bool
else
nLoopCnt = 0;
- } while( nLoopCnt );
+ } while (nLoopCnt);
if( bRet )
{
@@ -2875,7 +3462,7 @@ bool DocumentRedlineManager::RejectRedline( SwRedlineTable::size_type nPos, bool
// #TODO - add 'SwExtraRedlineTable' also ?
}
-bool DocumentRedlineManager::RejectRedline( const SwPaM& rPam, bool bCallDelete )
+bool DocumentRedlineManager::RejectRedline( const SwPaM& rPam, bool bCallDelete, sal_Int8 nDepth )
{
// Switch to visible in any case
if( (RedlineFlags::ShowInsert | RedlineFlags::ShowDelete) !=
@@ -2891,11 +3478,23 @@ bool DocumentRedlineManager::RejectRedline( const SwPaM& rPam, bool bCallDelete
if (m_rDoc.GetIDocumentUndoRedo().DoesUndo())
{
m_rDoc.GetIDocumentUndoRedo().StartUndo( SwUndoId::REJECT_REDLINE, nullptr );
- m_rDoc.GetIDocumentUndoRedo().AppendUndo( std::make_unique<SwUndoRejectRedline>(aPam) );
+ m_rDoc.GetIDocumentUndoRedo().AppendUndo( std::make_unique<SwUndoRejectRedline>(aPam, nDepth) );
+ }
+
+ int nRet = 0;
+ if (nDepth == 0)
+ {
+ nRet = lcl_AcceptRejectRedl(lcl_RejectRedline, maRedlineTable, bCallDelete, aPam);
+ }
+ else
+ {
+ // For now it is called only if it is an Insert redline in a delete redline.
+ SwRedlineTable::size_type nRdlIdx = 0;
+ maRedlineTable.FindAtPosition(*rPam.Start(), nRdlIdx);
+ if (lcl_AcceptRedline(maRedlineTable, nRdlIdx, bCallDelete))
+ nRet = 1;
}
- int nRet = lcl_AcceptRejectRedl( lcl_RejectRedline, *mpRedlineTable,
- bCallDelete, aPam );
if( nRet > 0 )
{
CompressRedlines();
@@ -2928,11 +3527,11 @@ void DocumentRedlineManager::AcceptAllRedline(bool bAccept)
OUString sUndoStr;
IDocumentUndoRedo& rUndoMgr = m_rDoc.GetIDocumentUndoRedo();
- if (mpRedlineTable->size() > 1)
+ if (maRedlineTable.size() > 1)
{
{
SwRewriter aRewriter;
- aRewriter.AddRule(UndoArg1, OUString::number(mpRedlineTable->size()));
+ aRewriter.AddRule(UndoArg1, OUString::number(maRedlineTable.size()));
sUndoStr = aRewriter.Apply(SwResId(STR_N_REDLINES));
}
@@ -2941,12 +3540,12 @@ void DocumentRedlineManager::AcceptAllRedline(bool bAccept)
rUndoMgr.StartUndo(bAccept ? SwUndoId::ACCEPT_REDLINE : SwUndoId::REJECT_REDLINE, &aRewriter);
}
- while (!mpRedlineTable->empty() && bSuccess)
+ while (!maRedlineTable.empty() && bSuccess)
{
if (bAccept)
- bSuccess = AcceptRedline(mpRedlineTable->size() - 1, true);
+ bSuccess = AcceptRedline(maRedlineTable.size() - 1, true);
else
- bSuccess = RejectRedline(mpRedlineTable->size() - 1, true);
+ bSuccess = RejectRedline(maRedlineTable.size() - 1, true);
}
if (!sUndoStr.isEmpty())
@@ -2971,12 +3570,12 @@ const SwRangeRedline* DocumentRedlineManager::SelNextRedline( SwPaM& rPam ) cons
if( pFnd )
{
const SwPosition* pEnd = pFnd->End();
- if( !pEnd->nNode.GetNode().IsContentNode() )
+ if( !pEnd->GetNode().IsContentNode() )
{
- SwNodeIndex aTmp( pEnd->nNode );
+ SwNodeIndex aTmp( pEnd->GetNode() );
SwContentNode* pCNd = SwNodes::GoPrevSection( &aTmp );
- if( !pCNd || ( aTmp == rSttPos.nNode &&
- pCNd->Len() == rSttPos.nContent.GetIndex() ))
+ if( !pCNd || ( aTmp == rSttPos.GetNode() &&
+ pCNd->Len() == rSttPos.GetContentIndex() ))
pFnd = nullptr;
}
if( pFnd )
@@ -2986,9 +3585,9 @@ const SwRangeRedline* DocumentRedlineManager::SelNextRedline( SwPaM& rPam ) cons
do {
bRestart = false;
- for( ; !pFnd && n < mpRedlineTable->size(); ++n )
+ for( ; !pFnd && n < maRedlineTable.size(); ++n )
{
- pFnd = (*mpRedlineTable)[ n ];
+ pFnd = maRedlineTable[ n ];
if( pFnd->HasMark() && pFnd->IsVisible() )
{
*rPam.GetMark() = *pFnd->Start();
@@ -3004,9 +3603,9 @@ const SwRangeRedline* DocumentRedlineManager::SelNextRedline( SwPaM& rPam ) cons
// Merge all of the same type and author that are
// consecutive into one Selection.
const SwPosition* pPrevEnd = pFnd->End();
- while( ++n < mpRedlineTable->size() )
+ while( ++n < maRedlineTable.size() )
{
- const SwRangeRedline* pTmp = (*mpRedlineTable)[ n ];
+ const SwRangeRedline* pTmp = maRedlineTable[ n ];
if( pTmp->HasMark() && pTmp->IsVisible() )
{
const SwPosition *pRStt;
@@ -3030,14 +3629,14 @@ const SwRangeRedline* DocumentRedlineManager::SelNextRedline( SwPaM& rPam ) cons
const SwRangeRedline* pSaveFnd = pFnd;
SwContentNode* pCNd;
- SwNodeIndex* pIdx = &rPam.GetMark()->nNode;
- if( !pIdx->GetNode().IsContentNode() )
+ SwPosition* pPos = rPam.GetMark();
+ if( !pPos->GetNode().IsContentNode() )
{
- pCNd = m_rDoc.GetNodes().GoNextSection( pIdx );
+ pCNd = SwNodes::GoNextSection(pPos);
if( pCNd )
{
- if( *pIdx <= rPam.GetPoint()->nNode )
- rPam.GetMark()->nContent.Assign( pCNd, 0 );
+ if( pPos->GetNode() <= rPam.GetPoint()->GetNode() )
+ pPos->Assign( *pCNd, 0 );
else
pFnd = nullptr;
}
@@ -3045,14 +3644,14 @@ const SwRangeRedline* DocumentRedlineManager::SelNextRedline( SwPaM& rPam ) cons
if( pFnd )
{
- pIdx = &rPam.GetPoint()->nNode;
- if( !pIdx->GetNode().IsContentNode() )
+ pPos = rPam.GetPoint();
+ if( !pPos->GetNode().IsContentNode() )
{
- pCNd = SwNodes::GoPrevSection( pIdx );
+ pCNd = SwNodes::GoPrevSection( pPos );
if( pCNd )
{
- if( *pIdx >= rPam.GetMark()->nNode )
- rPam.GetPoint()->nContent.Assign( pCNd, pCNd->Len() );
+ if( pPos->GetNode() >= rPam.GetMark()->GetNode() )
+ pPos->Assign( *pCNd, pCNd->Len() );
else
pFnd = nullptr;
}
@@ -3061,7 +3660,7 @@ const SwRangeRedline* DocumentRedlineManager::SelNextRedline( SwPaM& rPam ) cons
if( !pFnd || *rPam.GetMark() == *rPam.GetPoint() )
{
- if( n < mpRedlineTable->size() )
+ if( n < maRedlineTable.size() )
{
bRestart = true;
*rPam.GetPoint() = *pSaveFnd->End();
@@ -3097,12 +3696,12 @@ const SwRangeRedline* DocumentRedlineManager::SelPrevRedline( SwPaM& rPam ) cons
if( pFnd )
{
const SwPosition* pStt = pFnd->Start();
- if( !pStt->nNode.GetNode().IsContentNode() )
+ if( !pStt->GetNode().IsContentNode() )
{
- SwNodeIndex aTmp( pStt->nNode );
- SwContentNode* pCNd = m_rDoc.GetNodes().GoNextSection( &aTmp );
- if( !pCNd || ( aTmp == rSttPos.nNode &&
- !rSttPos.nContent.GetIndex() ))
+ SwNodeIndex aTmp( pStt->GetNode() );
+ SwContentNode* pCNd = SwNodes::GoNextSection(&aTmp);
+ if( !pCNd || ( aTmp == rSttPos.GetNode() &&
+ !rSttPos.GetContentIndex() ))
pFnd = nullptr;
}
if( pFnd )
@@ -3114,7 +3713,7 @@ const SwRangeRedline* DocumentRedlineManager::SelPrevRedline( SwPaM& rPam ) cons
while( !pFnd && 0 < n )
{
- pFnd = (*mpRedlineTable)[ --n ];
+ pFnd = maRedlineTable[ --n ];
if( pFnd->HasMark() && pFnd->IsVisible() )
{
*rPam.GetMark() = *pFnd->End();
@@ -3131,7 +3730,7 @@ const SwRangeRedline* DocumentRedlineManager::SelPrevRedline( SwPaM& rPam ) cons
const SwPosition* pNextStt = pFnd->Start();
while( 0 < n )
{
- const SwRangeRedline* pTmp = (*mpRedlineTable)[ --n ];
+ const SwRangeRedline* pTmp = maRedlineTable[ --n ];
if( pTmp->HasMark() && pTmp->IsVisible() )
{
const SwPosition *pREnd;
@@ -3157,14 +3756,14 @@ const SwRangeRedline* DocumentRedlineManager::SelPrevRedline( SwPaM& rPam ) cons
const SwRangeRedline* pSaveFnd = pFnd;
SwContentNode* pCNd;
- SwNodeIndex* pIdx = &rPam.GetMark()->nNode;
- if( !pIdx->GetNode().IsContentNode() )
+ SwPosition* pPos = rPam.GetMark();
+ if( !pPos->GetNode().IsContentNode() )
{
- pCNd = SwNodes::GoPrevSection( pIdx );
+ pCNd = SwNodes::GoPrevSection( pPos );
if( pCNd )
{
- if( *pIdx >= rPam.GetPoint()->nNode )
- rPam.GetMark()->nContent.Assign( pCNd, pCNd->Len() );
+ if( pPos->GetNode() >= rPam.GetPoint()->GetNode() )
+ pPos->Assign( *pCNd, pCNd->Len() );
else
pFnd = nullptr;
}
@@ -3172,14 +3771,14 @@ const SwRangeRedline* DocumentRedlineManager::SelPrevRedline( SwPaM& rPam ) cons
if( pFnd )
{
- pIdx = &rPam.GetPoint()->nNode;
- if( !pIdx->GetNode().IsContentNode() )
+ pPos = rPam.GetPoint();
+ if( !pPos->GetNode().IsContentNode() )
{
- pCNd = m_rDoc.GetNodes().GoNextSection( pIdx );
+ pCNd = SwNodes::GoNextSection(pPos);
if( pCNd )
{
- if( *pIdx <= rPam.GetMark()->nNode )
- rPam.GetPoint()->nContent.Assign( pCNd, 0 );
+ if( pPos->GetNode() <= rPam.GetMark()->GetNode() )
+ pPos->Assign( *pCNd, 0 );
else
pFnd = nullptr;
}
@@ -3212,16 +3811,14 @@ const SwRangeRedline* DocumentRedlineManager::SelPrevRedline( SwPaM& rPam ) cons
bool DocumentRedlineManager::SetRedlineComment( const SwPaM& rPaM, const OUString& rS )
{
bool bRet = false;
- const SwPosition* pStt = rPaM.Start(),
- * pEnd = pStt == rPaM.GetPoint() ? rPaM.GetMark()
- : rPaM.GetPoint();
+ auto [pStt, pEnd] = rPaM.StartEnd(); // SwPosition*
SwRedlineTable::size_type n = 0;
if( GetRedlineTable().FindAtPosition( *pStt, n ) )
{
- for( ; n < mpRedlineTable->size(); ++n )
+ for( ; n < maRedlineTable.size(); ++n )
{
bRet = true;
- SwRangeRedline* pTmp = (*mpRedlineTable)[ n ];
+ SwRangeRedline* pTmp = maRedlineTable[ n ];
if( pStt != pEnd && *pTmp->Start() > *pEnd )
break;
@@ -3283,11 +3880,11 @@ void DocumentRedlineManager::SetAutoFormatRedlineComment( const OUString* pText,
m_rDoc.SetAutoFormatRedline( nullptr != pText );
if( pText )
{
- mpAutoFormatRedlnComment.reset( new OUString( *pText ) );
+ moAutoFormatRedlnComment = *pText;
}
else
{
- mpAutoFormatRedlnComment.reset();
+ moAutoFormatRedlnComment.reset();
}
mnAutoFormatRedlnCommentNo = nSeqNo;