Kaydet (Commit) 72e3dd4d authored tarafından Michael Stahl's avatar Michael Stahl

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
üst 91a90acc
......@@ -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& );
......
......@@ -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();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment