diff options
Diffstat (limited to 'svl')
-rw-r--r-- | svl/inc/svl/undo.hxx | 13 | ||||
-rw-r--r-- | svl/source/undo/undo.cxx | 52 |
2 files changed, 54 insertions, 11 deletions
diff --git a/svl/inc/svl/undo.hxx b/svl/inc/svl/undo.hxx index cfa3e6155862..08d2fa6c5b84 100644 --- a/svl/inc/svl/undo.hxx +++ b/svl/inc/svl/undo.hxx @@ -400,12 +400,23 @@ protected: void ImplClearRedo_NoLock( bool const i_currentLevel ); + /** clears all undo actions on the current level, plus all undo actions on superordinate levels, + as soon as those levels are reached. + + If no list action is active currently, i.e. we're on the top level already, this method is equivalent to + ->Clear. + + Otherwise, the Undo actions on the current level are removed. Upon leaving the current list action, all + undo actions on the then-current level are removed, too. This is continued until the top level is reached. + */ + void ClearAllLevels(); + private: size_t ImplLeaveListAction( const bool i_merge, ::svl::undo::impl::UndoManagerGuard& i_guard ); bool ImplAddUndoAction_NoNotify( SfxUndoAction* pAction, bool bTryMerge, bool bClearRedo, ::svl::undo::impl::UndoManagerGuard& i_guard ); void ImplClearRedo( ::svl::undo::impl::UndoManagerGuard& i_guard, bool const i_currentLevel ); void ImplClearUndo( ::svl::undo::impl::UndoManagerGuard& i_guard ); - void ImplClear( ::svl::undo::impl::UndoManagerGuard& i_guard ); + void ImplClearCurrentLevel_NoNotify( ::svl::undo::impl::UndoManagerGuard& i_guard ); size_t 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 4787e6a26292..fd789e6a4aac 100644 --- a/svl/source/undo/undo.cxx +++ b/svl/source/undo/undo.cxx @@ -190,6 +190,7 @@ struct SVL_DLLPRIVATE SfxUndoManager_Data sal_Int32 mnMarks; sal_Int32 mnEmptyMark; bool mbDoing; + bool mbClearUntilTopLevel; UndoListeners aListeners; @@ -201,7 +202,7 @@ struct SVL_DLLPRIVATE SfxUndoManager_Data ,mnMarks( 0 ) ,mnEmptyMark(MARK_INVALID) ,mbDoing( false ) - + ,mbClearUntilTopLevel( false ) { pActUndoArray = pUndoArray; } @@ -500,7 +501,7 @@ size_t SfxUndoManager::GetMaxUndoActionCount() const //------------------------------------------------------------------------ -void SfxUndoManager::ImplClear( UndoManagerGuard& i_guard ) +void SfxUndoManager::ImplClearCurrentLevel_NoNotify( UndoManagerGuard& i_guard ) { // clear array while ( !m_pData->pActUndoArray->aUndoActions.empty() ) @@ -515,9 +516,6 @@ void SfxUndoManager::ImplClear( UndoManagerGuard& i_guard ) m_pData->mnMarks = 0; m_pData->mnEmptyMark = MARK_INVALID; - - // notify listeners - i_guard.scheduleNotification( &SfxUndoListener::cleared ); } //------------------------------------------------------------------------ @@ -525,8 +523,29 @@ void SfxUndoManager::ImplClear( UndoManagerGuard& i_guard ) void SfxUndoManager::Clear() { UndoManagerGuard aGuard( *m_pData ); + OSL_ENSURE( !ImplIsInListAction_Lock(), "SfxUndoManager::Clear: suspicious call - do you really wish to clear the current level?" ); - ImplClear( aGuard ); + ImplClearCurrentLevel_NoNotify( aGuard ); + + // notify listeners + aGuard.scheduleNotification( &SfxUndoListener::cleared ); +} + +//------------------------------------------------------------------------ + +void SfxUndoManager::ClearAllLevels() +{ + UndoManagerGuard aGuard( *m_pData ); + ImplClearCurrentLevel_NoNotify( aGuard ); + + if ( ImplIsInListAction_Lock() ) + { + m_pData->mbClearUntilTopLevel = true; + } + else + { + aGuard.scheduleNotification( &SfxUndoListener::cleared ); + } } //------------------------------------------------------------------------ @@ -560,9 +579,9 @@ void SfxUndoManager::Reset() ImplLeaveListAction( false, aGuard ); // clear both stacks - ImplClear( aGuard ); + ImplClearCurrentLevel_NoNotify( aGuard ); - // cancel the notifications scheduled by ImplLeaveListAction resp. ImplClear, + // cancel the notifications scheduled by ImplLeaveListAction, // as we want to do an own, dedicated notification aGuard.cancelNotifications(); @@ -1053,7 +1072,20 @@ size_t SfxUndoManager::GetListActionDepth() const size_t SfxUndoManager::LeaveListAction() { UndoManagerGuard aGuard( *m_pData ); - return ImplLeaveListAction( false, aGuard ); + size_t nCount = ImplLeaveListAction( false, aGuard ); + + if ( m_pData->mbClearUntilTopLevel ) + { + ImplClearCurrentLevel_NoNotify( aGuard ); + if ( !ImplIsInListAction_Lock() ) + { + m_pData->mbClearUntilTopLevel = false; + aGuard.scheduleNotification( &SfxUndoListener::cleared ); + } + nCount = 0; + } + + return nCount; } //------------------------------------------------------------------------ @@ -1080,7 +1112,7 @@ size_t SfxUndoManager::ImplLeaveListAction( const bool i_merge, UndoManagerGuard return 0; } - DBG_ASSERT( m_pData->pActUndoArray->pFatherUndoArray, "svl::SfxUndoManager::ImplLeaveListAction, no father undo array!?" ); + DBG_ASSERT( m_pData->pActUndoArray->pFatherUndoArray, "SfxUndoManager::ImplLeaveListAction, no father undo array!?" ); // the array/level which we're about to leave SfxUndoArray* pArrayToLeave = m_pData->pActUndoArray; |