summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--svl/inc/svl/undo.hxx23
-rw-r--r--svl/source/undo/undo.cxx64
2 files changed, 73 insertions, 14 deletions
diff --git a/svl/inc/svl/undo.hxx b/svl/inc/svl/undo.hxx
index de9c26c7a946..ce8d18403766 100644
--- a/svl/inc/svl/undo.hxx
+++ b/svl/inc/svl/undo.hxx
@@ -144,6 +144,7 @@ public:
virtual void undoActionAdded( const String& i_actionComment ) = 0;
virtual void cleared() = 0;
virtual void clearedRedo() = 0;
+ virtual void resetAll() = 0;
virtual void listActionEntered( const String& i_comment ) = 0;
virtual void listActionLeft( const String& i_comment ) = 0;
virtual void listActionLeftAndMerged() = 0;
@@ -182,9 +183,27 @@ namespace svl
virtual BOOL Undo() = 0;
virtual BOOL Redo() = 0;
+ /** clears both the Redo and the Undo stack.
+
+ Will assert and bail out when called while within a list action (<member>IsInListAction</member>).
+ */
virtual void Clear() = 0;
+
+ /** clears the Redo stack.
+
+ Will assert and bail out when called while within a list action (<member>IsInListAction</member>).
+ */
virtual void ClearRedo() = 0;
+ /** leaves any possible open list action (<member>IsInListAction</member>), and clears both the Undo and the
+ Redo stack.
+
+ Effectively, calling this method is equivalent to <code>while ( IsInListAction() ) LeaveListAction();</code>,
+ followed by <code>Clear()</code>. The only difference to this calling sequence is that Reset is an
+ atomar operation, also resulting in only one notification.
+ */
+ virtual void Reset() = 0;
+
/** determines whether an Undo or Redo is currently running
*/
virtual bool IsDoing() const = 0;
@@ -277,6 +296,7 @@ public:
virtual BOOL Redo();
virtual void Clear();
virtual void ClearRedo();
+ virtual void Reset();
virtual bool IsDoing() const;
virtual USHORT GetRepeatActionCount() const;
virtual UniString GetRepeatActionComment( SfxRepeatTarget &rTarget) const;
@@ -294,10 +314,11 @@ public:
virtual void RemoveUndoListener( SfxUndoListener& i_listener );
private:
- USHORT ImplLeaveListAction( const bool i_merge );
+ USHORT ImplLeaveListAction( const bool i_merge, ::svl::undo::impl::UndoManagerGuard& i_guard );
bool ImplAddUndoAction_NoNotify( SfxUndoAction* pAction, BOOL bTryMerge, ::svl::undo::impl::UndoManagerGuard& i_guard );
void ImplClearRedo( ::svl::undo::impl::UndoManagerGuard& i_guard );
void ImplClearUndo( ::svl::undo::impl::UndoManagerGuard& i_guard );
+ void ImplClear( ::svl::undo::impl::UndoManagerGuard& i_guard );
USHORT ImplGetRedoActionCount_Lock( bool const i_currentLevel = CurrentLevel ) const;
bool ImplIsUndoEnabled_Lock() const;
bool ImplIsInListAction_Lock() const;
diff --git a/svl/source/undo/undo.cxx b/svl/source/undo/undo.cxx
index f9a51a6bf53d..6b975e62c300 100644
--- a/svl/source/undo/undo.cxx
+++ b/svl/source/undo/undo.cxx
@@ -284,6 +284,11 @@ namespace svl { namespace undo { namespace impl
m_aGuard.reset();
}
+ void cancelNotifications()
+ {
+ m_notifiers.clear();
+ }
+
/** marks the given Undo action for deletion
The Undo action will be put into a list, whose members will be deleted from within the destructor of the
@@ -470,21 +475,28 @@ USHORT SfxUndoManager::GetMaxUndoActionCount() const
//------------------------------------------------------------------------
-void SfxUndoManager::Clear()
+void SfxUndoManager::ImplClear( UndoManagerGuard& i_guard )
{
- UndoManagerGuard aGuard( *m_pData );
-
// clear array
while ( m_pData->pActUndoArray->aUndoActions.Count() )
{
- aGuard.markForDeletion( m_pData->pActUndoArray->aUndoActions[ m_pData->pActUndoArray->aUndoActions.Count() - 1 ] );
+ i_guard.markForDeletion( m_pData->pActUndoArray->aUndoActions[ m_pData->pActUndoArray->aUndoActions.Count() - 1 ] );
m_pData->pActUndoArray->aUndoActions.Remove( m_pData->pActUndoArray->aUndoActions.Count() - 1 );
}
m_pData->pActUndoArray->nCurUndoAction = 0;
// notify listeners
- aGuard.scheduleNotification( &SfxUndoListener::cleared );
+ i_guard.scheduleNotification( &SfxUndoListener::cleared );
+}
+
+//------------------------------------------------------------------------
+
+void SfxUndoManager::Clear()
+{
+ UndoManagerGuard aGuard( *m_pData );
+ ENSURE_OR_RETURN_VOID( !IsInListAction(), "SfxUndoManager::Clear: not allowed when within a list action!" );
+ ImplClear( aGuard );
}
//------------------------------------------------------------------------
@@ -492,11 +504,37 @@ void SfxUndoManager::Clear()
void SfxUndoManager::ClearRedo()
{
UndoManagerGuard aGuard( *m_pData );
+ ENSURE_OR_RETURN_VOID( !IsInListAction(), "SfxUndoManager::ClearRedo: not allowed when within a list action!" );
ImplClearRedo( aGuard );
}
//------------------------------------------------------------------------
+void SfxUndoManager::Reset()
+{
+ UndoManagerGuard aGuard( *m_pData );
+
+ // clear all locks
+ while ( ImplIsUndoEnabled_Lock() )
+ ImplEnableUndo_Lock( false );
+
+ // cancel all list actions
+ while ( IsInListAction() )
+ ImplLeaveListAction( false, aGuard );
+
+ // clear both stacks
+ ImplClear( aGuard );
+
+ // cancel the notifications scheduled by ImplLeaveListAction resp. ImplClear,
+ // as we want to do an own, dedicated notification
+ aGuard.cancelNotifications();
+
+ // schedule notification
+ aGuard.scheduleNotification( &SfxUndoListener::resetAll );
+}
+
+//------------------------------------------------------------------------
+
void SfxUndoManager::ImplClearUndo( UndoManagerGuard& i_guard )
{
while ( m_pData->pActUndoArray->nCurUndoAction > 0 )
@@ -941,22 +979,22 @@ USHORT SfxUndoManager::GetListActionDepth() const
USHORT SfxUndoManager::LeaveListAction()
{
- return ImplLeaveListAction( false );
+ UndoManagerGuard aGuard( *m_pData );
+ return ImplLeaveListAction( false, aGuard );
}
//------------------------------------------------------------------------
USHORT SfxUndoManager::LeaveAndMergeListAction()
{
- return ImplLeaveListAction( true );
+ UndoManagerGuard aGuard( *m_pData );
+ return ImplLeaveListAction( true, aGuard );
}
//------------------------------------------------------------------------
-USHORT SfxUndoManager::ImplLeaveListAction( const bool i_merge )
+USHORT SfxUndoManager::ImplLeaveListAction( const bool i_merge, UndoManagerGuard& i_guard )
{
- UndoManagerGuard aGuard( *m_pData );
-
if ( !ImplIsUndoEnabled_Lock() )
return 0;
@@ -982,9 +1020,9 @@ USHORT SfxUndoManager::ImplLeaveListAction( const bool i_merge )
{
SfxUndoAction* pCurrentAction= m_pData->pActUndoArray->aUndoActions[ m_pData->pActUndoArray->nCurUndoAction-1 ];
m_pData->pActUndoArray->aUndoActions.Remove( --m_pData->pActUndoArray->nCurUndoAction );
- aGuard.markForDeletion( pCurrentAction );
+ i_guard.markForDeletion( pCurrentAction );
- aGuard.scheduleNotification( &SfxUndoListener::listActionCancelled );
+ i_guard.scheduleNotification( &SfxUndoListener::listActionCancelled );
return 0;
}
@@ -1024,7 +1062,7 @@ USHORT SfxUndoManager::ImplLeaveListAction( const bool i_merge )
}
// notify listeners
- aGuard.scheduleNotification( &SfxUndoListener::listActionLeft, pListAction->GetComment() );
+ i_guard.scheduleNotification( &SfxUndoListener::listActionLeft, pListAction->GetComment() );
// outta here
return nListActionElements;