summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Stahl <mstahl@redhat.com>2012-12-19 23:53:11 +0100
committerMichael Stahl <mstahl@redhat.com>2012-12-20 14:11:44 +0100
commit72e3dd4d8ab6fe4368972a761c70185d1742855d (patch)
treeca3ff0d60ecd7138389a80c8a3a882f5fc997d3f
parent91a90acc033cfadb0cc7bf271fa9ea92c4c52e88 (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
-rw-r--r--sw/inc/undobj.hxx4
-rw-r--r--sw/source/core/undo/untblk.cxx39
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();