2000-09-18 23:08:29 +00:00
|
|
|
/*************************************************************************
|
|
|
|
*
|
2008-04-10 15:03:27 +00:00
|
|
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
2000-09-18 23:08:29 +00:00
|
|
|
*
|
2010-02-12 15:01:35 +01:00
|
|
|
* Copyright 2000, 2010 Oracle and/or its affiliates.
|
2000-09-18 23:08:29 +00:00
|
|
|
*
|
2008-04-10 15:03:27 +00:00
|
|
|
* OpenOffice.org - a multi-platform office productivity suite
|
2000-09-18 23:08:29 +00:00
|
|
|
*
|
2008-04-10 15:03:27 +00:00
|
|
|
* This file is part of OpenOffice.org.
|
2000-09-18 23:08:29 +00:00
|
|
|
*
|
2008-04-10 15:03:27 +00:00
|
|
|
* OpenOffice.org is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU Lesser General Public License version 3
|
|
|
|
* only, as published by the Free Software Foundation.
|
2000-09-18 23:08:29 +00:00
|
|
|
*
|
2008-04-10 15:03:27 +00:00
|
|
|
* OpenOffice.org is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU Lesser General Public License version 3 for more details
|
|
|
|
* (a copy is included in the LICENSE file that accompanied this code).
|
2000-09-18 23:08:29 +00:00
|
|
|
*
|
2008-04-10 15:03:27 +00:00
|
|
|
* You should have received a copy of the GNU Lesser General Public License
|
|
|
|
* version 3 along with OpenOffice.org. If not, see
|
|
|
|
* <http://www.openoffice.org/license.html>
|
|
|
|
* for a copy of the LGPLv3 License.
|
2000-09-18 23:08:29 +00:00
|
|
|
*
|
|
|
|
************************************************************************/
|
|
|
|
|
2006-09-16 20:49:45 +00:00
|
|
|
// MARKER(update_precomp.py): autogen include statement, do not remove
|
|
|
|
#include "precompiled_sw.hxx"
|
|
|
|
|
2010-11-25 14:31:07 +01:00
|
|
|
#include <UndoManager.hxx>
|
|
|
|
|
2010-11-25 14:31:11 +01:00
|
|
|
#include <unotools/undoopt.hxx>
|
|
|
|
|
2010-11-25 14:31:10 +01:00
|
|
|
#include <vcl/wrkwin.hxx>
|
|
|
|
|
2009-06-04 16:21:29 +00:00
|
|
|
#include <svx/svdmodel.hxx>
|
2000-09-18 23:08:29 +00:00
|
|
|
|
2010-11-25 14:31:11 +01:00
|
|
|
#include <swmodule.hxx>
|
2000-09-18 23:08:29 +00:00
|
|
|
#include <doc.hxx>
|
2010-11-25 14:31:10 +01:00
|
|
|
#include <ndarr.hxx>
|
2000-09-18 23:08:29 +00:00
|
|
|
#include <pam.hxx>
|
|
|
|
#include <ndtxt.hxx>
|
|
|
|
#include <swundo.hxx> // fuer die UndoIds
|
|
|
|
#include <undobj.hxx>
|
|
|
|
#include <rolbck.hxx>
|
|
|
|
#include <docary.hxx>
|
2004-05-18 13:06:14 +00:00
|
|
|
#include <undo.hrc>
|
2000-09-18 23:08:29 +00:00
|
|
|
|
2007-09-27 08:29:16 +00:00
|
|
|
|
|
|
|
using namespace ::com::sun::star;
|
|
|
|
|
|
|
|
|
2002-06-03 11:35:54 +00:00
|
|
|
// the undo array should never grow beyond this limit:
|
|
|
|
#define UNDO_ACTION_LIMIT (USHRT_MAX - 1000)
|
|
|
|
|
|
|
|
|
2000-09-18 23:08:29 +00:00
|
|
|
//#define _SHOW_UNDORANGE
|
|
|
|
#ifdef _SHOW_UNDORANGE
|
|
|
|
|
|
|
|
|
|
|
|
class UndoArrStatus : public WorkWindow
|
|
|
|
{
|
|
|
|
USHORT nUndo, nUndoNds;
|
|
|
|
virtual void Paint( const Rectangle& );
|
|
|
|
public:
|
|
|
|
UndoArrStatus();
|
|
|
|
void Set( USHORT, USHORT );
|
|
|
|
};
|
|
|
|
static UndoArrStatus* pUndoMsgWin = 0;
|
|
|
|
|
|
|
|
|
|
|
|
UndoArrStatus::UndoArrStatus()
|
|
|
|
: WorkWindow( APP_GETAPPWINDOW() ), nUndo(0), nUndoNds(0)
|
|
|
|
{
|
|
|
|
SetSizePixel( Size( 200, 100 ));
|
|
|
|
SetFont( Font( "Courier", Size( 0, 10 )) );
|
|
|
|
Show();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void UndoArrStatus::Set( USHORT n1, USHORT n2 )
|
|
|
|
{
|
|
|
|
nUndo = n1; nUndoNds = n2;
|
|
|
|
Invalidate();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void UndoArrStatus::Paint( const Rectangle& )
|
|
|
|
{
|
|
|
|
String s;
|
|
|
|
DrawRect( Rectangle( Point(0,0), GetOutputSize() ));
|
|
|
|
( s = "Undos: " ) += nUndo;
|
|
|
|
DrawText( Point( 0, 0 ), s );
|
|
|
|
( s = "UndoNodes: " ) += nUndoNds;
|
|
|
|
DrawText( Point( 0, 15 ), s );
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
2010-11-25 14:31:07 +01:00
|
|
|
|
|
|
|
// UndoManager ///////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
namespace sw {
|
|
|
|
|
2010-11-25 14:31:11 +01:00
|
|
|
UndoManager::UndoManager(::std::auto_ptr<SwNodes> pUndoNodes,
|
|
|
|
IDocumentDrawModelAccess & rDrawModelAccess,
|
|
|
|
IDocumentRedlineAccess & rRedlineAccess,
|
|
|
|
IDocumentState & rState)
|
|
|
|
: m_rDrawModelAccess(rDrawModelAccess)
|
|
|
|
, m_rRedlineAccess(rRedlineAccess)
|
|
|
|
, m_rState(rState)
|
|
|
|
, m_pUndoNodes(pUndoNodes)
|
2010-11-25 14:31:11 +01:00
|
|
|
, m_pUndos( new SwUndos( 0, 20 ) )
|
|
|
|
, m_nUndoPos(0)
|
|
|
|
, m_nUndoSavePos(0)
|
|
|
|
, m_nUndoActions(0)
|
|
|
|
, m_nNestingDepth(0)
|
|
|
|
, m_bUndo(false)
|
|
|
|
, m_bGroupUndo(true)
|
2010-11-25 14:31:11 +01:00
|
|
|
, m_bDrawUndo(true)
|
2010-11-25 14:31:10 +01:00
|
|
|
, m_bLockUndoNoModifiedPosition(false)
|
2010-11-25 14:31:07 +01:00
|
|
|
{
|
2010-11-25 14:31:11 +01:00
|
|
|
OSL_ASSERT(m_pUndoNodes.get());
|
2010-11-25 14:31:07 +01:00
|
|
|
}
|
|
|
|
|
2010-11-25 14:31:10 +01:00
|
|
|
SwNodes const& UndoManager::GetUndoNodes() const
|
|
|
|
{
|
|
|
|
return *m_pUndoNodes;
|
|
|
|
}
|
|
|
|
|
|
|
|
SwNodes & UndoManager::GetUndoNodes()
|
|
|
|
{
|
|
|
|
return *m_pUndoNodes;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool UndoManager::IsUndoNodes(SwNodes const& rNodes) const
|
2010-11-25 14:31:07 +01:00
|
|
|
{
|
2010-11-25 14:31:10 +01:00
|
|
|
return & rNodes == m_pUndoNodes.get();
|
2010-11-25 14:31:07 +01:00
|
|
|
}
|
|
|
|
|
2010-11-25 14:31:10 +01:00
|
|
|
void UndoManager::DoUndo(bool const bDoUndo)
|
2010-11-25 14:31:07 +01:00
|
|
|
{
|
2010-11-25 14:31:11 +01:00
|
|
|
m_bUndo = bDoUndo;
|
2010-11-25 14:31:07 +01:00
|
|
|
|
2010-11-25 14:31:11 +01:00
|
|
|
SdrModel *const pSdrModel = m_rDrawModelAccess.GetDrawModel();
|
2010-11-25 14:31:07 +01:00
|
|
|
if( pSdrModel )
|
2010-11-25 14:31:10 +01:00
|
|
|
{
|
|
|
|
pSdrModel->EnableUndo(bDoUndo);
|
|
|
|
}
|
2010-11-25 14:31:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
bool UndoManager::DoesUndo() const
|
|
|
|
{
|
2010-11-25 14:31:11 +01:00
|
|
|
return m_bUndo;
|
2010-11-25 14:31:07 +01:00
|
|
|
}
|
|
|
|
|
2010-11-25 14:31:10 +01:00
|
|
|
void UndoManager::DoGroupUndo(bool const bDoUndo)
|
2010-11-25 14:31:07 +01:00
|
|
|
{
|
2010-11-25 14:31:11 +01:00
|
|
|
m_bGroupUndo = bDoUndo;
|
2010-11-25 14:31:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
bool UndoManager::DoesGroupUndo() const
|
|
|
|
{
|
2010-11-25 14:31:11 +01:00
|
|
|
return m_bGroupUndo;
|
2010-11-25 14:31:07 +01:00
|
|
|
}
|
|
|
|
|
2010-11-25 14:31:11 +01:00
|
|
|
void UndoManager::DoDrawUndo(bool const bDoUndo)
|
|
|
|
{
|
|
|
|
m_bDrawUndo = bDoUndo;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool UndoManager::DoesDrawUndo() const
|
|
|
|
{
|
|
|
|
return m_bDrawUndo;
|
|
|
|
}
|
|
|
|
|
2010-11-25 14:31:10 +01:00
|
|
|
|
|
|
|
bool UndoManager::IsUndoNoResetModified() const
|
|
|
|
{
|
2010-11-25 14:31:11 +01:00
|
|
|
return USHRT_MAX == m_nUndoSavePos;
|
2010-11-25 14:31:10 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void UndoManager::SetUndoNoResetModified()
|
|
|
|
{
|
2010-11-25 14:31:11 +01:00
|
|
|
m_nUndoSavePos = USHRT_MAX;
|
2010-11-25 14:31:10 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void UndoManager::SetUndoNoModifiedPosition()
|
|
|
|
{
|
|
|
|
if (!m_bLockUndoNoModifiedPosition)
|
|
|
|
{
|
2010-11-25 14:31:11 +01:00
|
|
|
m_nUndoSavePos = (m_pUndos->Count())
|
|
|
|
? m_nUndoPos
|
2010-11-25 14:31:10 +01:00
|
|
|
: USHRT_MAX;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void UndoManager::LockUndoNoModifiedPosition()
|
|
|
|
{
|
|
|
|
m_bLockUndoNoModifiedPosition = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void UndoManager::UnLockUndoNoModifiedPosition()
|
|
|
|
{
|
|
|
|
m_bLockUndoNoModifiedPosition = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-11-25 14:31:07 +01:00
|
|
|
SwUndo* UndoManager::GetLastUndo()
|
|
|
|
{
|
2010-11-25 14:31:11 +01:00
|
|
|
return (0 == m_nUndoPos)
|
|
|
|
? 0
|
|
|
|
: (*m_pUndos)[m_nUndoPos-1];
|
2010-11-25 14:31:07 +01:00
|
|
|
}
|
|
|
|
|
2010-11-25 14:31:10 +01:00
|
|
|
void UndoManager::AppendUndo(SwUndo *const pUndo)
|
2006-08-14 15:48:33 +00:00
|
|
|
{
|
2010-12-15 09:14:06 +01:00
|
|
|
OSL_ENSURE(DoesUndo(), "AppendUndo called with Undo disabled?");
|
|
|
|
if (!DoesUndo())
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2007-09-27 08:29:16 +00:00
|
|
|
if( nsRedlineMode_t::REDLINE_NONE == pUndo->GetRedlineMode() )
|
2010-11-25 14:31:07 +01:00
|
|
|
{
|
2010-11-25 14:31:11 +01:00
|
|
|
pUndo->SetRedlineMode( m_rRedlineAccess.GetRedlineMode() );
|
2010-11-25 14:31:07 +01:00
|
|
|
}
|
2000-09-18 23:08:29 +00:00
|
|
|
|
2002-06-03 11:35:54 +00:00
|
|
|
// Unfortunately, the silly SvPtrArr can only store a little less than
|
|
|
|
// USHRT_MAX elements. Of course it doesn't see any necessity for asserting
|
|
|
|
// or even doing error handling. pUndos should definitely be replaced by an
|
|
|
|
// STL container that doesn't have this problem. cf #95884#
|
2010-11-25 14:31:11 +01:00
|
|
|
OSL_ENSURE( m_pUndos->Count() < USHRT_MAX - 16,
|
2002-06-03 11:35:54 +00:00
|
|
|
"Writer will crash soon. I apologize for the inconvenience." );
|
|
|
|
|
2010-11-25 14:31:11 +01:00
|
|
|
m_pUndos->Insert(pUndo, m_nUndoPos);
|
|
|
|
++m_nUndoPos;
|
2000-09-18 23:08:29 +00:00
|
|
|
switch( pUndo->GetId() )
|
|
|
|
{
|
2010-11-25 14:31:11 +01:00
|
|
|
case UNDO_START:
|
|
|
|
++m_nNestingDepth;
|
|
|
|
break;
|
2000-09-18 23:08:29 +00:00
|
|
|
|
2010-11-25 14:31:11 +01:00
|
|
|
case UNDO_END:
|
|
|
|
OSL_ENSURE(m_nNestingDepth, "AppendUndo(): Undo-End without Start");
|
|
|
|
--m_nNestingDepth;
|
|
|
|
// no break !
|
|
|
|
|
|
|
|
default:
|
|
|
|
if ((m_pUndos->Count() != m_nUndoPos) &&
|
|
|
|
(UNDO_END != pUndo->GetId()))
|
|
|
|
{
|
|
|
|
ClearRedo();
|
|
|
|
}
|
|
|
|
OSL_ENSURE( m_pUndos->Count() == m_nUndoPos
|
|
|
|
|| UNDO_END == pUndo->GetId(),
|
|
|
|
"AppendUndo(): Redo history not deleted!" );
|
|
|
|
if (!m_nNestingDepth)
|
|
|
|
{
|
|
|
|
++m_nUndoActions;
|
|
|
|
}
|
2001-09-27 12:44:28 +00:00
|
|
|
break;
|
2000-09-18 23:08:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef _SHOW_UNDORANGE
|
|
|
|
// zur Anzeige der aktuellen Undo-Groessen
|
|
|
|
if( !pUndoMsgWin )
|
|
|
|
pUndoMsgWin = new UndoArrStatus;
|
2010-11-25 14:31:11 +01:00
|
|
|
pUndoMsgWin->Set( m_pUndos->Count(), GetUndoNodes()->Count() );
|
2000-09-18 23:08:29 +00:00
|
|
|
#endif
|
|
|
|
|
2010-11-25 14:31:11 +01:00
|
|
|
// if the bracketing is still open, nothing more to do here
|
|
|
|
if (m_nNestingDepth)
|
|
|
|
{
|
2000-09-18 23:08:29 +00:00
|
|
|
return;
|
2010-11-25 14:31:11 +01:00
|
|
|
}
|
2000-09-18 23:08:29 +00:00
|
|
|
|
|
|
|
// folgende Array-Grenzen muessen ueberwacht werden:
|
|
|
|
// - Undo, Grenze: fester Wert oder USHRT_MAX - 1000
|
|
|
|
// - UndoNodes, Grenze: USHRT_MAX - 1000
|
|
|
|
// - AttrHistory Grenze: USHRT_MAX - 1000
|
2002-06-03 11:35:54 +00:00
|
|
|
// (defined in UNDO_ACTION_LIMIT at the top of this file)
|
2000-09-18 23:08:29 +00:00
|
|
|
|
2002-06-03 11:35:54 +00:00
|
|
|
USHORT nEnde = UNDO_ACTION_LIMIT;
|
2000-09-18 23:08:29 +00:00
|
|
|
|
2009-07-10 14:03:42 +02:00
|
|
|
#ifdef DBG_UTIL
|
2000-09-18 23:08:29 +00:00
|
|
|
{
|
2007-09-27 08:29:16 +00:00
|
|
|
USHORT nUndosCnt = 0, nSttEndCnt = 0;
|
2010-11-25 14:31:11 +01:00
|
|
|
for (USHORT nCnt = 0; nCnt < m_nUndoPos; ++nCnt)
|
2000-09-18 23:08:29 +00:00
|
|
|
{
|
2010-11-25 14:31:11 +01:00
|
|
|
SwUndoId const nId = (*m_pUndos)[ nCnt ]->GetId();
|
|
|
|
if (UNDO_START == nId)
|
|
|
|
{
|
2000-09-18 23:08:29 +00:00
|
|
|
++nSttEndCnt;
|
2010-11-25 14:31:11 +01:00
|
|
|
}
|
2000-09-18 23:08:29 +00:00
|
|
|
else if( UNDO_END == nId )
|
|
|
|
--nSttEndCnt;
|
|
|
|
if( !nSttEndCnt )
|
|
|
|
++nUndosCnt;
|
|
|
|
}
|
2010-11-25 14:31:11 +01:00
|
|
|
OSL_ENSURE(nSttEndCnt == m_nNestingDepth,
|
|
|
|
"AppendUndo(): nesting depth is wrong");
|
|
|
|
OSL_ENSURE(nUndosCnt == m_nUndoActions,
|
|
|
|
"AppendUndo(): Undo action count is wrong");
|
2000-09-18 23:08:29 +00:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2010-11-25 14:31:11 +01:00
|
|
|
sal_Int32 const nActions(SW_MOD()->GetUndoOptions().GetUndoCount());
|
2010-11-25 14:31:11 +01:00
|
|
|
if (nActions < m_nUndoActions)
|
2010-11-25 14:31:07 +01:00
|
|
|
{
|
2000-09-18 23:08:29 +00:00
|
|
|
// immer 1/10 loeschen
|
|
|
|
//JP 23.09.95: oder wenn neu eingestellt wurde um die Differenz
|
2001-05-29 08:08:52 +00:00
|
|
|
//JP 29.5.2001: Task #83891#: remove only the overlapping actions
|
2010-11-26 11:48:32 +01:00
|
|
|
DelUndoObj( sal_uInt16( m_nUndoActions - nActions ) );
|
2010-11-25 14:31:07 +01:00
|
|
|
}
|
2000-09-18 23:08:29 +00:00
|
|
|
else
|
|
|
|
{
|
2010-11-25 14:31:11 +01:00
|
|
|
USHORT const nUndosCnt = m_nUndoActions;
|
2000-09-18 23:08:29 +00:00
|
|
|
// immer 1/10 loeschen bis der "Ausloeser" behoben ist
|
2010-11-25 14:31:10 +01:00
|
|
|
while (nEnde < GetUndoNodes().Count())
|
2010-11-25 14:31:07 +01:00
|
|
|
{
|
2000-09-18 23:08:29 +00:00
|
|
|
DelUndoObj( nUndosCnt / 10 );
|
2010-11-25 14:31:07 +01:00
|
|
|
}
|
2000-09-18 23:08:29 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-11-25 14:31:07 +01:00
|
|
|
void UndoManager::ClearRedo()
|
2000-09-18 23:08:29 +00:00
|
|
|
{
|
2010-11-25 14:31:11 +01:00
|
|
|
if (m_nUndoPos != m_pUndos->Count())
|
2000-09-18 23:08:29 +00:00
|
|
|
{
|
2010-11-25 14:31:11 +01:00
|
|
|
// update m_nUndoActions
|
|
|
|
for (USHORT nCnt = m_pUndos->Count(); m_nUndoPos < nCnt;
|
|
|
|
--m_nUndoActions)
|
2000-09-18 23:08:29 +00:00
|
|
|
{
|
2010-11-25 14:31:11 +01:00
|
|
|
// skip Start/End bracketing
|
|
|
|
SwUndo *const pUndo = (*m_pUndos)[ --nCnt ];
|
|
|
|
if (UNDO_END == pUndo->GetId())
|
|
|
|
{
|
|
|
|
nCnt = nCnt - static_cast<SwUndoEnd*>(pUndo)->GetSttOffset();
|
|
|
|
}
|
2000-09-18 23:08:29 +00:00
|
|
|
}
|
|
|
|
|
2010-11-25 14:31:11 +01:00
|
|
|
// delete Undo actions in reverse order!
|
|
|
|
m_pUndos->DeleteAndDestroy(m_nUndoPos, m_pUndos->Count() - m_nUndoPos);
|
2000-09-18 23:08:29 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-11-25 14:31:07 +01:00
|
|
|
void UndoManager::DelAllUndoObj()
|
2000-09-18 23:08:29 +00:00
|
|
|
{
|
2010-11-25 14:31:09 +01:00
|
|
|
::sw::UndoGuard const undoGuard(*this);
|
2000-09-18 23:08:29 +00:00
|
|
|
|
2010-11-25 14:31:09 +01:00
|
|
|
ClearRedo();
|
2000-09-18 23:08:29 +00:00
|
|
|
|
2010-11-25 14:31:11 +01:00
|
|
|
// retain open Start bracketing!
|
|
|
|
USHORT nSize = m_pUndos->Count();
|
2000-09-18 23:08:29 +00:00
|
|
|
while( nSize )
|
2010-11-25 14:31:11 +01:00
|
|
|
{
|
|
|
|
SwUndo *const pUndo = (*m_pUndos)[ --nSize ];
|
|
|
|
if ((UNDO_START != pUndo->GetId()) ||
|
|
|
|
// bracketing closed with End?
|
|
|
|
static_cast<SwUndoStart*>(pUndo)->GetEndOffset())
|
|
|
|
{
|
|
|
|
m_pUndos->DeleteAndDestroy( nSize, 1 );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
m_nUndoActions = 0;
|
|
|
|
m_nUndoPos = m_pUndos->Count();
|
|
|
|
|
|
|
|
m_nUndoSavePos = USHRT_MAX;
|
2000-09-18 23:08:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-11-25 14:31:07 +01:00
|
|
|
bool UndoManager::DelUndoObj( sal_uInt16 nEnd )
|
2000-09-18 23:08:29 +00:00
|
|
|
{
|
2010-11-25 14:31:07 +01:00
|
|
|
if (0 == nEnd) // in case 0 is passed in
|
2000-09-18 23:08:29 +00:00
|
|
|
{
|
2010-11-25 14:31:11 +01:00
|
|
|
if (!m_pUndos->Count())
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
2010-11-25 14:31:07 +01:00
|
|
|
++nEnd; // correct it to 1 // FIXME why ???
|
2000-09-18 23:08:29 +00:00
|
|
|
}
|
|
|
|
|
2010-11-25 14:31:09 +01:00
|
|
|
::sw::UndoGuard const undoGuard(*this);
|
2000-09-18 23:08:29 +00:00
|
|
|
|
2010-11-25 14:31:11 +01:00
|
|
|
// check where the end is
|
2007-09-27 08:29:16 +00:00
|
|
|
USHORT nSttEndCnt = 0;
|
2003-12-01 16:23:31 +00:00
|
|
|
USHORT nCnt;
|
|
|
|
|
2010-11-25 14:31:11 +01:00
|
|
|
for (nCnt = 0; nEnd && nCnt < m_nUndoPos; ++nCnt)
|
2000-09-18 23:08:29 +00:00
|
|
|
{
|
2010-11-25 14:31:11 +01:00
|
|
|
SwUndoId const nId = (*m_pUndos)[ nCnt ]->GetId();
|
|
|
|
if (UNDO_START == nId)
|
|
|
|
{
|
2000-09-18 23:08:29 +00:00
|
|
|
++nSttEndCnt;
|
2010-11-25 14:31:11 +01:00
|
|
|
}
|
2000-09-18 23:08:29 +00:00
|
|
|
else if( UNDO_END == nId )
|
2010-11-25 14:31:11 +01:00
|
|
|
{
|
2000-09-18 23:08:29 +00:00
|
|
|
--nSttEndCnt;
|
2010-11-25 14:31:11 +01:00
|
|
|
}
|
2000-09-18 23:08:29 +00:00
|
|
|
if( !nSttEndCnt )
|
2010-11-25 14:31:11 +01:00
|
|
|
{
|
|
|
|
--nEnd, --m_nUndoActions;
|
|
|
|
}
|
2000-09-18 23:08:29 +00:00
|
|
|
}
|
|
|
|
|
2010-11-25 14:31:11 +01:00
|
|
|
OSL_ENSURE( nCnt < m_nUndoPos || m_nUndoPos == m_pUndos->Count(),
|
|
|
|
"DelUndoObj(): end inside of Redo actions!" );
|
2000-09-18 23:08:29 +00:00
|
|
|
|
2010-11-25 14:31:11 +01:00
|
|
|
// update positions
|
|
|
|
nSttEndCnt = nCnt;
|
|
|
|
if (m_nUndoSavePos < nSttEndCnt) // abandon SavePos
|
|
|
|
{
|
|
|
|
m_nUndoSavePos = USHRT_MAX;
|
|
|
|
}
|
|
|
|
else if (m_nUndoSavePos != USHRT_MAX)
|
|
|
|
{
|
|
|
|
m_nUndoSavePos = m_nUndoSavePos - nSttEndCnt;
|
|
|
|
}
|
2000-09-18 23:08:29 +00:00
|
|
|
|
|
|
|
while( nSttEndCnt )
|
2010-11-25 14:31:11 +01:00
|
|
|
{
|
|
|
|
m_pUndos->DeleteAndDestroy( --nSttEndCnt, 1 );
|
|
|
|
}
|
|
|
|
m_nUndoPos = m_pUndos->Count();
|
2000-09-18 23:08:29 +00:00
|
|
|
|
2010-11-25 14:31:11 +01:00
|
|
|
return true;
|
2000-09-18 23:08:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**************** UNDO ******************/
|
|
|
|
|
2010-11-25 14:31:10 +01:00
|
|
|
bool UndoManager::HasUndoId(SwUndoId const eId) const
|
2000-09-18 23:08:29 +00:00
|
|
|
{
|
2010-11-25 14:31:11 +01:00
|
|
|
USHORT nSize = m_nUndoPos;
|
2000-09-18 23:08:29 +00:00
|
|
|
while( nSize-- )
|
2010-11-25 14:31:11 +01:00
|
|
|
{
|
|
|
|
SwUndo *const pUndo = (*m_pUndos)[nSize];
|
|
|
|
if ((pUndo->GetId() == eId) ||
|
2000-09-18 23:08:29 +00:00
|
|
|
( UNDO_START == pUndo->GetId() &&
|
2010-11-25 14:31:11 +01:00
|
|
|
(static_cast<SwUndoStart*>(pUndo)->GetUserId() == eId))
|
2000-09-18 23:08:29 +00:00
|
|
|
|| ( UNDO_END == pUndo->GetId() &&
|
2010-11-25 14:31:11 +01:00
|
|
|
(static_cast<SwUndoEnd*>(pUndo)->GetUserId() == eId)))
|
2000-09-18 23:08:29 +00:00
|
|
|
{
|
2010-11-25 14:31:11 +01:00
|
|
|
return true;
|
2000-09-18 23:08:29 +00:00
|
|
|
}
|
2010-11-25 14:31:11 +01:00
|
|
|
}
|
2000-09-18 23:08:29 +00:00
|
|
|
|
2010-11-25 14:31:11 +01:00
|
|
|
return false;
|
2000-09-18 23:08:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-11-25 14:31:07 +01:00
|
|
|
bool UndoManager::Undo( SwUndoIter& rUndoIter )
|
2000-09-18 23:08:29 +00:00
|
|
|
{
|
|
|
|
if ( (rUndoIter.GetId()!=0) && (!HasUndoId(rUndoIter.GetId())) )
|
|
|
|
{
|
|
|
|
rUndoIter.bWeiter = FALSE;
|
2010-11-25 14:31:11 +01:00
|
|
|
return false;
|
2000-09-18 23:08:29 +00:00
|
|
|
}
|
2010-11-25 14:31:11 +01:00
|
|
|
if (!m_nUndoPos)
|
2000-09-18 23:08:29 +00:00
|
|
|
{
|
|
|
|
rUndoIter.bWeiter = FALSE;
|
2010-11-25 14:31:11 +01:00
|
|
|
return false;
|
2000-09-18 23:08:29 +00:00
|
|
|
}
|
|
|
|
|
2010-12-15 09:14:06 +01:00
|
|
|
::sw::UndoGuard const undoGuard(*this);
|
|
|
|
|
2010-11-25 14:31:11 +01:00
|
|
|
SwUndo * pUndo = (*m_pUndos)[ --m_nUndoPos ];
|
2000-09-18 23:08:29 +00:00
|
|
|
|
2010-11-25 14:31:11 +01:00
|
|
|
RedlineMode_t const eOld = m_rRedlineAccess.GetRedlineMode();
|
2007-09-27 08:29:16 +00:00
|
|
|
RedlineMode_t eTmpMode = (RedlineMode_t)pUndo->GetRedlineMode();
|
|
|
|
if( (nsRedlineMode_t::REDLINE_SHOW_MASK & eTmpMode) != (nsRedlineMode_t::REDLINE_SHOW_MASK & eOld) &&
|
2000-09-18 23:08:29 +00:00
|
|
|
UNDO_START != pUndo->GetId() && UNDO_END != pUndo->GetId() )
|
2010-11-25 14:31:07 +01:00
|
|
|
{
|
2010-11-25 14:31:11 +01:00
|
|
|
m_rRedlineAccess.SetRedlineMode( eTmpMode );
|
2010-11-25 14:31:07 +01:00
|
|
|
}
|
2010-11-25 14:31:11 +01:00
|
|
|
m_rRedlineAccess.SetRedlineMode_intern(
|
2010-11-25 14:31:07 +01:00
|
|
|
static_cast<RedlineMode_t>(eTmpMode | nsRedlineMode_t::REDLINE_IGNORE));
|
2000-09-18 23:08:29 +00:00
|
|
|
|
2010-11-25 14:31:11 +01:00
|
|
|
SwUndoId const nAktId = pUndo->GetId();
|
2000-09-18 23:08:29 +00:00
|
|
|
//JP 11.05.98: FlyFormate ueber die EditShell selektieren, nicht aus dem
|
|
|
|
// Undo heraus
|
2001-11-13 12:52:46 +00:00
|
|
|
switch( nAktId )
|
|
|
|
{
|
|
|
|
case UNDO_START:
|
|
|
|
case UNDO_END:
|
|
|
|
case UNDO_INSDRAWFMT:
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
2000-09-18 23:08:29 +00:00
|
|
|
rUndoIter.ClearSelections();
|
2001-11-13 12:52:46 +00:00
|
|
|
}
|
2000-09-18 23:08:29 +00:00
|
|
|
|
|
|
|
pUndo->Undo( rUndoIter );
|
|
|
|
|
2010-11-25 14:31:11 +01:00
|
|
|
m_rRedlineAccess.SetRedlineMode( eOld );
|
2000-09-18 23:08:29 +00:00
|
|
|
|
2010-11-25 14:31:11 +01:00
|
|
|
if (m_nUndoPos && !rUndoIter.bWeiter)
|
2010-11-25 14:31:07 +01:00
|
|
|
{
|
2010-11-25 14:31:11 +01:00
|
|
|
pUndo = (*m_pUndos)[ m_nUndoPos-1 ];
|
|
|
|
if (UNDO_START == pUndo->GetId())
|
|
|
|
{
|
|
|
|
--m_nUndoPos;
|
|
|
|
}
|
2010-11-25 14:31:07 +01:00
|
|
|
}
|
2000-09-18 23:08:29 +00:00
|
|
|
|
2010-11-25 14:31:11 +01:00
|
|
|
// if we are at the "last save" position, the document is not modified
|
|
|
|
if (m_nUndoSavePos == m_nUndoPos)
|
2010-11-25 14:31:07 +01:00
|
|
|
{
|
2010-11-25 14:31:11 +01:00
|
|
|
m_rState.ResetModified();
|
2010-11-25 14:31:07 +01:00
|
|
|
}
|
2010-11-25 14:31:11 +01:00
|
|
|
// JP 29.10.96: Start und End setzen kein Modify-Flag.
|
|
|
|
// Sonst gibt es Probleme mit der autom. Aufnahme von Ausnahmen
|
|
|
|
// bei der Autokorrektur
|
|
|
|
else if ((UNDO_START != nAktId) && (UNDO_END != nAktId))
|
|
|
|
{
|
|
|
|
m_rState.SetModified();
|
|
|
|
}
|
2006-08-14 15:48:33 +00:00
|
|
|
|
2010-11-25 14:31:11 +01:00
|
|
|
return true;
|
2000-09-18 23:08:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-11-25 14:31:07 +01:00
|
|
|
SwUndoId
|
2010-11-25 14:31:10 +01:00
|
|
|
UndoManager::StartUndo(SwUndoId const i_eUndoId,
|
|
|
|
SwRewriter const*const pRewriter)
|
2000-09-18 23:08:29 +00:00
|
|
|
{
|
2010-11-25 14:31:11 +01:00
|
|
|
if (!m_bUndo)
|
|
|
|
{
|
2007-09-27 08:29:16 +00:00
|
|
|
return UNDO_EMPTY;
|
2010-11-25 14:31:11 +01:00
|
|
|
}
|
2000-09-18 23:08:29 +00:00
|
|
|
|
2010-11-25 14:31:10 +01:00
|
|
|
SwUndoId const eUndoId( (0 == i_eUndoId) ? UNDO_START : i_eUndoId );
|
2000-09-18 23:08:29 +00:00
|
|
|
|
2007-09-27 08:29:16 +00:00
|
|
|
SwUndoStart * pUndo = new SwUndoStart( eUndoId );
|
2004-05-18 13:06:14 +00:00
|
|
|
|
2010-12-15 09:14:02 +01:00
|
|
|
OSL_ASSERT(UNDO_END != eUndoId);
|
|
|
|
String comment( (UNDO_START == eUndoId)
|
|
|
|
? String("??", RTL_TEXTENCODING_ASCII_US)
|
|
|
|
: String(SW_RES(UNDO_BASE + eUndoId)) );
|
2004-05-18 13:06:14 +00:00
|
|
|
if (pRewriter)
|
2010-12-15 09:14:02 +01:00
|
|
|
{
|
|
|
|
OSL_ASSERT(UNDO_START != eUndoId);
|
|
|
|
comment = pRewriter->Apply(comment);
|
|
|
|
}
|
|
|
|
pUndo->SetComment(comment);
|
2004-05-18 13:06:14 +00:00
|
|
|
|
|
|
|
AppendUndo(pUndo);
|
|
|
|
|
2007-09-27 08:29:16 +00:00
|
|
|
return eUndoId;
|
2000-09-18 23:08:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-11-25 14:31:10 +01:00
|
|
|
SwUndoId
|
|
|
|
UndoManager::EndUndo(SwUndoId const i_eUndoId, SwRewriter const*const pRewriter)
|
2000-09-18 23:08:29 +00:00
|
|
|
{
|
2010-11-25 14:31:11 +01:00
|
|
|
USHORT nSize = m_nUndoPos;
|
|
|
|
if (!m_bUndo || !nSize--)
|
|
|
|
{
|
2007-09-27 08:29:16 +00:00
|
|
|
return UNDO_EMPTY;
|
2010-11-25 14:31:11 +01:00
|
|
|
}
|
2000-09-18 23:08:29 +00:00
|
|
|
|
2010-11-25 14:31:10 +01:00
|
|
|
SwUndoId const eUndoId( ((0 == i_eUndoId) || (UNDO_START == i_eUndoId))
|
|
|
|
? UNDO_END : i_eUndoId );
|
2000-09-18 23:08:29 +00:00
|
|
|
|
2010-11-25 14:31:11 +01:00
|
|
|
SwUndo * pUndo = (*m_pUndos)[ nSize ];
|
2000-09-18 23:08:29 +00:00
|
|
|
if( UNDO_START == pUndo->GetId() )
|
|
|
|
{
|
2010-11-25 14:31:11 +01:00
|
|
|
// empty Start/End bracketing?
|
|
|
|
m_pUndos->DeleteAndDestroy( nSize );
|
|
|
|
--m_nUndoPos;
|
|
|
|
--m_nNestingDepth;
|
2007-09-27 08:29:16 +00:00
|
|
|
return UNDO_EMPTY;
|
2000-09-18 23:08:29 +00:00
|
|
|
}
|
|
|
|
|
2001-09-27 12:44:28 +00:00
|
|
|
// exist above any redo objects? If yes, delete them
|
2010-11-25 14:31:11 +01:00
|
|
|
if (m_nUndoPos != m_pUndos->Count())
|
2001-09-27 12:44:28 +00:00
|
|
|
{
|
2010-11-25 14:31:11 +01:00
|
|
|
// update UndoCnt
|
|
|
|
for (USHORT nCnt = m_pUndos->Count(); m_nUndoPos < nCnt;
|
|
|
|
--m_nUndoActions)
|
|
|
|
{
|
|
|
|
// skip bracketing
|
|
|
|
pUndo = (*m_pUndos)[ --nCnt ];
|
|
|
|
if (UNDO_END == pUndo->GetId())
|
|
|
|
{
|
|
|
|
nCnt -= static_cast<SwUndoEnd*>(pUndo)->GetSttOffset();
|
|
|
|
}
|
|
|
|
}
|
2001-09-27 12:44:28 +00:00
|
|
|
|
2010-11-25 14:31:11 +01:00
|
|
|
m_pUndos->DeleteAndDestroy(m_nUndoPos, m_pUndos->Count() - m_nUndoPos);
|
2001-09-27 12:44:28 +00:00
|
|
|
}
|
|
|
|
|
2010-11-25 14:31:11 +01:00
|
|
|
// search for Start of this bracketing
|
|
|
|
SwUndoStart * pUndoStart(0);
|
2000-09-18 23:08:29 +00:00
|
|
|
while( nSize )
|
2010-11-25 14:31:11 +01:00
|
|
|
{
|
|
|
|
SwUndo *const pTmpUndo = (*m_pUndos)[ --nSize ];
|
|
|
|
if ((UNDO_START == pTmpUndo->GetId()) &&
|
|
|
|
!static_cast<SwUndoStart*>(pTmpUndo)->GetEndOffset())
|
|
|
|
{
|
|
|
|
pUndoStart = static_cast<SwUndoStart *>(pTmpUndo);
|
|
|
|
break; // found start
|
|
|
|
}
|
|
|
|
}
|
2000-09-18 23:08:29 +00:00
|
|
|
|
2010-11-25 14:31:11 +01:00
|
|
|
if (!pUndoStart)
|
2000-09-18 23:08:29 +00:00
|
|
|
{
|
|
|
|
// kann eigentlich nur beim Abspielen von Macros passieren, die
|
|
|
|
// Undo/Redo/Repeat benutzen und die eine exitierende Selection
|
|
|
|
// durch Einfuegen loeschen
|
2010-11-25 14:31:11 +01:00
|
|
|
OSL_ENSURE(false , "EndUndo(): corresponding UNDO_START not found");
|
|
|
|
// not found => do not insert end and reset members
|
|
|
|
|
|
|
|
m_nNestingDepth = 0;
|
|
|
|
m_nUndoActions = 0;
|
|
|
|
// update m_nUndoActions
|
|
|
|
for (USHORT nCnt = 0; nCnt < m_pUndos->Count();
|
|
|
|
++nCnt, ++m_nUndoActions)
|
|
|
|
{
|
|
|
|
// skip bracketing
|
|
|
|
SwUndo *const pTmpUndo = (*m_pUndos)[ nCnt ];
|
|
|
|
if (UNDO_START == pTmpUndo->GetId())
|
|
|
|
{
|
|
|
|
nCnt += static_cast<SwUndoStart*>(pTmpUndo)->GetEndOffset();
|
|
|
|
}
|
|
|
|
}
|
2007-09-27 08:29:16 +00:00
|
|
|
return UNDO_EMPTY;
|
2000-09-18 23:08:29 +00:00
|
|
|
}
|
|
|
|
|
2010-11-25 14:31:11 +01:00
|
|
|
// bracketing around single Undo action is unnecessary!
|
|
|
|
// except if there is a custom user ID.
|
|
|
|
if ((2 == m_pUndos->Count() - nSize) &&
|
|
|
|
((UNDO_END == eUndoId) || (eUndoId == (*m_pUndos)[ nSize+1 ]->GetId())))
|
2000-09-18 23:08:29 +00:00
|
|
|
{
|
2010-11-25 14:31:11 +01:00
|
|
|
m_pUndos->DeleteAndDestroy( nSize );
|
|
|
|
m_nUndoPos = m_pUndos->Count();
|
|
|
|
if (!--m_nNestingDepth)
|
2000-09-18 23:08:29 +00:00
|
|
|
{
|
2010-11-25 14:31:11 +01:00
|
|
|
++m_nUndoActions;
|
2010-11-25 14:31:11 +01:00
|
|
|
sal_Int32 const nActions(SW_MOD()->GetUndoOptions().GetUndoCount());
|
2010-11-25 14:31:11 +01:00
|
|
|
if (nActions < m_nUndoActions)
|
2010-11-25 14:31:07 +01:00
|
|
|
{
|
2000-09-18 23:08:29 +00:00
|
|
|
// immer 1/10 loeschen
|
|
|
|
//JP 23.09.95: oder wenn neu eingestellt wurde um die Differenz
|
2001-05-29 08:08:52 +00:00
|
|
|
//JP 29.5.2001: Task #83891#: remove only the overlapping actions
|
2010-11-26 11:48:32 +01:00
|
|
|
DelUndoObj( sal_uInt16( m_nUndoActions - nActions ) );
|
2010-11-25 14:31:07 +01:00
|
|
|
}
|
2000-09-18 23:08:29 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
USHORT nEnde = USHRT_MAX - 1000;
|
2010-11-25 14:31:11 +01:00
|
|
|
USHORT const nUndosCnt = m_nUndoActions;
|
2000-09-18 23:08:29 +00:00
|
|
|
// immer 1/10 loeschen bis der "Ausloeser" behoben ist
|
2010-11-25 14:31:10 +01:00
|
|
|
while (nEnde < GetUndoNodes().Count())
|
2010-11-25 14:31:07 +01:00
|
|
|
{
|
2000-09-18 23:08:29 +00:00
|
|
|
DelUndoObj( nUndosCnt / 10 );
|
2010-11-25 14:31:07 +01:00
|
|
|
}
|
2000-09-18 23:08:29 +00:00
|
|
|
}
|
|
|
|
}
|
2007-09-27 08:29:16 +00:00
|
|
|
return eUndoId;
|
2000-09-18 23:08:29 +00:00
|
|
|
}
|
|
|
|
|
2010-11-25 14:31:11 +01:00
|
|
|
// set offset for Start/End bracketing
|
|
|
|
nSize = m_pUndos->Count() - nSize;
|
|
|
|
pUndoStart->SetEndOffset( nSize );
|
2000-09-18 23:08:29 +00:00
|
|
|
|
2010-11-25 14:31:11 +01:00
|
|
|
SwUndoEnd *const pUndoEnd = new SwUndoEnd( eUndoId );
|
2000-09-18 23:08:29 +00:00
|
|
|
pUndoEnd->SetSttOffset( nSize );
|
|
|
|
|
|
|
|
// nur zum Testen der Start/End-Verpointerung vom Start/End Undo
|
2009-07-10 14:03:42 +02:00
|
|
|
#ifdef DBG_UTIL
|
2000-09-18 23:08:29 +00:00
|
|
|
{
|
2010-11-25 14:31:11 +01:00
|
|
|
USHORT nEndCnt = 1;
|
|
|
|
USHORT nCnt = m_pUndos->Count();
|
2007-09-27 08:29:16 +00:00
|
|
|
SwUndoId nTmpId = UNDO_EMPTY;
|
2004-05-18 13:06:14 +00:00
|
|
|
while( nCnt )
|
2000-09-18 23:08:29 +00:00
|
|
|
{
|
2010-11-25 14:31:11 +01:00
|
|
|
nTmpId = (*m_pUndos)[ --nCnt ]->GetId();
|
|
|
|
if (UNDO_START == nTmpId)
|
2004-05-18 13:06:14 +00:00
|
|
|
{
|
|
|
|
if( !nEndCnt ) // falls mal ein Start ohne Ende vorhanden ist
|
|
|
|
continue;
|
|
|
|
--nEndCnt;
|
|
|
|
if( !nEndCnt ) // hier ist der Anfang
|
|
|
|
break;
|
|
|
|
}
|
2007-09-27 08:29:16 +00:00
|
|
|
else if( UNDO_END == nTmpId )
|
2004-05-18 13:06:14 +00:00
|
|
|
++nEndCnt;
|
|
|
|
else if( !nEndCnt )
|
2000-09-18 23:08:29 +00:00
|
|
|
break;
|
|
|
|
}
|
2010-11-25 14:31:11 +01:00
|
|
|
OSL_ENSURE( nCnt == m_pUndos->Count() - nSize,
|
|
|
|
"EndUndo(): Start-End bracketing wrong" );
|
2000-09-18 23:08:29 +00:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2004-05-18 13:06:14 +00:00
|
|
|
if (pRewriter)
|
|
|
|
{
|
2010-12-15 09:14:02 +01:00
|
|
|
OSL_ASSERT(UNDO_START != eUndoId);
|
|
|
|
String const comment( (UNDO_END == eUndoId)
|
|
|
|
? String("??", RTL_TEXTENCODING_ASCII_US)
|
|
|
|
: pRewriter->Apply(String(SW_RES(UNDO_BASE + eUndoId))) );
|
|
|
|
pUndoStart->SetComment(comment);
|
|
|
|
pUndoEnd->SetComment(comment);
|
2004-05-18 13:06:14 +00:00
|
|
|
}
|
|
|
|
else
|
2010-11-25 14:31:11 +01:00
|
|
|
{
|
2010-12-15 09:14:02 +01:00
|
|
|
pUndoEnd->SetComment(pUndoStart->GetComment());
|
2010-11-25 14:31:11 +01:00
|
|
|
}
|
2004-05-18 13:06:14 +00:00
|
|
|
|
2000-09-18 23:08:29 +00:00
|
|
|
AppendUndo( pUndoEnd );
|
2007-09-27 08:29:16 +00:00
|
|
|
return eUndoId;
|
2000-09-18 23:08:29 +00:00
|
|
|
}
|
|
|
|
|
2005-01-05 15:09:05 +00:00
|
|
|
/*-- 24.11.2004 16:11:21---------------------------------------------------
|
|
|
|
|
|
|
|
-----------------------------------------------------------------------*/
|
2010-11-25 14:31:11 +01:00
|
|
|
|
2010-12-15 09:14:02 +01:00
|
|
|
typedef ::std::pair<SwUndoId, ::rtl::OUString> IdAndName_t;
|
2005-01-05 15:09:05 +00:00
|
|
|
|
2004-10-22 07:14:25 +00:00
|
|
|
/**
|
|
|
|
Returns id and comment for a certain undo object in an undo stack.
|
2000-09-18 23:08:29 +00:00
|
|
|
|
2004-10-22 07:14:25 +00:00
|
|
|
Remark: In the following the object type referred to is always the
|
|
|
|
effective object type. If an UNDO_START or UNDO_END has a user type
|
|
|
|
it is referred to as this type.
|
2000-09-18 23:08:29 +00:00
|
|
|
|
2004-10-22 07:14:25 +00:00
|
|
|
If the queried object is an UNDO_END and has no user id the result
|
|
|
|
is taken from the first object that is not an UNDO_END nor an
|
|
|
|
UNDO_START preceeding the queried object.
|
2004-05-18 13:06:14 +00:00
|
|
|
|
2004-10-22 07:14:25 +00:00
|
|
|
If the queried object is an UNDO_START and has no user id the
|
|
|
|
result is taken from the first object that is not an UNDO_END nor
|
|
|
|
an UNDO_START preceeding the UNDO_END object belonging to the
|
|
|
|
queried object.
|
2000-09-18 23:08:29 +00:00
|
|
|
|
2004-10-22 07:14:25 +00:00
|
|
|
In all other cases the result is taken from the queried object.
|
2001-04-09 06:23:08 +00:00
|
|
|
|
2004-10-22 07:14:25 +00:00
|
|
|
@param rUndos the undo stack
|
|
|
|
@param nPos position of the undo object to query
|
|
|
|
|
2010-12-15 09:14:02 +01:00
|
|
|
@return IdAndName_t object containing the query result
|
2004-10-22 07:14:25 +00:00
|
|
|
*/
|
2010-12-15 09:14:02 +01:00
|
|
|
IdAndName_t lcl_GetUndoIdAndName(const SwUndos & rUndos, sal_uInt16 nPos)
|
2004-10-22 07:14:25 +00:00
|
|
|
{
|
2007-09-27 08:29:16 +00:00
|
|
|
SwUndo * pUndo = rUndos[ nPos ];
|
|
|
|
SwUndoId nId = UNDO_EMPTY;
|
2004-10-22 07:14:25 +00:00
|
|
|
String sStr("??", RTL_TEXTENCODING_ASCII_US);
|
|
|
|
|
2010-11-25 14:31:11 +01:00
|
|
|
OSL_ENSURE( nPos < rUndos.Count(), "nPos out of range");
|
2004-10-22 07:14:25 +00:00
|
|
|
|
|
|
|
switch (pUndo->GetId())
|
|
|
|
{
|
|
|
|
case UNDO_START:
|
2001-04-09 06:23:08 +00:00
|
|
|
{
|
2004-10-22 07:14:25 +00:00
|
|
|
SwUndoStart * pUndoStart = (SwUndoStart *) pUndo;
|
|
|
|
nId = pUndoStart->GetUserId();
|
2004-05-18 13:06:14 +00:00
|
|
|
|
2004-10-22 07:14:25 +00:00
|
|
|
if (nId <= UNDO_END)
|
2004-05-18 13:06:14 +00:00
|
|
|
{
|
2004-10-22 07:14:25 +00:00
|
|
|
/**
|
|
|
|
Start at the according UNDO_END. Search backwards
|
|
|
|
for first objects that is not a UNDO_END.
|
|
|
|
*/
|
|
|
|
int nTmpPos = nPos + pUndoStart->GetEndOffset();
|
|
|
|
int nSubstitute = -1;
|
|
|
|
|
2009-10-14 17:33:11 +00:00
|
|
|
// --> OD 2009-09-30 #i105457#
|
|
|
|
if ( nTmpPos > 0 )
|
|
|
|
// <--
|
2004-05-18 13:06:14 +00:00
|
|
|
{
|
2009-10-14 17:33:11 +00:00
|
|
|
SwUndo * pTmpUndo;
|
|
|
|
do
|
|
|
|
{
|
|
|
|
nTmpPos--;
|
|
|
|
pTmpUndo = rUndos[ static_cast<USHORT>(nTmpPos) ];
|
|
|
|
|
|
|
|
if (pTmpUndo->GetEffectiveId() > UNDO_END)
|
|
|
|
nSubstitute = nTmpPos;
|
|
|
|
}
|
|
|
|
while (nSubstitute < 0 && nTmpPos > nPos);
|
|
|
|
|
|
|
|
if (nSubstitute >= 0)
|
|
|
|
{
|
|
|
|
SwUndo * pSubUndo = rUndos[ static_cast<USHORT>(nSubstitute) ];
|
|
|
|
nId = pSubUndo->GetEffectiveId();
|
|
|
|
sStr = pSubUndo->GetComment();
|
|
|
|
}
|
2004-10-22 07:14:25 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
sStr = pUndo->GetComment();
|
|
|
|
}
|
2004-05-18 13:06:14 +00:00
|
|
|
|
2004-10-22 07:14:25 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case UNDO_END:
|
|
|
|
{
|
|
|
|
SwUndoEnd * pUndoEnd = (SwUndoEnd *) pUndo;
|
|
|
|
nId = pUndoEnd->GetUserId();
|
|
|
|
|
|
|
|
if (nId <= UNDO_END)
|
|
|
|
{
|
|
|
|
/**
|
|
|
|
Start at this UNDO_END. Search backwards
|
|
|
|
for first objects that is not a UNDO_END.
|
|
|
|
*/
|
2004-05-18 13:06:14 +00:00
|
|
|
|
2004-10-22 07:14:25 +00:00
|
|
|
int nTmpPos = nPos;
|
|
|
|
int nUndoStart = nTmpPos - pUndoEnd->GetSttOffset();
|
|
|
|
int nSubstitute = -1;
|
|
|
|
|
|
|
|
if (nTmpPos > 0)
|
|
|
|
{
|
|
|
|
SwUndo * pTmpUndo;
|
|
|
|
|
|
|
|
do
|
|
|
|
{
|
|
|
|
nTmpPos--;
|
2007-09-27 08:29:16 +00:00
|
|
|
pTmpUndo = rUndos[ static_cast<USHORT>(nTmpPos) ];
|
2004-10-22 07:14:25 +00:00
|
|
|
|
|
|
|
if (pTmpUndo->GetEffectiveId() > UNDO_END)
|
|
|
|
nSubstitute = nTmpPos;
|
2004-05-18 13:06:14 +00:00
|
|
|
}
|
2004-10-22 07:14:25 +00:00
|
|
|
while (nSubstitute < 0 && nTmpPos > nUndoStart);
|
2004-05-18 13:06:14 +00:00
|
|
|
|
2004-10-22 07:14:25 +00:00
|
|
|
if (nSubstitute >= 0)
|
|
|
|
{
|
2007-09-27 08:29:16 +00:00
|
|
|
SwUndo * pSubUndo = rUndos[ static_cast<USHORT>(nSubstitute) ];
|
2004-10-22 07:14:25 +00:00
|
|
|
nId = pSubUndo->GetEffectiveId();
|
|
|
|
sStr = pSubUndo->GetComment();
|
|
|
|
}
|
2004-05-18 13:06:14 +00:00
|
|
|
}
|
|
|
|
}
|
2004-10-22 07:14:25 +00:00
|
|
|
else
|
|
|
|
sStr = pUndo->GetComment();
|
2001-04-09 06:23:08 +00:00
|
|
|
}
|
2000-09-18 23:08:29 +00:00
|
|
|
|
2004-10-22 07:14:25 +00:00
|
|
|
break;
|
2004-05-18 13:06:14 +00:00
|
|
|
|
2004-10-22 07:14:25 +00:00
|
|
|
default:
|
|
|
|
nId = pUndo->GetId();
|
|
|
|
sStr = pUndo->GetComment();
|
|
|
|
}
|
2004-05-18 13:06:14 +00:00
|
|
|
|
2010-12-15 09:14:02 +01:00
|
|
|
return IdAndName_t(nId, sStr);
|
2004-10-22 07:14:25 +00:00
|
|
|
}
|
|
|
|
|
2010-12-15 09:14:02 +01:00
|
|
|
|
|
|
|
SwUndoId UndoManager::GetLastUndoInfo(::rtl::OUString *const o_pStr) const
|
2004-10-22 07:14:25 +00:00
|
|
|
{
|
2010-12-15 09:14:02 +01:00
|
|
|
if (!m_nUndoPos)
|
|
|
|
{
|
|
|
|
return UNDO_EMPTY;
|
|
|
|
}
|
|
|
|
|
|
|
|
IdAndName_t const idAndName(lcl_GetUndoIdAndName(*m_pUndos, m_nUndoPos-1));
|
|
|
|
|
|
|
|
if (o_pStr)
|
|
|
|
{
|
|
|
|
*o_pStr = idAndName.second;
|
|
|
|
}
|
|
|
|
|
|
|
|
return idAndName.first;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
SwUndoComments_t UndoManager::GetUndoComments() const
|
|
|
|
{
|
|
|
|
SwUndoComments_t ret;
|
2010-11-25 14:31:11 +01:00
|
|
|
int nTmpPos = m_nUndoPos - 1;
|
2004-10-22 07:14:25 +00:00
|
|
|
|
|
|
|
while (nTmpPos >= 0)
|
|
|
|
{
|
2010-11-25 14:31:11 +01:00
|
|
|
SwUndo *const pUndo = (*m_pUndos)[ static_cast<USHORT>(nTmpPos) ];
|
2004-10-22 07:14:25 +00:00
|
|
|
|
2010-12-15 09:14:02 +01:00
|
|
|
IdAndName_t const idAndName(
|
|
|
|
lcl_GetUndoIdAndName(*m_pUndos, static_cast<sal_uInt16>(nTmpPos)));
|
2004-10-22 07:14:25 +00:00
|
|
|
|
2010-12-15 09:14:02 +01:00
|
|
|
ret.push_back(idAndName.second);
|
2004-10-22 07:14:25 +00:00
|
|
|
|
|
|
|
if (pUndo->GetId() == UNDO_END)
|
2010-11-25 14:31:11 +01:00
|
|
|
{
|
|
|
|
nTmpPos -= static_cast<SwUndoEnd *>(pUndo)->GetSttOffset();
|
|
|
|
}
|
2004-10-22 07:14:25 +00:00
|
|
|
|
|
|
|
nTmpPos--;
|
|
|
|
}
|
2004-09-08 13:58:12 +00:00
|
|
|
|
2010-12-15 09:14:02 +01:00
|
|
|
return ret;
|
2000-09-18 23:08:29 +00:00
|
|
|
}
|
|
|
|
|
2010-11-25 14:31:07 +01:00
|
|
|
bool UndoManager::HasTooManyUndos() const
|
2002-06-03 11:35:54 +00:00
|
|
|
{
|
|
|
|
// AppendUndo checks the UNDO_ACTION_LIMIT, unless there's a nested undo.
|
|
|
|
// So HasTooManyUndos() may only occur when undos are nested; else
|
|
|
|
// AppendUndo has some sort of bug.
|
2010-11-25 14:31:11 +01:00
|
|
|
OSL_ENSURE(
|
|
|
|
(m_nNestingDepth != 0) || (m_pUndos->Count() < UNDO_ACTION_LIMIT),
|
2002-06-03 11:35:54 +00:00
|
|
|
"non-nested undos should have been handled in AppendUndo" );
|
2010-11-25 14:31:11 +01:00
|
|
|
return (m_pUndos->Count() >= UNDO_ACTION_LIMIT);
|
2002-06-03 11:35:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2000-09-18 23:08:29 +00:00
|
|
|
/**************** REDO ******************/
|
|
|
|
|
|
|
|
|
2010-11-25 14:31:10 +01:00
|
|
|
bool UndoManager::Redo(SwUndoIter & rUndoIter)
|
2000-09-18 23:08:29 +00:00
|
|
|
{
|
|
|
|
if( rUndoIter.GetId() && !HasUndoId( rUndoIter.GetId() ) )
|
|
|
|
{
|
|
|
|
rUndoIter.bWeiter = FALSE;
|
2010-11-25 14:31:11 +01:00
|
|
|
return false;
|
2000-09-18 23:08:29 +00:00
|
|
|
}
|
2010-11-25 14:31:11 +01:00
|
|
|
if (m_nUndoPos == m_pUndos->Count())
|
2000-09-18 23:08:29 +00:00
|
|
|
{
|
|
|
|
rUndoIter.bWeiter = FALSE;
|
2010-11-25 14:31:11 +01:00
|
|
|
return false;
|
2000-09-18 23:08:29 +00:00
|
|
|
}
|
|
|
|
|
2010-12-15 09:14:06 +01:00
|
|
|
::sw::UndoGuard const undoGuard(*this);
|
|
|
|
|
2010-11-25 14:31:11 +01:00
|
|
|
SwUndo *const pUndo = (*m_pUndos)[ m_nUndoPos++ ];
|
2000-09-18 23:08:29 +00:00
|
|
|
|
2010-11-25 14:31:11 +01:00
|
|
|
RedlineMode_t const eOld = m_rRedlineAccess.GetRedlineMode();
|
2007-09-27 08:29:16 +00:00
|
|
|
RedlineMode_t eTmpMode = (RedlineMode_t)pUndo->GetRedlineMode();
|
|
|
|
if( (nsRedlineMode_t::REDLINE_SHOW_MASK & eTmpMode) != (nsRedlineMode_t::REDLINE_SHOW_MASK & eOld) &&
|
2000-09-18 23:08:29 +00:00
|
|
|
UNDO_START != pUndo->GetId() && UNDO_END != pUndo->GetId() )
|
2010-11-25 14:31:07 +01:00
|
|
|
{
|
2010-11-25 14:31:11 +01:00
|
|
|
m_rRedlineAccess.SetRedlineMode(eTmpMode);
|
2010-11-25 14:31:07 +01:00
|
|
|
}
|
2010-11-25 14:31:11 +01:00
|
|
|
m_rRedlineAccess.SetRedlineMode_intern(
|
2010-11-25 14:31:07 +01:00
|
|
|
static_cast<RedlineMode_t>(eTmpMode | nsRedlineMode_t::REDLINE_IGNORE));
|
2000-09-18 23:08:29 +00:00
|
|
|
|
|
|
|
//JP 11.05.98: FlyFormate ueber die EditShell selektieren, nicht aus dem
|
|
|
|
// Undo heraus
|
|
|
|
if( UNDO_START != pUndo->GetId() && UNDO_END != pUndo->GetId() )
|
|
|
|
rUndoIter.ClearSelections();
|
|
|
|
|
|
|
|
pUndo->Redo( rUndoIter );
|
|
|
|
|
2010-11-25 14:31:11 +01:00
|
|
|
m_rRedlineAccess.SetRedlineMode(eOld);
|
2000-09-18 23:08:29 +00:00
|
|
|
|
2010-11-25 14:31:11 +01:00
|
|
|
if (rUndoIter.bWeiter && (m_nUndoPos >= m_pUndos->Count()))
|
|
|
|
{
|
2000-09-18 23:08:29 +00:00
|
|
|
rUndoIter.bWeiter = FALSE;
|
2010-11-25 14:31:11 +01:00
|
|
|
}
|
2000-09-18 23:08:29 +00:00
|
|
|
|
2010-11-25 14:31:11 +01:00
|
|
|
// if we are at the "last save" position, the document is not modified
|
|
|
|
if (m_nUndoSavePos == m_nUndoPos)
|
2010-11-25 14:31:07 +01:00
|
|
|
{
|
2010-11-25 14:31:11 +01:00
|
|
|
m_rState.ResetModified();
|
2010-11-25 14:31:07 +01:00
|
|
|
}
|
2000-09-18 23:08:29 +00:00
|
|
|
else
|
2010-11-25 14:31:07 +01:00
|
|
|
{
|
2010-11-25 14:31:11 +01:00
|
|
|
m_rState.SetModified();
|
2010-11-25 14:31:07 +01:00
|
|
|
}
|
2010-11-25 14:31:11 +01:00
|
|
|
return true;
|
2000-09-18 23:08:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-12-15 09:14:07 +01:00
|
|
|
bool UndoManager::GetFirstRedoInfo(::rtl::OUString *const o_pStr) const
|
2000-09-18 23:08:29 +00:00
|
|
|
{
|
2010-12-15 09:14:02 +01:00
|
|
|
if (m_pUndos->Count() == m_nUndoPos)
|
|
|
|
{
|
2010-12-15 09:14:07 +01:00
|
|
|
return false;
|
2010-12-15 09:14:02 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
IdAndName_t const idAndName(lcl_GetUndoIdAndName(*m_pUndos, m_nUndoPos));
|
|
|
|
|
|
|
|
if (o_pStr)
|
|
|
|
{
|
|
|
|
*o_pStr = idAndName.second;
|
|
|
|
}
|
|
|
|
|
2010-12-15 09:14:07 +01:00
|
|
|
return true;
|
2010-12-15 09:14:02 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
SwUndoComments_t UndoManager::GetRedoComments() const
|
|
|
|
{
|
|
|
|
SwUndoComments_t ret;
|
2010-11-25 14:31:11 +01:00
|
|
|
sal_uInt16 nTmpPos = m_nUndoPos;
|
2000-09-18 23:08:29 +00:00
|
|
|
|
2010-11-25 14:31:11 +01:00
|
|
|
while (nTmpPos < m_pUndos->Count())
|
2004-10-22 07:14:25 +00:00
|
|
|
{
|
2010-11-25 14:31:11 +01:00
|
|
|
SwUndo *const pUndo = (*m_pUndos)[nTmpPos];
|
2004-05-18 13:06:14 +00:00
|
|
|
|
2010-12-15 09:14:02 +01:00
|
|
|
IdAndName_t const idAndName(lcl_GetUndoIdAndName(*m_pUndos, nTmpPos));
|
2000-09-18 23:08:29 +00:00
|
|
|
|
2010-12-15 09:14:02 +01:00
|
|
|
ret.push_back(idAndName.second);
|
2001-05-17 10:49:56 +00:00
|
|
|
|
2004-10-22 07:14:25 +00:00
|
|
|
if (pUndo->GetId() == UNDO_START)
|
2010-11-25 14:31:11 +01:00
|
|
|
{
|
|
|
|
nTmpPos =
|
|
|
|
nTmpPos + static_cast<SwUndoStart *>(pUndo)->GetEndOffset();
|
|
|
|
}
|
2000-09-18 23:08:29 +00:00
|
|
|
|
2004-10-22 07:14:25 +00:00
|
|
|
nTmpPos++;
|
|
|
|
}
|
2000-09-18 23:08:29 +00:00
|
|
|
|
2010-12-15 09:14:02 +01:00
|
|
|
return ret;
|
2000-09-18 23:08:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**************** REPEAT ******************/
|
|
|
|
|
|
|
|
|
2010-11-25 14:31:10 +01:00
|
|
|
bool UndoManager::Repeat(SwUndoIter & rUndoIter, sal_uInt16 const nRepeatCnt)
|
2000-09-18 23:08:29 +00:00
|
|
|
{
|
|
|
|
if( rUndoIter.GetId() && !HasUndoId( rUndoIter.GetId() ) )
|
|
|
|
{
|
|
|
|
rUndoIter.bWeiter = FALSE;
|
2010-11-25 14:31:11 +01:00
|
|
|
return false;
|
2000-09-18 23:08:29 +00:00
|
|
|
}
|
2010-11-25 14:31:11 +01:00
|
|
|
USHORT nCurrentRepeat = m_nUndoPos;
|
|
|
|
if( !nCurrentRepeat )
|
2000-09-18 23:08:29 +00:00
|
|
|
{
|
|
|
|
rUndoIter.bWeiter = FALSE;
|
2010-11-25 14:31:11 +01:00
|
|
|
return false;
|
2000-09-18 23:08:29 +00:00
|
|
|
}
|
|
|
|
|
2010-11-25 14:31:11 +01:00
|
|
|
// look for current Repeat action, considering Start/End bracketing
|
|
|
|
SwUndo *const pUndo = (*m_pUndos)[ --nCurrentRepeat ];
|
2000-09-18 23:08:29 +00:00
|
|
|
if( UNDO_END == pUndo->GetId() )
|
2010-11-25 14:31:11 +01:00
|
|
|
{
|
|
|
|
nCurrentRepeat -= static_cast<SwUndoEnd*>(pUndo)->GetSttOffset();
|
|
|
|
}
|
2000-09-18 23:08:29 +00:00
|
|
|
|
2010-11-25 14:31:11 +01:00
|
|
|
USHORT const nEndCnt = m_nUndoPos;
|
|
|
|
bool const bOneUndo = (nCurrentRepeat + 1 == m_nUndoPos);
|
2000-09-18 23:08:29 +00:00
|
|
|
|
|
|
|
SwPaM* pTmpCrsr = rUndoIter.pAktPam;
|
2007-09-27 08:29:16 +00:00
|
|
|
SwUndoId nId = UNDO_EMPTY;
|
2005-02-21 15:06:16 +00:00
|
|
|
|
2010-11-25 14:31:11 +01:00
|
|
|
// need Start/End bracketing?
|
|
|
|
if (pTmpCrsr != pTmpCrsr->GetNext() || !bOneUndo)
|
2005-02-21 15:06:16 +00:00
|
|
|
{
|
|
|
|
if (pUndo->GetId() == UNDO_END)
|
|
|
|
{
|
2010-11-25 14:31:11 +01:00
|
|
|
SwUndoStart *const pStartUndo =
|
|
|
|
static_cast<SwUndoStart *>((*m_pUndos)[nCurrentRepeat]);
|
2005-02-21 15:06:16 +00:00
|
|
|
nId = pStartUndo->GetUserId();
|
|
|
|
}
|
|
|
|
|
2006-08-14 15:48:33 +00:00
|
|
|
StartUndo( nId, NULL );
|
2005-02-21 15:06:16 +00:00
|
|
|
}
|
2010-11-25 14:31:11 +01:00
|
|
|
do { // iterate over ring
|
2000-09-18 23:08:29 +00:00
|
|
|
for( USHORT nRptCnt = nRepeatCnt; nRptCnt > 0; --nRptCnt )
|
|
|
|
{
|
2010-11-25 14:31:11 +01:00
|
|
|
for (USHORT nCnt = nCurrentRepeat; nCnt < nEndCnt; ++nCnt)
|
|
|
|
{
|
|
|
|
(*m_pUndos)[ nCnt ]->Repeat( rUndoIter );
|
|
|
|
}
|
2000-09-18 23:08:29 +00:00
|
|
|
}
|
2010-12-15 09:14:04 +01:00
|
|
|
rUndoIter.m_bDeleteRepeated = false; // reset for next PaM
|
2010-11-25 14:31:11 +01:00
|
|
|
rUndoIter.pAktPam = static_cast<SwPaM*>(rUndoIter.pAktPam->GetNext());
|
|
|
|
} while (pTmpCrsr != rUndoIter.pAktPam);
|
2000-09-18 23:08:29 +00:00
|
|
|
if( pTmpCrsr != pTmpCrsr->GetNext() || !bOneUndo )
|
2010-11-25 14:31:11 +01:00
|
|
|
{
|
2006-08-14 15:48:33 +00:00
|
|
|
EndUndo( nId, NULL );
|
2010-11-25 14:31:11 +01:00
|
|
|
}
|
2000-09-18 23:08:29 +00:00
|
|
|
|
2010-11-25 14:31:11 +01:00
|
|
|
return true;
|
2000-09-18 23:08:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-12-15 09:14:02 +01:00
|
|
|
SwUndoId UndoManager::GetRepeatInfo(::rtl::OUString *const o_pStr) const
|
2004-05-18 13:06:14 +00:00
|
|
|
{
|
2010-12-15 09:14:02 +01:00
|
|
|
SwUndoId const nRepeatId = GetLastUndoInfo(o_pStr);
|
2010-11-25 14:31:10 +01:00
|
|
|
if( REPEAT_START <= nRepeatId && REPEAT_END > nRepeatId )
|
2004-05-18 13:06:14 +00:00
|
|
|
{
|
2010-11-25 14:31:10 +01:00
|
|
|
return nRepeatId;
|
2004-05-18 13:06:14 +00:00
|
|
|
}
|
2010-11-25 14:31:10 +01:00
|
|
|
if (o_pStr) // not repeatable -> clear comment
|
2010-11-25 14:31:10 +01:00
|
|
|
{
|
2010-11-25 14:31:10 +01:00
|
|
|
*o_pStr = String();
|
2010-11-25 14:31:10 +01:00
|
|
|
}
|
2007-09-27 08:29:16 +00:00
|
|
|
return UNDO_EMPTY;
|
2000-09-18 23:08:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-11-25 14:31:10 +01:00
|
|
|
SwUndo* UndoManager::RemoveLastUndo(SwUndoId const eUndoId)
|
2000-09-18 23:08:29 +00:00
|
|
|
{
|
2010-11-25 14:31:11 +01:00
|
|
|
SwUndo *const pUndo = (*m_pUndos)[ m_nUndoPos - 1 ];
|
|
|
|
if ((eUndoId != pUndo->GetId()) || (m_nUndoPos != m_pUndos->Count()))
|
2000-09-18 23:08:29 +00:00
|
|
|
{
|
2010-11-25 14:31:11 +01:00
|
|
|
OSL_ENSURE(false, "RemoveLastUndo(): wrong Undo action");
|
|
|
|
return 0;
|
2000-09-18 23:08:29 +00:00
|
|
|
}
|
2010-11-25 14:31:11 +01:00
|
|
|
if (!m_nNestingDepth)
|
2000-09-18 23:08:29 +00:00
|
|
|
{
|
2010-11-25 14:31:11 +01:00
|
|
|
--m_nUndoActions;
|
2000-09-18 23:08:29 +00:00
|
|
|
}
|
2010-11-25 14:31:11 +01:00
|
|
|
--m_nUndoPos;
|
|
|
|
m_pUndos->Remove( m_nUndoPos, 1 );
|
2000-09-18 23:08:29 +00:00
|
|
|
return pUndo;
|
|
|
|
}
|
|
|
|
|
2010-11-25 14:31:07 +01:00
|
|
|
} // namespace sw
|
|
|
|
|