diff options
author | Frank Schoenheit [fs] <frank.schoenheit@oracle.com> | 2010-11-26 11:49:51 +0100 |
---|---|---|
committer | Frank Schoenheit [fs] <frank.schoenheit@oracle.com> | 2010-11-26 11:49:51 +0100 |
commit | 620269ac01acf975855176ab7cff22b3153bea6f (patch) | |
tree | baf95ecbb0e1b06ce03597b3650a065e3e25cfc3 /svl | |
parent | udoapi: merge sw refactoring with undoapi stuff (diff) | |
download | core-620269ac01acf975855176ab7cff22b3153bea6f.tar.gz core-620269ac01acf975855176ab7cff22b3153bea6f.zip |
undoapi: support for (simple) marks on the Undo stack
Diffstat (limited to 'svl')
-rw-r--r-- | svl/inc/svl/undo.hxx | 77 | ||||
-rw-r--r-- | svl/source/undo/undo.cxx | 221 |
2 files changed, 213 insertions, 85 deletions
diff --git a/svl/inc/svl/undo.hxx b/svl/inc/svl/undo.hxx index ce8d18403766..1c6ab5570c14 100644 --- a/svl/inc/svl/undo.hxx +++ b/svl/inc/svl/undo.hxx @@ -34,6 +34,8 @@ #include <boost/scoped_ptr.hpp> +#include <vector> + //==================================================================== class SVL_DLLPUBLIC SfxRepeatTarget @@ -62,8 +64,8 @@ public: virtual BOOL Merge( SfxUndoAction *pNextAction ); - virtual UniString GetComment() const; - virtual UniString GetRepeatComment(SfxRepeatTarget&) const; + virtual UniString GetComment() const; + virtual UniString GetRepeatComment(SfxRepeatTarget&) const; virtual USHORT GetId() const; private: @@ -72,11 +74,59 @@ private: //======================================================================== -SV_DECL_PTRARR( SfxUndoActions, SfxUndoAction*, 20, 8 ) +/// is a mark on the Undo stack +typedef sal_Int32 UndoStackMark; +#define MARK_INVALID ::std::numeric_limits< UndoStackMark >::max() + +//======================================================================== + +struct MarkedUndoAction +{ + SfxUndoAction* pAction; + ::std::vector< UndoStackMark > aMarks; + + MarkedUndoAction( SfxUndoAction* i_action ) + :pAction( i_action ) + ,aMarks() + { + } +}; + +class SfxUndoActions +{ +private: + ::std::vector< MarkedUndoAction > m_aActions; + +public: + SfxUndoActions() + { + } + + bool empty() const { return m_aActions.empty(); } + size_t size() const { return m_aActions.size(); } + + const MarkedUndoAction& operator[]( size_t i ) const { return m_aActions[i]; } + MarkedUndoAction& operator[]( size_t i ) { return m_aActions[i]; } + + void Remove( size_t i_pos ) + { + m_aActions.erase( m_aActions.begin() + i_pos ); + } + + void Remove( size_t i_pos, size_t i_count ) + { + m_aActions.erase( m_aActions.begin() + i_pos, m_aActions.begin() + i_pos + i_count ); + } + + void Insert( SfxUndoAction* i_action, USHORT i_pos ) + { + m_aActions.insert( m_aActions.begin() + i_pos, MarkedUndoAction( i_action ) ); + } +}; //==================================================================== -/** do not make use of this implementation details, unless you +/** do not make use of these implementation details, unless you really really have to! */ struct SVL_DLLPUBLIC SfxUndoArray { @@ -92,7 +142,7 @@ struct SVL_DLLPUBLIC SfxUndoArray //========================================================================= -/** do not make use of this implementation details, unless you +/** do not make use of these implementation details, unless you really really have to! */ class SVL_DLLPUBLIC SfxListUndoAction : public SfxUndoAction, public SfxUndoArray @@ -128,7 +178,8 @@ class SVL_DLLPUBLIC SfxListUndoAction : public SfxUndoAction, public SfxUndoArra private: USHORT nId; - UniString aComment, aRepeatComment; + UniString aComment; + UniString aRepeatComment; }; @@ -313,6 +364,20 @@ public: virtual void AddUndoListener( SfxUndoListener& i_listener ); virtual void RemoveUndoListener( SfxUndoListener& i_listener ); + /** marks the current top-level element of the Undo stack, and returns a unique ID for it + */ + UndoStackMark MarkTopUndoAction(); + + /** removes a mark given by its ID. + + After the call, the mark ID is invalid. + */ + void RemoveMark( UndoStackMark const i_mark ); + + /** determines whether the top action on the Undo stack has a given mark + */ + bool HasTopUndoActionMark( UndoStackMark const i_mark ); + private: 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 ); diff --git a/svl/source/undo/undo.cxx b/svl/source/undo/undo.cxx index 715dce04225c..38cb88cf346d 100644 --- a/svl/source/undo/undo.cxx +++ b/svl/source/undo/undo.cxx @@ -38,6 +38,7 @@ #include <vector> #include <list> +#include <limits> using ::com::sun::star::uno::Exception; @@ -165,6 +166,7 @@ struct SVL_DLLPRIVATE SfxUndoManager_Data SfxUndoArray* pFatherUndoArray; sal_Int32 mnLockCount; + sal_Int32 mnMarks; bool mbDoing; UndoListeners aListeners; @@ -174,6 +176,7 @@ struct SVL_DLLPRIVATE SfxUndoManager_Data ,pActUndoArray( NULL ) ,pFatherUndoArray( NULL ) ,mnLockCount( 0 ) + ,mnMarks( 0 ) ,mbDoing( false ) { @@ -430,36 +433,35 @@ void SfxUndoManager::SetMaxUndoActionCount( USHORT nMaxUndoActionCount ) // Both redo and undo action entries will be removed until we reached the // new nMaxUndoActionCount. - long nNumToDelete = m_pData->pActUndoArray->aUndoActions.Count() - nMaxUndoActionCount; - if ( nNumToDelete > 0 ) + long nNumToDelete = m_pData->pActUndoArray->aUndoActions.size() - nMaxUndoActionCount; + while ( nNumToDelete > 0 ) { - while ( nNumToDelete > 0 ) + size_t nPos = m_pData->pActUndoArray->aUndoActions.size(); + if ( nPos > m_pData->pActUndoArray->nCurUndoAction ) { - USHORT nPos = m_pData->pActUndoArray->aUndoActions.Count(); - if ( nPos > m_pData->pActUndoArray->nCurUndoAction ) + SfxUndoAction* pAction = m_pData->pActUndoArray->aUndoActions[nPos-1].pAction; + if ( !pAction->IsLinked() ) { - if ( !m_pData->pActUndoArray->aUndoActions[nPos-1]->IsLinked() ) - { - aGuard.markForDeletion( m_pData->pActUndoArray->aUndoActions[ nPos-1 ] ); - m_pData->pActUndoArray->aUndoActions.Remove( nPos-1 ); - --nNumToDelete; - } + aGuard.markForDeletion( pAction ); + m_pData->pActUndoArray->aUndoActions.Remove( nPos-1 ); + --nNumToDelete; } + } - if ( nNumToDelete > 0 && m_pData->pActUndoArray->nCurUndoAction > 0 ) + if ( nNumToDelete > 0 && m_pData->pActUndoArray->nCurUndoAction > 0 ) + { + SfxUndoAction* pAction = m_pData->pActUndoArray->aUndoActions[0].pAction; + if ( !pAction->IsLinked() ) { - if ( !m_pData->pActUndoArray->aUndoActions[0]->IsLinked() ) - { - aGuard.markForDeletion( m_pData->pActUndoArray->aUndoActions[0] ); - m_pData->pActUndoArray->aUndoActions.Remove(0); - --m_pData->pActUndoArray->nCurUndoAction; - --nNumToDelete; - } + aGuard.markForDeletion( pAction ); + m_pData->pActUndoArray->aUndoActions.Remove(0); + --m_pData->pActUndoArray->nCurUndoAction; + --nNumToDelete; } - - if ( nPos == m_pData->pActUndoArray->aUndoActions.Count() ) - break; // Cannot delete more entries } + + if ( nPos == m_pData->pActUndoArray->aUndoActions.size() ) + break; // Cannot delete more entries } m_pData->pActUndoArray->nMaxUndoActions = nMaxUndoActionCount; @@ -478,14 +480,18 @@ USHORT SfxUndoManager::GetMaxUndoActionCount() const void SfxUndoManager::ImplClear( UndoManagerGuard& i_guard ) { // clear array - while ( m_pData->pActUndoArray->aUndoActions.Count() ) + while ( !m_pData->pActUndoArray->aUndoActions.empty() ) { - i_guard.markForDeletion( m_pData->pActUndoArray->aUndoActions[ m_pData->pActUndoArray->aUndoActions.Count() - 1 ] ); - m_pData->pActUndoArray->aUndoActions.Remove( m_pData->pActUndoArray->aUndoActions.Count() - 1 ); + size_t deletePos = m_pData->pActUndoArray->aUndoActions.size() - 1; + SfxUndoAction* pAction = m_pData->pActUndoArray->aUndoActions[ deletePos ].pAction; + i_guard.markForDeletion( pAction ); + m_pData->pActUndoArray->aUndoActions.Remove( deletePos ); } m_pData->pActUndoArray->nCurUndoAction = 0; + m_pData->mnMarks = 0; + // notify listeners i_guard.scheduleNotification( &SfxUndoListener::cleared ); } @@ -539,7 +545,7 @@ void SfxUndoManager::ImplClearUndo( UndoManagerGuard& i_guard ) { while ( m_pData->pActUndoArray->nCurUndoAction > 0 ) { - SfxUndoAction* pUndoAction = m_pData->pActUndoArray->aUndoActions[0]; + SfxUndoAction* pUndoAction = m_pData->pActUndoArray->aUndoActions[0].pAction; m_pData->pActUndoArray->aUndoActions.Remove( 0 ); i_guard.markForDeletion( pUndoAction ); --m_pData->pActUndoArray->nCurUndoAction; @@ -552,11 +558,11 @@ void SfxUndoManager::ImplClearUndo( UndoManagerGuard& i_guard ) void SfxUndoManager::ImplClearRedo( UndoManagerGuard& i_guard ) { // clearance - while ( m_pData->pActUndoArray->aUndoActions.Count() > m_pData->pActUndoArray->nCurUndoAction ) + while ( m_pData->pActUndoArray->aUndoActions.size() > m_pData->pActUndoArray->nCurUndoAction ) { - SfxUndoAction *pAction = - m_pData->pActUndoArray->aUndoActions[m_pData->pActUndoArray->aUndoActions.Count() - 1]; - m_pData->pActUndoArray->aUndoActions.Remove( m_pData->pActUndoArray->aUndoActions.Count() - 1 ); + size_t deletePos = m_pData->pActUndoArray->aUndoActions.size() - 1; + SfxUndoAction* pAction = m_pData->pActUndoArray->aUndoActions[ deletePos ].pAction; + m_pData->pActUndoArray->aUndoActions.Remove( deletePos ); i_guard.markForDeletion( pAction ); } @@ -580,7 +586,7 @@ bool SfxUndoManager::ImplAddUndoAction_NoNotify( SfxUndoAction *pAction, BOOL bT // merge, if required SfxUndoAction* pMergeWithAction = m_pData->pActUndoArray->nCurUndoAction ? - m_pData->pActUndoArray->aUndoActions[m_pData->pActUndoArray->nCurUndoAction-1] : NULL; + m_pData->pActUndoArray->aUndoActions[m_pData->pActUndoArray->nCurUndoAction-1].pAction : NULL; if ( bTryMerge && ( !pMergeWithAction || !pMergeWithAction->Merge( pAction ) ) ) { i_guard.markForDeletion( pAction ); @@ -590,18 +596,18 @@ bool SfxUndoManager::ImplAddUndoAction_NoNotify( SfxUndoAction *pAction, BOOL bT // respect max number if( m_pData->pActUndoArray == m_pData->pUndoArray ) { - while( m_pData->pActUndoArray->aUndoActions.Count() >= + while( m_pData->pActUndoArray->aUndoActions.size() >= m_pData->pActUndoArray->nMaxUndoActions && - !m_pData->pActUndoArray->aUndoActions[0]->IsLinked() ) + !m_pData->pActUndoArray->aUndoActions[0].pAction->IsLinked() ) { - i_guard.markForDeletion( m_pData->pActUndoArray->aUndoActions[0] ); + i_guard.markForDeletion( m_pData->pActUndoArray->aUndoActions[0].pAction ); m_pData->pActUndoArray->aUndoActions.Remove(0); --m_pData->pActUndoArray->nCurUndoAction; } } // append new action - const SfxUndoAction* pMakeCompilerHappy = pAction; + SfxUndoAction* pMakeCompilerHappy = pAction; m_pData->pActUndoArray->aUndoActions.Insert( pMakeCompilerHappy, m_pData->pActUndoArray->nCurUndoAction++ ); return true; } @@ -640,7 +646,7 @@ XubString SfxUndoManager::GetUndoActionComment( USHORT nNo, bool const i_current DBG_ASSERT( nNo < pUndoArray->nCurUndoAction, "svl::SfxUndoManager::GetUndoActionComment: illegal index!" ); if( nNo < pUndoArray->nCurUndoAction ) { - sComment = pUndoArray->aUndoActions[ pUndoArray->nCurUndoAction - 1 - nNo ]->GetComment(); + sComment = pUndoArray->aUndoActions[ pUndoArray->nCurUndoAction - 1 - nNo ].pAction->GetComment(); } return sComment; } @@ -654,7 +660,7 @@ USHORT SfxUndoManager::GetUndoActionId() const DBG_ASSERT( m_pData->pActUndoArray->nCurUndoAction > 0, "svl::SfxUndoManager::GetUndoActionId(), illegal id!" ); if ( m_pData->pActUndoArray->nCurUndoAction == 0 ) return NULL; - return m_pData->pActUndoArray->aUndoActions[m_pData->pActUndoArray->nCurUndoAction-1]->GetId(); + return m_pData->pActUndoArray->aUndoActions[m_pData->pActUndoArray->nCurUndoAction-1].pAction->GetId(); } //------------------------------------------------------------------------ @@ -666,7 +672,7 @@ SfxUndoAction* SfxUndoManager::GetUndoAction( USHORT nNo ) const DBG_ASSERT( nNo < m_pData->pActUndoArray->nCurUndoAction, "svl::SfxUndoManager::GetUndoAction(), illegal id!" ); if( nNo >= m_pData->pActUndoArray->nCurUndoAction ) return NULL; - return m_pData->pActUndoArray->aUndoActions[m_pData->pActUndoArray->nCurUndoAction-1-nNo]; //! + return m_pData->pActUndoArray->aUndoActions[m_pData->pActUndoArray->nCurUndoAction-1-nNo].pAction; } //------------------------------------------------------------------------ @@ -681,15 +687,14 @@ void SfxUndoManager::RemoveLastUndoAction() m_pData->pActUndoArray->nCurUndoAction--; // delete redo-actions and top action - USHORT nPos; - for ( nPos = m_pData->pActUndoArray->aUndoActions.Count(); nPos > m_pData->pActUndoArray->nCurUndoAction; --nPos ) + for ( size_t nPos = m_pData->pActUndoArray->aUndoActions.size(); nPos > m_pData->pActUndoArray->nCurUndoAction; --nPos ) { - aGuard.markForDeletion( m_pData->pActUndoArray->aUndoActions[nPos-1] ); + aGuard.markForDeletion( m_pData->pActUndoArray->aUndoActions[nPos-1].pAction ); } m_pData->pActUndoArray->aUndoActions.Remove( m_pData->pActUndoArray->nCurUndoAction, - m_pData->pActUndoArray->aUndoActions.Count() - m_pData->pActUndoArray->nCurUndoAction ); + m_pData->pActUndoArray->aUndoActions.size() - m_pData->pActUndoArray->nCurUndoAction ); } //------------------------------------------------------------------------ @@ -722,7 +727,7 @@ BOOL SfxUndoManager::Undo() return FALSE; } - SfxUndoAction* pAction = m_pData->pActUndoArray->aUndoActions[ --m_pData->pActUndoArray->nCurUndoAction ]; + SfxUndoAction* pAction = m_pData->pActUndoArray->aUndoActions[ --m_pData->pActUndoArray->nCurUndoAction ].pAction; const String sActionComment = pAction->GetComment(); try { @@ -739,9 +744,9 @@ BOOL SfxUndoManager::Undo() // in theory, somebody might have tampered with all of *m_pData while the mutex was unlocked. So, see if // we still find pAction in our current Undo array USHORT nCurAction = 0; - while ( nCurAction < m_pData->pActUndoArray->aUndoActions.Count() ) + while ( nCurAction < m_pData->pActUndoArray->aUndoActions.size() ) { - if ( m_pData->pActUndoArray->aUndoActions[ nCurAction++ ] == pAction ) + if ( m_pData->pActUndoArray->aUndoActions[ nCurAction++ ].pAction == pAction ) { // the Undo action is still there ... // assume the error is a permanent failure, and clear the Undo stack @@ -771,7 +776,7 @@ USHORT SfxUndoManager::GetRedoActionCount( bool const i_currentLevel ) const USHORT SfxUndoManager::ImplGetRedoActionCount_Lock( bool const i_currentLevel ) const { const SfxUndoArray* pUndoArray = i_currentLevel ? m_pData->pActUndoArray : m_pData->pUndoArray; - return pUndoArray->aUndoActions.Count() - pUndoArray->nCurUndoAction; + return USHORT( pUndoArray->aUndoActions.size() - pUndoArray->nCurUndoAction ); } //------------------------------------------------------------------------ @@ -780,7 +785,7 @@ XubString SfxUndoManager::GetRedoActionComment( USHORT nNo, bool const i_current { UndoManagerGuard aGuard( *m_pData ); const SfxUndoArray* pUndoArray = i_currentLevel ? m_pData->pActUndoArray : m_pData->pUndoArray; - return pUndoArray->aUndoActions[ pUndoArray->nCurUndoAction + nNo ]->GetComment(); + return pUndoArray->aUndoActions[ pUndoArray->nCurUndoAction + nNo ].pAction->GetComment(); } //------------------------------------------------------------------------ @@ -799,13 +804,13 @@ BOOL SfxUndoManager::Redo() return FALSE; } - if ( m_pData->pActUndoArray->nCurUndoAction >= m_pData->pActUndoArray->aUndoActions.Count() ) + if ( m_pData->pActUndoArray->nCurUndoAction >= m_pData->pActUndoArray->aUndoActions.size() ) { OSL_ENSURE( false, "SfxUndoManager::Redo: redo stack is empty!" ); return FALSE; } - SfxUndoAction* pAction = m_pData->pActUndoArray->aUndoActions[ m_pData->pActUndoArray->nCurUndoAction++ ]; + SfxUndoAction* pAction = m_pData->pActUndoArray->aUndoActions[ m_pData->pActUndoArray->nCurUndoAction++ ].pAction; const String sActionComment = pAction->GetComment(); try { @@ -822,9 +827,9 @@ BOOL SfxUndoManager::Redo() // in theory, somebody might have tampered with all of *m_pData while the mutex was unlocked. So, see if // we still find pAction in our current Undo array USHORT nCurAction = 0; - while ( nCurAction < m_pData->pActUndoArray->aUndoActions.Count() ) + while ( nCurAction < m_pData->pActUndoArray->aUndoActions.size() ) { - if ( m_pData->pActUndoArray->aUndoActions[ nCurAction ] == pAction ) + if ( m_pData->pActUndoArray->aUndoActions[ nCurAction ].pAction == pAction ) { // the Undo action is still there ... // assume the error is a permanent failure, and clear the Undo stack @@ -847,7 +852,7 @@ BOOL SfxUndoManager::Redo() USHORT SfxUndoManager::GetRepeatActionCount() const { UndoManagerGuard aGuard( *m_pData ); - return m_pData->pActUndoArray->aUndoActions.Count(); + return USHORT( m_pData->pActUndoArray->aUndoActions.size() ); } //------------------------------------------------------------------------ @@ -855,7 +860,7 @@ USHORT SfxUndoManager::GetRepeatActionCount() const XubString SfxUndoManager::GetRepeatActionComment( SfxRepeatTarget &rTarget) const { UndoManagerGuard aGuard( *m_pData ); - return m_pData->pActUndoArray->aUndoActions[ m_pData->pActUndoArray->aUndoActions.Count() - 1 ] + return m_pData->pActUndoArray->aUndoActions[ m_pData->pActUndoArray->aUndoActions.size() - 1 ].pAction ->GetRepeatComment(rTarget); } @@ -864,9 +869,9 @@ XubString SfxUndoManager::GetRepeatActionComment( SfxRepeatTarget &rTarget) cons BOOL SfxUndoManager::Repeat( SfxRepeatTarget &rTarget ) { UndoManagerGuard aGuard( *m_pData ); - if ( m_pData->pActUndoArray->aUndoActions.Count() ) + if ( !m_pData->pActUndoArray->aUndoActions.empty() ) { - SfxUndoAction* pAction = m_pData->pActUndoArray->aUndoActions[ m_pData->pActUndoArray->aUndoActions.Count() - 1 ]; + SfxUndoAction* pAction = m_pData->pActUndoArray->aUndoActions[ m_pData->pActUndoArray->aUndoActions.size() - 1 ].pAction; aGuard.clear(); if ( pAction->CanRepeat( rTarget ) ) pAction->Repeat( rTarget ); @@ -881,10 +886,10 @@ BOOL SfxUndoManager::Repeat( SfxRepeatTarget &rTarget ) BOOL SfxUndoManager::CanRepeat( SfxRepeatTarget &rTarget ) const { UndoManagerGuard aGuard( *m_pData ); - if ( m_pData->pActUndoArray->aUndoActions.Count() > 0 ) + if ( !m_pData->pActUndoArray->aUndoActions.empty() ) { - USHORT nActionNo = m_pData->pActUndoArray->aUndoActions.Count() - 1; - return m_pData->pActUndoArray->aUndoActions[nActionNo]->CanRepeat(rTarget); + size_t nActionNo = m_pData->pActUndoArray->aUndoActions.size() - 1; + return m_pData->pActUndoArray->aUndoActions[nActionNo].pAction->CanRepeat(rTarget); } return FALSE; } @@ -1018,7 +1023,7 @@ USHORT SfxUndoManager::ImplLeaveListAction( const bool i_merge, UndoManagerGuard const USHORT nListActionElements = pArrayToLeave->nCurUndoAction; if ( nListActionElements == 0 ) { - SfxUndoAction* pCurrentAction= m_pData->pActUndoArray->aUndoActions[ m_pData->pActUndoArray->nCurUndoAction-1 ]; + SfxUndoAction* pCurrentAction= m_pData->pActUndoArray->aUndoActions[ m_pData->pActUndoArray->nCurUndoAction-1 ].pAction; m_pData->pActUndoArray->aUndoActions.Remove( --m_pData->pActUndoArray->nCurUndoAction ); i_guard.markForDeletion( pCurrentAction ); @@ -1027,7 +1032,7 @@ USHORT SfxUndoManager::ImplLeaveListAction( const bool i_merge, UndoManagerGuard } - SfxUndoAction* pCurrentAction= m_pData->pActUndoArray->aUndoActions[ m_pData->pActUndoArray->nCurUndoAction-1 ]; + SfxUndoAction* pCurrentAction= m_pData->pActUndoArray->aUndoActions[ m_pData->pActUndoArray->nCurUndoAction-1 ].pAction; SfxListUndoAction* pListAction = dynamic_cast< SfxListUndoAction * >( pCurrentAction ); ENSURE_OR_RETURN( pListAction, "SfxUndoManager::ImplLeaveListAction: list action expected at this position!", nListActionElements ); @@ -1038,7 +1043,7 @@ USHORT SfxUndoManager::ImplLeaveListAction( const bool i_merge, UndoManagerGuard "SfxUndoManager::ImplLeaveListAction: cannot merge the list action if there's no other action on the same level - check this beforehand!" ); if ( m_pData->pActUndoArray->nCurUndoAction > 1 ) { - const SfxUndoAction* pPreviousAction = m_pData->pActUndoArray->aUndoActions[ m_pData->pActUndoArray->nCurUndoAction - 2 ]; + SfxUndoAction* pPreviousAction = m_pData->pActUndoArray->aUndoActions[ m_pData->pActUndoArray->nCurUndoAction - 2 ].pAction; m_pData->pActUndoArray->aUndoActions.Remove( m_pData->pActUndoArray->nCurUndoAction - 2 ); --m_pData->pActUndoArray->nCurUndoAction; pListAction->aUndoActions.Insert( pPreviousAction, 0 ); @@ -1051,11 +1056,11 @@ USHORT SfxUndoManager::ImplLeaveListAction( const bool i_merge, UndoManagerGuard // if the undo array has no comment, try to get it from its children if ( pListAction->GetComment().Len() == 0 ) { - for( USHORT n = 0; n < pListAction->aUndoActions.Count(); n++ ) + for( USHORT n = 0; n < pListAction->aUndoActions.size(); n++ ) { - if( pListAction->aUndoActions[n]->GetComment().Len() ) + if( pListAction->aUndoActions[n].pAction->GetComment().Len() ) { - pListAction->SetComment( pListAction->aUndoActions[n]->GetComment() ); + pListAction->SetComment( pListAction->aUndoActions[n].pAction->GetComment() ); break; } } @@ -1069,6 +1074,68 @@ USHORT SfxUndoManager::ImplLeaveListAction( const bool i_merge, UndoManagerGuard } //------------------------------------------------------------------------ +UndoStackMark SfxUndoManager::MarkTopUndoAction() +{ + UndoManagerGuard aGuard( *m_pData ); + + USHORT nActionPos = m_pData->pUndoArray->nCurUndoAction; + ENSURE_OR_RETURN( nActionPos > 0, "SfxUndoManager::MarkTopUndoAction: undo stack is empty!", MARK_INVALID ); + + OSL_ENSURE( !IsInListAction(), "SfxUndoManager::MarkTopUndoAction: suspicious call!" ); + + m_pData->pUndoArray->aUndoActions[ nActionPos ].aMarks.push_back( ++m_pData->mnMarks ); + return m_pData->mnMarks; +} + +//------------------------------------------------------------------------ +void SfxUndoManager::RemoveMark( UndoStackMark const i_mark ) +{ + UndoManagerGuard aGuard( *m_pData ); + + for ( size_t i=0; i<m_pData->pUndoArray->aUndoActions.size(); ++i ) + { + MarkedUndoAction& rAction = m_pData->pUndoArray->aUndoActions[i]; + for ( ::std::vector< UndoStackMark >::iterator markPos = rAction.aMarks.begin(); + markPos != rAction.aMarks.end(); + ++markPos + ) + { + if ( *markPos == i_mark ) + { + rAction.aMarks.erase( markPos ); + return; + } + } + } + OSL_ENSURE( false, "SfxUndoManager::RemoveMark: mark not found!" ); + // TODO: this might be too offensive. There are situations where we implicitly remove marks + // without our clients, in particular the client which created the mark, having a chance to know + // about this. +} + +//------------------------------------------------------------------------ +bool SfxUndoManager::HasTopUndoActionMark( UndoStackMark const i_mark ) +{ + UndoManagerGuard aGuard( *m_pData ); + + USHORT nActionPos = m_pData->pUndoArray->nCurUndoAction; + if ( nActionPos == 0 ) + return false; + + const MarkedUndoAction& rAction = m_pData->pUndoArray->aUndoActions[ nActionPos ]; + for ( ::std::vector< UndoStackMark >::const_iterator markPos = rAction.aMarks.begin(); + markPos != rAction.aMarks.end(); + ++markPos + ) + { + if ( *markPos == i_mark ) + return true; + } + + return false; +} + +//------------------------------------------------------------------------ USHORT SfxListUndoAction::GetId() const { @@ -1117,7 +1184,7 @@ SfxListUndoAction::SfxListUndoAction void SfxListUndoAction::Undo() { for(INT16 i=nCurUndoAction-1;i>=0;i--) - aUndoActions[i]->Undo(); + aUndoActions[i].pAction->Undo(); nCurUndoAction=0; } @@ -1125,9 +1192,9 @@ void SfxListUndoAction::Undo() void SfxListUndoAction::Redo() { - for(USHORT i=nCurUndoAction;i<aUndoActions.Count();i++) - aUndoActions[i]->Redo(); - nCurUndoAction = aUndoActions.Count(); + for(USHORT i=nCurUndoAction;i<aUndoActions.size();i++) + aUndoActions[i].pAction->Redo(); + nCurUndoAction = USHORT( aUndoActions.size() ); } //------------------------------------------------------------------------ @@ -1135,7 +1202,7 @@ void SfxListUndoAction::Redo() void SfxListUndoAction::Repeat(SfxRepeatTarget&rTarget) { for(USHORT i=0;i<nCurUndoAction;i++) - aUndoActions[i]->Repeat(rTarget); + aUndoActions[i].pAction->Repeat(rTarget); } //------------------------------------------------------------------------ @@ -1143,7 +1210,7 @@ void SfxListUndoAction::Repeat(SfxRepeatTarget&rTarget) BOOL SfxListUndoAction::CanRepeat(SfxRepeatTarget&r) const { for(USHORT i=0;i<nCurUndoAction;i++) - if(!aUndoActions[i]->CanRepeat(r)) + if(!aUndoActions[i].pAction->CanRepeat(r)) return FALSE; return TRUE; } @@ -1152,7 +1219,7 @@ BOOL SfxListUndoAction::CanRepeat(SfxRepeatTarget&r) const BOOL SfxListUndoAction::Merge( SfxUndoAction *pNextAction ) { - return aUndoActions.Count() && aUndoActions[aUndoActions.Count()-1]->Merge( pNextAction ); + return !aUndoActions.empty() && aUndoActions[aUndoActions.size()-1].pAction->Merge( pNextAction ); } //------------------------------------------------------------------------ @@ -1175,7 +1242,7 @@ SfxLinkUndoAction::SfxLinkUndoAction(::svl::IUndoManager *pManager) if ( pManager->GetMaxUndoActionCount() ) { USHORT nPos = pManager->GetUndoActionCount()-1; - pAction = pUndoManagerImplementation->m_pData->pActUndoArray->aUndoActions[nPos]; + pAction = pUndoManagerImplementation->m_pData->pActUndoArray->aUndoActions[nPos].pAction; pAction->SetLinked(); } else @@ -1251,11 +1318,10 @@ SfxLinkUndoAction::~SfxLinkUndoAction() SfxUndoArray::~SfxUndoArray() { - while ( aUndoActions.Count() ) + while ( !aUndoActions.empty() ) { - SfxUndoAction *pAction = - aUndoActions[ aUndoActions.Count() - 1 ]; - aUndoActions.Remove( aUndoActions.Count() - 1 ); + SfxUndoAction *pAction = aUndoActions[ aUndoActions.size() - 1 ].pAction; + aUndoActions.Remove( aUndoActions.size() - 1 ); delete pAction; } } @@ -1265,6 +1331,3 @@ USHORT SfxLinkUndoAction::GetId() const { return pAction ? pAction->GetId() : 0; } - - - |