diff options
author | Michael Stahl <mstahl@redhat.com> | 2013-05-16 12:01:30 +0200 |
---|---|---|
committer | Michael Stahl <mstahl@redhat.com> | 2013-05-16 12:38:31 +0200 |
commit | c7b883498cb47a7d2a330057dbcd7f74f87a0184 (patch) | |
tree | b9371aa6523970f625d83265202f3a850b47f3e9 /sw | |
parent | 87bdc30851af21d9d29b36de07261c682eb70227 (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.cxx | 75 |
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 ); } |