diff options
author | Michael Stahl <mstahl@redhat.com> | 2012-12-19 23:53:11 +0100 |
---|---|---|
committer | Michael Stahl <mstahl@redhat.com> | 2012-12-20 14:11:44 +0100 |
commit | 72e3dd4d8ab6fe4368972a761c70185d1742855d (patch) | |
tree | ca3ff0d60ecd7138389a80c8a3a882f5fc997d3f /sw | |
parent | 91a90acc033cfadb0cc7bf271fa9ea92c4c52e88 (diff) |
SwUndoInserts should not use a SwPosition:
There is a problem here; to see it paste something 3 times, then undo
twice and close the document, there is a SwIndexReg assertion because
the SwPosition in the one SwUndoInserts points to a node in the Undo
nodes array that is removed by the dtor of the other SwUndoInserts.
This is because the Undo objects are destroyed from the outermost Redo
backwards, which is usually a good idea but does not work for
SwUndoInserts, which (as they currently are) must be destroyed in the
other order.
But with the previous change to only store whole paragraphs in
SwUndoSaveCntnt it is possible to replace the SwPosition here with
a SwNodeIndex, which points directly to the SwTxtNode and thus does
not care if the position of that node changes due to whatever order
other SwUndoInserts are removed.
Change-Id: I4f0cf308d26f6b2e5aaa8997951c03ae7b2f0951
Diffstat (limited to 'sw')
-rw-r--r-- | sw/inc/undobj.hxx | 4 | ||||
-rw-r--r-- | sw/source/core/undo/untblk.cxx | 39 |
2 files changed, 17 insertions, 26 deletions
diff --git a/sw/inc/undobj.hxx b/sw/inc/undobj.hxx index 4fbd74ab96de..5148327a6b13 100644 --- a/sw/inc/undobj.hxx +++ b/sw/inc/undobj.hxx @@ -21,6 +21,7 @@ #include <vector> +#include <boost/scoped_ptr.hpp> #include <boost/shared_ptr.hpp> #include <svl/undo.hxx> @@ -230,7 +231,8 @@ class SwUndoInserts : public SwUndo, public SwUndRng, private SwUndoSaveCntnt sal_Bool bSttWasTxtNd; protected: sal_uLong nNdDiff; - SwPosition *pPos; // Content for Redo. + /// start of Content in UndoNodes for Redo + ::boost::scoped_ptr<SwNodeIndex> m_pUndoNodeIndex; sal_uInt16 nSetPos; // Start in the history list. SwUndoInserts( SwUndoId nUndoId, const SwPaM& ); diff --git a/sw/source/core/undo/untblk.cxx b/sw/source/core/undo/untblk.cxx index 48457172966d..407edbaf6c7b 100644 --- a/sw/source/core/undo/untblk.cxx +++ b/sw/source/core/undo/untblk.cxx @@ -34,7 +34,7 @@ SwUndoInserts::SwUndoInserts( SwUndoId nUndoId, const SwPaM& rPam ) : SwUndo( nUndoId ), SwUndRng( rPam ), pTxtFmtColl( 0 ), pLastNdColl(0), pFrmFmts( 0 ), pRedlData( 0 ), - bSttWasTxtNd( sal_True ), nNdDiff( 0 ), pPos( 0 ), nSetPos( 0 ) + bSttWasTxtNd( sal_True ), nNdDiff( 0 ), nSetPos( 0 ) { pHistory = new SwHistory; SwDoc* pDoc = (SwDoc*)rPam.GetDoc(); @@ -131,24 +131,13 @@ void SwUndoInserts::SetInsertRange( const SwPaM& rPam, sal_Bool bScanFlys, SwUndoInserts::~SwUndoInserts() { - if( pPos ) // delete also the section from UndoNodes array + if (m_pUndoNodeIndex) // delete also the section from UndoNodes array { // Insert saves content in IconSection - SwNodes& rUNds = pPos->nNode.GetNodes(); - if( pPos->nContent.GetIndex() ) // do not delete complete Node - { - SwTxtNode* pTxtNd = pPos->nNode.GetNode().GetTxtNode(); - OSL_ENSURE( pTxtNd, "no TextNode to delete from" ); - if( pTxtNd ) // robust - { - pTxtNd->EraseText( pPos->nContent ); - } - pPos->nNode++; - } - pPos->nContent.Assign( 0, 0 ); - rUNds.Delete( pPos->nNode, rUNds.GetEndOfExtras().GetIndex() - - pPos->nNode.GetIndex() ); - delete pPos; + SwNodes& rUNds = m_pUndoNodeIndex->GetNodes(); + rUNds.Delete(*m_pUndoNodeIndex, + rUNds.GetEndOfExtras().GetIndex() - m_pUndoNodeIndex->GetIndex()); + m_pUndoNodeIndex.reset(); } delete pFrmFmts; delete pRedlData; @@ -189,8 +178,9 @@ void SwUndoInserts::UndoImpl(::sw::UndoRedoContext & rContext) if( *pPam->GetPoint() != *pPam->GetMark() ) { - pPos = new SwPosition( *pPam->GetPoint() ); - MoveToUndoNds( *pPam, &pPos->nNode, &pPos->nContent ); + m_pUndoNodeIndex.reset( + new SwNodeIndex(pDoc->GetNodes().GetEndOfContent())); + MoveToUndoNds( *pPam, m_pUndoNodeIndex.get(), 0 ); if( !bSttWasTxtNd ) pPam->Move( fnMoveBackward, fnGoCntnt ); @@ -269,15 +259,14 @@ void SwUndoInserts::RedoImpl(::sw::UndoRedoContext & rContext) pHistory->SetTmpEnd( nSetPos ); // retrieve start position for rollback - if( ( nSttNode != nEndNode || nSttCntnt != nEndCntnt ) && pPos ) + if( ( nSttNode != nEndNode || nSttCntnt != nEndCntnt ) && m_pUndoNodeIndex) { sal_Bool bMvBkwrd = MovePtBackward( *pPam ); - // re-insert content again (first detach pPos!) - sal_uLong nMvNd = pPos->nNode.GetIndex(); - xub_StrLen nMvCnt = pPos->nContent.GetIndex(); - DELETEZ( pPos ); - MoveFromUndoNds( *pDoc, nMvNd, nMvCnt, *pPam->GetMark() ); + // re-insert content again (first detach m_pUndoNodeIndex!) + sal_uLong const nMvNd = m_pUndoNodeIndex->GetIndex(); + m_pUndoNodeIndex.reset(); + MoveFromUndoNds( *pDoc, nMvNd, 0, *pPam->GetMark() ); if( bSttWasTxtNd ) MovePtForward( *pPam, bMvBkwrd ); pPam->Exchange(); |