diff options
author | Frank Schoenheit [fs] <frank.schoenheit@oracle.com> | 2010-11-16 22:35:25 +0100 |
---|---|---|
committer | Frank Schoenheit [fs] <frank.schoenheit@oracle.com> | 2010-11-16 22:35:25 +0100 |
commit | 8767799d39fe93054ea12606f44403aa766a1853 (patch) | |
tree | af7ac9118c947b0c721ccc0cd6d786b3ebac4a0a | |
parent | 2b173b9eb115840aabb5742d4585b8ea1b84e25f (diff) |
undoapi: make reset an explicit, atomar operation at the IUndoManager, instead of simulating it in a higher layer
-rw-r--r-- | svl/inc/svl/undo.hxx | 23 | ||||
-rw-r--r-- | svl/source/undo/undo.cxx | 64 |
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; |