summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--svl/inc/svl/undo.hxx33
-rw-r--r--svl/source/undo/undo.cxx132
-rw-r--r--svtools/source/edit/textundo.cxx8
-rw-r--r--svtools/source/edit/textundo.hxx4
-rw-r--r--svtools/source/edit/textview.cxx4
5 files changed, 159 insertions, 22 deletions
diff --git a/svl/inc/svl/undo.hxx b/svl/inc/svl/undo.hxx
index a7c4f7615183..8d2e2c3c6670 100644
--- a/svl/inc/svl/undo.hxx
+++ b/svl/inc/svl/undo.hxx
@@ -134,6 +134,23 @@ class SVL_DLLPUBLIC SfxListUndoAction : public SfxUndoAction, public SfxUndoArra
//=========================================================================
+/** is a callback interface for notifications about state changes of an SfxUndoManager
+*/
+class SAL_NO_VTABLE SfxUndoListener
+{
+public:
+ virtual void actionUndone( SfxUndoAction& i_action ) = 0;
+ virtual void actionRedone( SfxUndoAction& i_action ) = 0;
+ virtual void undoActionAdded( SfxUndoAction& i_action ) = 0;
+ virtual void cleared() = 0;
+ virtual void clearedRedo() = 0;
+ virtual void listActionEntered( const String& i_comment ) = 0;
+ virtual void listActionLeft() = 0;
+ virtual void undoManagerDying() = 0;
+};
+
+//=========================================================================
+
struct SfxUndoManager_Data;
class SVL_DLLPUBLIC SfxUndoManager
{
@@ -157,15 +174,13 @@ public:
/** returns the nNo'th undo action from the top */
SfxUndoAction* GetUndoAction( USHORT nNo=0 ) const;
- virtual BOOL Undo( USHORT nCount=1 );
- virtual void Undo( SfxUndoAction &rAction );
+ virtual BOOL Undo();
virtual USHORT GetRedoActionCount() const;
virtual USHORT GetRedoActionId(USHORT nNo=0) const;
virtual UniString GetRedoActionComment( USHORT nNo=0 ) const;
- virtual BOOL Redo( USHORT nCount=1 );
- virtual void Redo( SfxUndoAction &rAction );
+ virtual BOOL Redo();
virtual void ClearRedo();
virtual USHORT GetRepeatActionCount() const;
@@ -181,6 +196,8 @@ public:
/// determines whether we're within a ListAction context, i.e. a LeaveListAction call is pending
bool IsInListAction() const;
+ USHORT GetListActionDepth() const;
+
/** clears the redo stack and removes the top undo action */
void RemoveLastUndoAction();
@@ -193,6 +210,14 @@ public:
// This returns false if undo was disabled using EnableUndo( false ) and
// also during the runtime of the Undo() and Redo() methods.
bool IsUndoEnabled() const;
+
+ /// adds a new listener to be notified about changes in the UndoManager's state
+ void AddUndoListener( SfxUndoListener& i_listener );
+ void RemoveUndoListener( SfxUndoListener& i_listener );
+
+protected:
+ void ImplUndo( SfxUndoAction &rAction );
+ void ImplRedo( SfxUndoAction &rAction );
};
//=========================================================================
diff --git a/svl/source/undo/undo.cxx b/svl/source/undo/undo.cxx
index b97ff1aaca3c..2f99e3aefbb0 100644
--- a/svl/source/undo/undo.cxx
+++ b/svl/source/undo/undo.cxx
@@ -34,6 +34,8 @@
#include <svl/undo.hxx>
+#include <vector>
+
using ::com::sun::star::uno::Exception;
// STATIC DATA -----------------------------------------------------------
@@ -150,6 +152,8 @@ BOOL SfxUndoAction::CanRepeat(SfxRepeatTarget&) const
//========================================================================
+typedef ::std::vector< SfxUndoListener* > UndoListeners;
+
struct SfxUndoManager_Data
{
SfxUndoArray* pUndoArray;
@@ -158,6 +162,8 @@ struct SfxUndoManager_Data
bool mbUndoEnabled;
+ UndoListeners aListeners;
+
SfxUndoManager_Data( USHORT i_nMaxUndoActionCount )
:pUndoArray( new SfxUndoArray( i_nMaxUndoActionCount ) )
,pActUndoArray( NULL )
@@ -185,6 +191,13 @@ SfxUndoManager::SfxUndoManager( USHORT nMaxUndoActionCount )
SfxUndoManager::~SfxUndoManager()
{
+ for ( UndoListeners::const_iterator listener = m_pData->aListeners.begin();
+ listener != m_pData->aListeners.end();
+ ++listener
+ )
+ {
+ (*listener)->undoManagerDying();
+ }
}
//------------------------------------------------------------------------
@@ -265,6 +278,14 @@ void SfxUndoManager::Clear()
}
m_pData->pActUndoArray->nCurUndoAction = 0;
+
+ for ( UndoListeners::const_iterator listener = m_pData->aListeners.begin();
+ listener != m_pData->aListeners.end();
+ ++listener
+ )
+ {
+ (*listener)->cleared();
+ }
}
//------------------------------------------------------------------------
@@ -278,6 +299,14 @@ void SfxUndoManager::ClearRedo()
m_pData->pActUndoArray->aUndoActions.Remove( m_pData->pActUndoArray->aUndoActions.Count() - 1 );
delete pAction;
}
+
+ for ( UndoListeners::const_iterator listener = m_pData->aListeners.begin();
+ listener != m_pData->aListeners.end();
+ ++listener
+ )
+ {
+ (*listener)->clearedRedo();
+ }
}
//------------------------------------------------------------------------
@@ -302,7 +331,7 @@ void SfxUndoManager::AddUndoAction( SfxUndoAction *pAction, BOOL bTryMerge )
if ( !bTryMerge || !(pTmpAction && pTmpAction->Merge(pAction)) )
{
- // auf Max-Anzahl anpassen
+ // respect max number
if( m_pData->pActUndoArray == m_pData->pUndoArray )
while( m_pData->pActUndoArray->aUndoActions.Count() >=
m_pData->pActUndoArray->nMaxUndoActions &&
@@ -313,10 +342,21 @@ void SfxUndoManager::AddUndoAction( SfxUndoAction *pAction, BOOL bTryMerge )
--m_pData->pActUndoArray->nCurUndoAction;
}
- // neue Action anh"angen
+ // append new action
const SfxUndoAction* pTemp = pAction;
m_pData->pActUndoArray->aUndoActions.Insert(
pTemp, m_pData->pActUndoArray->nCurUndoAction++ );
+
+ // notify listeners
+ for ( UndoListeners::const_iterator listener = m_pData->aListeners.begin();
+ listener != m_pData->aListeners.end();
+ ++listener
+ )
+ {
+ (*listener)->undoActionAdded( *pAction );
+ }
+
+ // outta here
return;
}
}
@@ -400,7 +440,7 @@ void SfxUndoManager::RemoveLastUndoAction()
//------------------------------------------------------------------------
-BOOL SfxUndoManager::Undo( USHORT )
+BOOL SfxUndoManager::Undo()
{
bool bUndoWasEnabled = m_pData->mbUndoEnabled;
m_pData->mbUndoEnabled = false;
@@ -412,7 +452,7 @@ BOOL SfxUndoManager::Undo( USHORT )
DBG_ASSERT( m_pData->pActUndoArray == m_pData->pUndoArray, "svl::SfxUndoManager::Undo(), LeaveListAction() not yet called!" );
if ( m_pData->pActUndoArray->nCurUndoAction )
{
- Undo( *m_pData->pActUndoArray->aUndoActions[ --m_pData->pActUndoArray->nCurUndoAction ] );
+ ImplUndo( *m_pData->pActUndoArray->aUndoActions[ --m_pData->pActUndoArray->nCurUndoAction ] );
bRet = TRUE;
}
}
@@ -427,13 +467,20 @@ BOOL SfxUndoManager::Undo( USHORT )
//------------------------------------------------------------------------
-void SfxUndoManager::Undo( SfxUndoAction &rAction )
+void SfxUndoManager::ImplUndo( SfxUndoAction &rAction )
{
bool bUndoWasEnabled = m_pData->mbUndoEnabled;
m_pData->mbUndoEnabled = false;
try
{
rAction.Undo();
+ for ( UndoListeners::const_iterator listener = m_pData->aListeners.begin();
+ listener != m_pData->aListeners.end();
+ ++listener
+ )
+ {
+ (*listener)->actionUndone( rAction );
+ }
}
catch( const Exception& )
{
@@ -467,7 +514,7 @@ USHORT SfxUndoManager::GetRedoActionId( USHORT nNo ) const
//------------------------------------------------------------------------
-BOOL SfxUndoManager::Redo( USHORT )
+BOOL SfxUndoManager::Redo()
{
bool bUndoWasEnabled = m_pData->mbUndoEnabled;
m_pData->mbUndoEnabled = false;
@@ -478,7 +525,7 @@ BOOL SfxUndoManager::Redo( USHORT )
{
if ( m_pData->pActUndoArray->aUndoActions.Count() > m_pData->pActUndoArray->nCurUndoAction )
{
- Redo( *m_pData->pActUndoArray->aUndoActions[m_pData->pActUndoArray->nCurUndoAction++] );
+ ImplRedo( *m_pData->pActUndoArray->aUndoActions[m_pData->pActUndoArray->nCurUndoAction++] );
bRet = TRUE;
}
}
@@ -494,7 +541,7 @@ BOOL SfxUndoManager::Redo( USHORT )
//------------------------------------------------------------------------
-void SfxUndoManager::Redo( SfxUndoAction &rAction )
+void SfxUndoManager::ImplRedo( SfxUndoAction &rAction )
{
bool bUndoWasEnabled = m_pData->mbUndoEnabled;
m_pData->mbUndoEnabled = false;
@@ -502,6 +549,13 @@ void SfxUndoManager::Redo( SfxUndoAction &rAction )
try
{
rAction.Redo();
+ for ( UndoListeners::const_iterator listener = m_pData->aListeners.begin();
+ listener != m_pData->aListeners.end();
+ ++listener
+ )
+ {
+ (*listener)->actionRedone( rAction );
+ }
}
catch( const Exception& )
{
@@ -570,6 +624,32 @@ BOOL SfxUndoManager::CanRepeat( SfxRepeatTarget &rTarget, USHORT nNo ) const
//------------------------------------------------------------------------
+void SfxUndoManager::AddUndoListener( SfxUndoListener& i_listener )
+{
+ DBG_TESTSOLARMUTEX();
+ m_pData->aListeners.push_back( &i_listener );
+}
+
+//------------------------------------------------------------------------
+
+void SfxUndoManager::RemoveUndoListener( SfxUndoListener& i_listener )
+{
+ DBG_TESTSOLARMUTEX();
+ for ( UndoListeners::iterator lookup = m_pData->aListeners.begin();
+ lookup != m_pData->aListeners.end();
+ ++lookup
+ )
+ {
+ if ( (*lookup) == &i_listener )
+ {
+ m_pData->aListeners.erase( lookup );
+ break;
+ }
+ }
+}
+
+//------------------------------------------------------------------------
+
void SfxUndoManager::EnterListAction(
const XubString& rComment, const XubString &rRepeatComment, USHORT nId )
@@ -590,6 +670,14 @@ void SfxUndoManager::EnterListAction(
rComment, rRepeatComment, nId, m_pData->pActUndoArray);
AddUndoAction( pAction );
m_pData->pActUndoArray=pAction;
+
+ for ( UndoListeners::const_iterator listener = m_pData->aListeners.begin();
+ listener != m_pData->aListeners.end();
+ ++listener
+ )
+ {
+ (*listener)->listActionEntered( rComment );
+ }
}
//------------------------------------------------------------------------
@@ -601,6 +689,22 @@ bool SfxUndoManager::IsInListAction() const
//------------------------------------------------------------------------
+USHORT SfxUndoManager::GetListActionDepth() const
+{
+ USHORT nDepth(0);
+
+ SfxUndoArray* pLookup( m_pData->pActUndoArray );
+ while ( pLookup != m_pData->pUndoArray )
+ {
+ pLookup = pLookup->pFatherUndoArray;
+ ++nDepth;
+ }
+
+ return nDepth;
+}
+
+//------------------------------------------------------------------------
+
void SfxUndoManager::LeaveListAction()
/* [Beschreibung]
@@ -649,6 +753,14 @@ void SfxUndoManager::LeaveListAction()
}
}
}
+
+ for ( UndoListeners::const_iterator listener = m_pData->aListeners.begin();
+ listener != m_pData->aListeners.end();
+ ++listener
+ )
+ {
+ (*listener)->listActionLeft();
+ }
}
//------------------------------------------------------------------------
@@ -765,7 +877,7 @@ SfxLinkUndoAction::SfxLinkUndoAction(SfxUndoManager *pManager)
void SfxLinkUndoAction::Undo()
{
if ( pAction )
- pUndoManager->Undo(1);
+ pUndoManager->Undo();
}
//------------------------------------------------------------------------
@@ -773,7 +885,7 @@ void SfxLinkUndoAction::Undo()
void SfxLinkUndoAction::Redo()
{
if ( pAction )
- pUndoManager->Redo(1);
+ pUndoManager->Redo();
}
//------------------------------------------------------------------------
diff --git a/svtools/source/edit/textundo.cxx b/svtools/source/edit/textundo.cxx
index 4c243de16c31..1ea2ee41efd0 100644
--- a/svtools/source/edit/textundo.cxx
+++ b/svtools/source/edit/textundo.cxx
@@ -54,7 +54,7 @@ TextUndoManager::~TextUndoManager()
{
}
-BOOL __EXPORT TextUndoManager::Undo( USHORT nCount )
+BOOL __EXPORT TextUndoManager::Undo()
{
if ( GetUndoActionCount() == 0 )
return FALSE;
@@ -62,7 +62,7 @@ BOOL __EXPORT TextUndoManager::Undo( USHORT nCount )
UndoRedoStart();
mpTextEngine->SetIsInUndo( TRUE );
- BOOL bDone = SfxUndoManager::Undo( nCount );
+ BOOL bDone = SfxUndoManager::Undo();
mpTextEngine->SetIsInUndo( FALSE );
UndoRedoEnd();
@@ -70,7 +70,7 @@ BOOL __EXPORT TextUndoManager::Undo( USHORT nCount )
return bDone;
}
-BOOL __EXPORT TextUndoManager::Redo( USHORT nCount )
+BOOL __EXPORT TextUndoManager::Redo()
{
if ( GetRedoActionCount() == 0 )
return FALSE;
@@ -79,7 +79,7 @@ BOOL __EXPORT TextUndoManager::Redo( USHORT nCount )
UndoRedoStart();
mpTextEngine->SetIsInUndo( TRUE );
- BOOL bDone = SfxUndoManager::Redo( nCount );
+ BOOL bDone = SfxUndoManager::Redo();
mpTextEngine->SetIsInUndo( FALSE );
UndoRedoEnd();
diff --git a/svtools/source/edit/textundo.hxx b/svtools/source/edit/textundo.hxx
index cc26c0b51ef6..27fe8933ad17 100644
--- a/svtools/source/edit/textundo.hxx
+++ b/svtools/source/edit/textundo.hxx
@@ -47,9 +47,9 @@ public:
~TextUndoManager();
using SfxUndoManager::Undo;
- virtual BOOL Undo( USHORT nCount=1 );
+ virtual BOOL Undo();
using SfxUndoManager::Redo;
- virtual BOOL Redo( USHORT nCount=1 );
+ virtual BOOL Redo();
};
diff --git a/svtools/source/edit/textview.cxx b/svtools/source/edit/textview.cxx
index 48cd23bdcc6f..a2f37c0bd34d 100644
--- a/svtools/source/edit/textview.cxx
+++ b/svtools/source/edit/textview.cxx
@@ -1122,13 +1122,13 @@ void TextView::Scroll( long ndX, long ndY )
void TextView::Undo()
{
mpImpl->mpTextEngine->SetActiveView( this );
- mpImpl->mpTextEngine->GetUndoManager().Undo( 1 );
+ mpImpl->mpTextEngine->GetUndoManager().Undo();
}
void TextView::Redo()
{
mpImpl->mpTextEngine->SetActiveView( this );
- mpImpl->mpTextEngine->GetUndoManager().Redo( 0 );
+ mpImpl->mpTextEngine->GetUndoManager().Redo();
}
void TextView::Cut()