summaryrefslogtreecommitdiff
path: root/sw
diff options
context:
space:
mode:
authorMichael Stahl <mstahl@redhat.com>2013-05-16 12:01:30 +0200
committerMichael Stahl <mstahl@redhat.com>2013-05-16 12:38:31 +0200
commitc7b883498cb47a7d2a330057dbcd7f74f87a0184 (patch)
treeb9371aa6523970f625d83265202f3a850b47f3e9 /sw
parent87bdc30851af21d9d29b36de07261c682eb70227 (diff)
SwDoc::CopyImpl: avoid ~SwIndexReg assertions:
These happen when enabling change tracking, deleting a full paragraph (incl. paragraph break) and then copying the deleted paragraph to the clipboard; the "rPos" and "aCpyPam" SwPositions are registered at a node that is deleted by lcl_DeleteRedlines. Change-Id: I3e9e29548d23377807c26fdd401b3c9637fddf25
Diffstat (limited to 'sw')
-rw-r--r--sw/source/core/docnode/ndcopy.cxx75
1 files changed, 42 insertions, 33 deletions
diff --git a/sw/source/core/docnode/ndcopy.cxx b/sw/source/core/docnode/ndcopy.cxx
index bbff535250e7..deefc128203d 100644
--- a/sw/source/core/docnode/ndcopy.cxx
+++ b/sw/source/core/docnode/ndcopy.cxx
@@ -31,6 +31,7 @@
#include <fldbas.hxx>
#include <swtable.hxx>
#include <ddefld.hxx>
+#include <unocrsr.hxx>
#include <undobj.hxx>
#include <IMark.hxx>
#include <mvsave.hxx>
@@ -865,13 +866,15 @@ bool SwDoc::CopyImpl( SwPaM& rPam, SwPosition& rPos,
// If Undo is enabled, create the UndoCopy object
SwUndoCpyDoc* pUndo = 0;
- SwPaM aCpyPam( rPos );
+ // lcl_DeleteRedlines may delete the start or end node of the cursor when
+ // removing the redlines so use cursor that is corrected by PaMCorrAbs
+ ::boost::scoped_ptr<SwUnoCrsr> const pCopyPam(pDoc->CreateUnoCrsr(rPos));
SwTblNumFmtMerge aTNFM( *this, *pDoc );
if (pDoc->GetIDocumentUndoRedo().DoesUndo())
{
- pUndo = new SwUndoCpyDoc( aCpyPam );
+ pUndo = new SwUndoCpyDoc(*pCopyPam);
pDoc->GetIDocumentUndoRedo().AppendUndo( pUndo );
}
@@ -880,21 +883,21 @@ bool SwDoc::CopyImpl( SwPaM& rPam, SwPosition& rPos,
// Move the PaM one node back from the insert position, so that
// the position doesn't get moved
- aCpyPam.SetMark();
- sal_Bool bCanMoveBack = aCpyPam.Move( fnMoveBackward, fnGoCntnt );
+ pCopyPam->SetMark();
+ sal_Bool bCanMoveBack = pCopyPam->Move(fnMoveBackward, fnGoCntnt);
// If the position was shifted from more than one node, an end node has been skipped
bool bAfterTable = false;
- if ( ( rPos.nNode.GetIndex() - aCpyPam.GetPoint()->nNode.GetIndex() ) > 1 )
+ if ((rPos.nNode.GetIndex() - pCopyPam->GetPoint()->nNode.GetIndex()) > 1)
{
// First go back to the original place
- aCpyPam.GetPoint()->nNode = rPos.nNode;
- aCpyPam.GetPoint()->nContent = rPos.nContent;
+ pCopyPam->GetPoint()->nNode = rPos.nNode;
+ pCopyPam->GetPoint()->nContent = rPos.nContent;
bCanMoveBack = false;
bAfterTable = true;
}
if( !bCanMoveBack )
- aCpyPam.GetPoint()->nNode--;
+ pCopyPam->GetPoint()->nNode--;
SwNodeRange aRg( pStt->nNode, pEnd->nNode );
SwNodeIndex aInsPos( rPos.nNode );
@@ -969,11 +972,11 @@ bool SwDoc::CopyImpl( SwPaM& rPam, SwPosition& rPos,
pDoc->SplitNode( rPos, false );
}
- if( bCanMoveBack && rPos == *aCpyPam.GetPoint() )
+ if (bCanMoveBack && rPos == *pCopyPam->GetPoint())
{
// after the SplitNode, span the CpyPam correctly again
- aCpyPam.Move( fnMoveBackward, fnGoCntnt );
- aCpyPam.Move( fnMoveBackward, fnGoCntnt );
+ pCopyPam->Move( fnMoveBackward, fnGoCntnt );
+ pCopyPam->Move( fnMoveBackward, fnGoCntnt );
}
pDestTxtNd = pDoc->GetNodes()[ aInsPos.GetIndex()-1 ]->GetTxtNode();
@@ -1096,11 +1099,11 @@ bool SwDoc::CopyImpl( SwPaM& rPam, SwPosition& rPos,
pDoc->SplitNode( rPos, false );
}
- if( bCanMoveBack && rPos == *aCpyPam.GetPoint() )
+ if (bCanMoveBack && rPos == *pCopyPam->GetPoint())
{
// after the SplitNode, span the CpyPam correctly again
- aCpyPam.Move( fnMoveBackward, fnGoCntnt );
- aCpyPam.Move( fnMoveBackward, fnGoCntnt );
+ pCopyPam->Move( fnMoveBackward, fnGoCntnt );
+ pCopyPam->Move( fnMoveBackward, fnGoCntnt );
}
// Correct the area again
@@ -1122,9 +1125,9 @@ bool SwDoc::CopyImpl( SwPaM& rPam, SwPosition& rPos,
// See below, before the SetInsertRange funciton of the undo object will be called,
// the CpyPam would be moved to the next content position. This has to be avoided
// We want to be moved to the table node itself thus we have to set bCanMoveBack
- // and to manipulate aCpyPam.
+ // and to manipulate pCopyPam.
bCanMoveBack = false;
- aCpyPam.GetPoint()->nNode--;
+ pCopyPam->GetPoint()->nNode--;
}
}
@@ -1236,7 +1239,7 @@ bool SwDoc::CopyImpl( SwPaM& rPam, SwPosition& rPos,
// Put the breaks back into the first node
if( aBrkSet.Count() && 0 != ( pDestTxtNd = pDoc->GetNodes()[
- aCpyPam.GetPoint()->nNode.GetIndex()+1 ]->GetTxtNode() ) )
+ pCopyPam->GetPoint()->nNode.GetIndex()+1 ]->GetTxtNode()))
{
pDestTxtNd->SetAttr( aBrkSet );
}
@@ -1249,53 +1252,59 @@ bool SwDoc::CopyImpl( SwPaM& rPam, SwPosition& rPos,
if( rPos.nNode != aInsPos )
{
- aCpyPam.GetMark()->nNode = aInsPos;
- aCpyPam.GetMark()->nContent.Assign( aCpyPam.GetCntntNode(sal_False), 0 );
- rPos = *aCpyPam.GetMark();
+ pCopyPam->GetMark()->nNode = aInsPos;
+ pCopyPam->GetMark()->nContent.Assign(pCopyPam->GetCntntNode(sal_False), 0);
+ rPos = *pCopyPam->GetMark();
}
else
- *aCpyPam.GetMark() = rPos;
+ *pCopyPam->GetMark() = rPos;
if ( !bAfterTable )
- aCpyPam.Move( fnMoveForward, bCanMoveBack ? fnGoCntnt : fnGoNode );
+ pCopyPam->Move( fnMoveForward, bCanMoveBack ? fnGoCntnt : fnGoNode );
else
{
// Reset the offset to 0 as it was before the insertion
- aCpyPam.GetPoint( )->nContent -= aCpyPam.GetPoint( )->nContent;
+ pCopyPam->GetPoint()->nContent -= pCopyPam->GetPoint()->nContent;
- aCpyPam.GetPoint( )->nNode++;
+ pCopyPam->GetPoint()->nNode++;
// If the next node is a start node, then step back: the start node
// has been copied and needs to be in the selection for the undo
- if ( aCpyPam.GetPoint()->nNode.GetNode().IsStartNode() )
- aCpyPam.GetPoint( )->nNode--;
+ if (pCopyPam->GetPoint()->nNode.GetNode().IsStartNode())
+ pCopyPam->GetPoint()->nNode--;
}
- aCpyPam.Exchange();
+ pCopyPam->Exchange();
// Also copy all bookmarks
if( bCopyBookmarks && getIDocumentMarkAccess()->getMarksCount() )
- lcl_CopyBookmarks( rPam, aCpyPam );
+ lcl_CopyBookmarks( rPam, *pCopyPam );
if( nsRedlineMode_t::REDLINE_DELETE_REDLINES & eOld )
- lcl_DeleteRedlines( rPam, aCpyPam );
+ {
+ assert(*pCopyPam->GetPoint() == rPos);
+ // the Node rPos points to may be deleted so unregister ...
+ rPos.nContent = SwIndex(0);
+ lcl_DeleteRedlines(rPam, *pCopyPam);
+ rPos = *pCopyPam->GetPoint(); // ... and restore.
+ }
// If Undo is enabled, store the inserted area
if (pDoc->GetIDocumentUndoRedo().DoesUndo())
{
- pUndo->SetInsertRange( aCpyPam, sal_True, bStartIsTxtNode );
+ pUndo->SetInsertRange( *pCopyPam, sal_True, bStartIsTxtNode );
}
if( pCpyRange )
{
pCpyRange->SetMark();
- *pCpyRange->GetPoint() = *aCpyPam.GetPoint();
- *pCpyRange->GetMark() = *aCpyPam.GetMark();
+ *pCpyRange->GetPoint() = *pCopyPam->GetPoint();
+ *pCpyRange->GetMark() = *pCopyPam->GetMark();
}
if ( pNumRuleToPropagate )
{
// #i86492# - use <SwDoc::SetNumRule(..)>, because it also handles the <ListId>
- pDoc->SetNumRule( aCpyPam, *pNumRuleToPropagate, false,
+ pDoc->SetNumRule( *pCopyPam, *pNumRuleToPropagate, false,
aListIdToPropagate, sal_True, true );
}