summaryrefslogtreecommitdiff
path: root/svl/source/undo/undo.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'svl/source/undo/undo.cxx')
-rw-r--r--svl/source/undo/undo.cxx1502
1 files changed, 0 insertions, 1502 deletions
diff --git a/svl/source/undo/undo.cxx b/svl/source/undo/undo.cxx
deleted file mode 100644
index 03c970a06d..0000000000
--- a/svl/source/undo/undo.cxx
+++ /dev/null
@@ -1,1502 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*************************************************************************
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * Copyright 2000, 2010 Oracle and/or its affiliates.
- *
- * OpenOffice.org - a multi-platform office productivity suite
- *
- * This file is part of OpenOffice.org.
- *
- * OpenOffice.org is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License version 3
- * only, as published by the Free Software Foundation.
- *
- * OpenOffice.org is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License version 3 for more details
- * (a copy is included in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU Lesser General Public License
- * version 3 along with OpenOffice.org. If not, see
- * <http://www.openoffice.org/license.html>
- * for a copy of the LGPLv3 License.
- *
- ************************************************************************/
-
-// MARKER(update_precomp.py): autogen include statement, do not remove
-#include "precompiled_svl.hxx"
-
-#include <com/sun/star/uno/Exception.hpp>
-
-#include <comphelper/flagguard.hxx>
-#include <tools/debug.hxx>
-#include <tools/diagnose_ex.h>
-
-#include <svl/undo.hxx>
-
-#include <vector>
-#include <list>
-#include <limits>
-
-using ::com::sun::star::uno::Exception;
-
-// STATIC DATA -----------------------------------------------------------
-
-DBG_NAME(SfxUndoAction)
-
-//========================================================================
-
-TYPEINIT0(SfxUndoAction);
-TYPEINIT0(SfxListUndoAction);
-TYPEINIT0(SfxLinkUndoAction);
-TYPEINIT0(SfxRepeatTarget);
-
-//------------------------------------------------------------------------
-
-SfxRepeatTarget::~SfxRepeatTarget()
-{
-}
-
-//------------------------------------------------------------------------
-
-SfxUndoContext::~SfxUndoContext()
-{
-}
-
-//------------------------------------------------------------------------
-
-sal_Bool SfxUndoAction::IsLinked()
-{
- return bLinked;
-}
-
-//------------------------------------------------------------------------
-
-void SfxUndoAction::SetLinked( sal_Bool bIsLinked )
-{
- bLinked = bIsLinked;
-}
-
-//------------------------------------------------------------------------
-
-SfxUndoAction::~SfxUndoAction()
-{
- DBG_DTOR(SfxUndoAction, 0);
- DBG_ASSERT( !IsLinked(), "Gelinkte Action geloescht" );
-}
-
-
-SfxUndoAction::SfxUndoAction()
-{
- DBG_CTOR(SfxUndoAction, 0);
- SetLinked( sal_False );
-}
-
-//------------------------------------------------------------------------
-
-sal_Bool SfxUndoAction::Merge( SfxUndoAction * )
-{
- DBG_CHKTHIS(SfxUndoAction, 0);
- return sal_False;
-}
-
-//------------------------------------------------------------------------
-
-XubString SfxUndoAction::GetComment() const
-{
- DBG_CHKTHIS(SfxUndoAction, 0);
- return XubString();
-}
-
-//------------------------------------------------------------------------
-
-
-sal_uInt16 SfxUndoAction::GetId() const
-{
- DBG_CHKTHIS(SfxUndoAction, 0);
- return 0;
-}
-
-//------------------------------------------------------------------------
-
-XubString SfxUndoAction::GetRepeatComment(SfxRepeatTarget&) const
-{
- DBG_CHKTHIS(SfxUndoAction, 0);
- return GetComment();
-}
-
-//------------------------------------------------------------------------
-
-void SfxUndoAction::Undo()
-{
- // die sind nur konzeptuell pure virtual
- OSL_FAIL( "pure virtual function called: SfxUndoAction::Undo()" );
-}
-
-//------------------------------------------------------------------------
-
-void SfxUndoAction::UndoWithContext( SfxUndoContext& i_context )
-{
- (void)i_context;
- Undo();
-}
-
-//------------------------------------------------------------------------
-
-void SfxUndoAction::Redo()
-{
- // die sind nur konzeptuell pure virtual
- OSL_FAIL( "pure virtual function called: SfxUndoAction::Redo()" );
-}
-
-//------------------------------------------------------------------------
-
-void SfxUndoAction::RedoWithContext( SfxUndoContext& i_context )
-{
- (void)i_context;
- Redo();
-}
-
-//------------------------------------------------------------------------
-
-void SfxUndoAction::Repeat(SfxRepeatTarget&)
-{
- // die sind nur konzeptuell pure virtual
- OSL_FAIL( "pure virtual function called: SfxUndoAction::Repeat()" );
-}
-
-//------------------------------------------------------------------------
-
-
-sal_Bool SfxUndoAction::CanRepeat(SfxRepeatTarget&) const
-{
- return sal_True;
-}
-
-//========================================================================
-
-typedef ::std::vector< SfxUndoListener* > UndoListeners;
-
-struct SVL_DLLPRIVATE SfxUndoManager_Data
-{
- ::osl::Mutex aMutex;
- SfxUndoArray* pUndoArray;
- SfxUndoArray* pActUndoArray;
- SfxUndoArray* pFatherUndoArray;
-
- sal_Int32 mnLockCount;
- sal_Int32 mnMarks;
- sal_Int32 mnEmptyMark;
- bool mbDoing;
- bool mbClearUntilTopLevel;
-
- UndoListeners aListeners;
-
- SfxUndoManager_Data( size_t i_nMaxUndoActionCount )
- :pUndoArray( new SfxUndoArray( i_nMaxUndoActionCount ) )
- ,pActUndoArray( NULL )
- ,pFatherUndoArray( NULL )
- ,mnLockCount( 0 )
- ,mnMarks( 0 )
- ,mnEmptyMark(MARK_INVALID)
- ,mbDoing( false )
- ,mbClearUntilTopLevel( false )
- {
- pActUndoArray = pUndoArray;
- }
-
- ~SfxUndoManager_Data()
- {
- delete pUndoArray;
- }
-};
-
-//========================================================================
-
-namespace svl { namespace undo { namespace impl
-{
- //--------------------------------------------------------------------
- class SVL_DLLPRIVATE LockGuard
- {
- public:
- LockGuard( SfxUndoManager& i_manager )
- :m_manager( i_manager )
- {
- m_manager.ImplEnableUndo_Lock( false );
- }
-
- ~LockGuard()
- {
- m_manager.ImplEnableUndo_Lock( true );
- }
-
- private:
- SfxUndoManager& m_manager;
- };
-
- //--------------------------------------------------------------------
- typedef void ( SfxUndoListener::*UndoListenerVoidMethod )();
- typedef void ( SfxUndoListener::*UndoListenerStringMethod )( const String& );
-
- //--------------------------------------------------------------------
- struct SVL_DLLPRIVATE NotifyUndoListener : public ::std::unary_function< SfxUndoListener*, void >
- {
- NotifyUndoListener()
- :m_notificationMethod( NULL )
- ,m_altNotificationMethod( NULL )
- ,m_sActionComment()
- {
- }
-
- NotifyUndoListener( UndoListenerVoidMethod i_notificationMethod )
- :m_notificationMethod( i_notificationMethod )
- ,m_altNotificationMethod( NULL )
- ,m_sActionComment()
- {
- }
-
- NotifyUndoListener( UndoListenerStringMethod i_notificationMethod, const String& i_actionComment )
- :m_notificationMethod( NULL )
- ,m_altNotificationMethod( i_notificationMethod )
- ,m_sActionComment( i_actionComment )
- {
- }
-
- bool is() const
- {
- return ( m_notificationMethod != NULL ) || ( m_altNotificationMethod != NULL );
- }
-
- void operator()( SfxUndoListener* i_listener ) const
- {
- OSL_PRECOND( is(), "NotifyUndoListener: this will crash!" );
- if ( m_altNotificationMethod != NULL )
- {
- ( i_listener->*m_altNotificationMethod )( m_sActionComment );
- }
- else
- {
- ( i_listener->*m_notificationMethod )();
- }
- }
-
- private:
- UndoListenerVoidMethod m_notificationMethod;
- UndoListenerStringMethod m_altNotificationMethod;
- String m_sActionComment;
- };
-
- //--------------------------------------------------------------------
- class SVL_DLLPRIVATE UndoManagerGuard
- {
- public:
- UndoManagerGuard( SfxUndoManager_Data& i_managerData )
- :m_rManagerData( i_managerData )
- ,m_aGuard( i_managerData.aMutex )
- ,m_notifiers()
- {
- }
-
- ~UndoManagerGuard();
-
- void clear()
- {
- m_aGuard.clear();
- }
-
- void reset()
- {
- 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
- UndoManagerGuard. This deletion will happen without the UndoManager's mutex locked.
- */
- void markForDeletion( SfxUndoAction* i_action )
- {
- // remember
- if ( i_action )
- m_aUndoActionsCleanup.push_back( i_action );
- }
-
- /** schedules the given SfxUndoListener method to be called for all registered listeners.
-
- The notification will happen after the Undo manager's mutex has been released, and after all pending
- deletions of Undo actions are done.
- */
- void scheduleNotification( UndoListenerVoidMethod i_notificationMethod )
- {
- m_notifiers.push_back( NotifyUndoListener( i_notificationMethod ) );
- }
-
- void scheduleNotification( UndoListenerStringMethod i_notificationMethod, const String& i_actionComment )
- {
- m_notifiers.push_back( NotifyUndoListener( i_notificationMethod, i_actionComment ) );
- }
-
- private:
- SfxUndoManager_Data& m_rManagerData;
- ::osl::ResettableMutexGuard m_aGuard;
- ::std::list< SfxUndoAction* > m_aUndoActionsCleanup;
- ::std::list< NotifyUndoListener > m_notifiers;
- };
-
- UndoManagerGuard::~UndoManagerGuard()
- {
- // copy members
- UndoListeners aListenersCopy( m_rManagerData.aListeners );
-
- // release mutex
- m_aGuard.clear();
-
- // delete all actions
- while ( !m_aUndoActionsCleanup.empty() )
- {
- SfxUndoAction* pAction = m_aUndoActionsCleanup.front();
- m_aUndoActionsCleanup.pop_front();
- try
- {
- delete pAction;
- }
- catch( const Exception& )
- {
- DBG_UNHANDLED_EXCEPTION();
- }
- }
-
- // handle scheduled notification
- for ( ::std::list< NotifyUndoListener >::const_iterator notifier = m_notifiers.begin();
- notifier != m_notifiers.end();
- ++notifier
- )
- {
- if ( notifier->is() )
- ::std::for_each( aListenersCopy.begin(), aListenersCopy.end(), *notifier );
- }
- }
-} } }
-
-using namespace ::svl::undo::impl;
-
-//========================================================================
-
-SfxUndoManager::SfxUndoManager( size_t nMaxUndoActionCount )
- :m_pData( new SfxUndoManager_Data( nMaxUndoActionCount ) )
-{
-}
-
-//------------------------------------------------------------------------
-
-SfxUndoManager::~SfxUndoManager()
-{
- UndoListeners aListenersCopy;
- {
- UndoManagerGuard aGuard( *m_pData );
- aListenersCopy = m_pData->aListeners;
- }
-
- ::std::for_each( aListenersCopy.begin(), aListenersCopy.end(),
- NotifyUndoListener( &SfxUndoListener::undoManagerDying ) );
-}
-
-//------------------------------------------------------------------------
-
-void SfxUndoManager::EnableUndo( bool i_enable )
-{
- UndoManagerGuard aGuard( *m_pData );
- ImplEnableUndo_Lock( i_enable );
-
-}
-
-//------------------------------------------------------------------------
-
-void SfxUndoManager::ImplEnableUndo_Lock( bool const i_enable )
-{
- if ( !i_enable )
- ++m_pData->mnLockCount;
- else
- {
- OSL_PRECOND( m_pData->mnLockCount > 0, "SfxUndoManager::ImplEnableUndo_NoNotify: not disabled, so why enabling?" );
- if ( m_pData->mnLockCount > 0 )
- --m_pData->mnLockCount;
- }
-}
-
-//------------------------------------------------------------------------
-
-bool SfxUndoManager::IsUndoEnabled() const
-{
- UndoManagerGuard aGuard( *m_pData );
- return ImplIsUndoEnabled_Lock();
-}
-
-//------------------------------------------------------------------------
-
-bool SfxUndoManager::ImplIsUndoEnabled_Lock() const
-{
- return m_pData->mnLockCount == 0;
-}
-
-//------------------------------------------------------------------------
-
-void SfxUndoManager::SetMaxUndoActionCount( size_t nMaxUndoActionCount )
-{
- UndoManagerGuard aGuard( *m_pData );
-
- // Remove entries from the pActUndoArray when we have to reduce
- // the number of entries due to a lower nMaxUndoActionCount.
- // Both redo and undo action entries will be removed until we reached the
- // new nMaxUndoActionCount.
-
- long nNumToDelete = m_pData->pActUndoArray->aUndoActions.size() - nMaxUndoActionCount;
- while ( nNumToDelete > 0 )
- {
- size_t nPos = m_pData->pActUndoArray->aUndoActions.size();
- if ( nPos > m_pData->pActUndoArray->nCurUndoAction )
- {
- SfxUndoAction* pAction = m_pData->pActUndoArray->aUndoActions[nPos-1].pAction;
- if ( !pAction->IsLinked() )
- {
- aGuard.markForDeletion( pAction );
- m_pData->pActUndoArray->aUndoActions.Remove( nPos-1 );
- --nNumToDelete;
- }
- }
-
- if ( nNumToDelete > 0 && m_pData->pActUndoArray->nCurUndoAction > 0 )
- {
- SfxUndoAction* pAction = m_pData->pActUndoArray->aUndoActions[0].pAction;
- if ( !pAction->IsLinked() )
- {
- aGuard.markForDeletion( pAction );
- m_pData->pActUndoArray->aUndoActions.Remove(0);
- --m_pData->pActUndoArray->nCurUndoAction;
- --nNumToDelete;
- }
- }
-
- if ( nPos == m_pData->pActUndoArray->aUndoActions.size() )
- break; // Cannot delete more entries
- }
-
- m_pData->pActUndoArray->nMaxUndoActions = nMaxUndoActionCount;
-}
-
-//------------------------------------------------------------------------
-
-size_t SfxUndoManager::GetMaxUndoActionCount() const
-{
- UndoManagerGuard aGuard( *m_pData );
- return m_pData->pActUndoArray->nMaxUndoActions;
-}
-
-//------------------------------------------------------------------------
-
-void SfxUndoManager::ImplClearCurrentLevel_NoNotify( UndoManagerGuard& i_guard )
-{
- // clear array
- while ( !m_pData->pActUndoArray->aUndoActions.empty() )
- {
- 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;
- m_pData->mnEmptyMark = MARK_INVALID;
-}
-
-//------------------------------------------------------------------------
-
-void SfxUndoManager::Clear()
-{
- UndoManagerGuard aGuard( *m_pData );
-
- OSL_ENSURE( !ImplIsInListAction_Lock(), "SfxUndoManager::Clear: suspicious call - do you really wish to clear the current level?" );
- 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 );
- }
-}
-
-//------------------------------------------------------------------------
-
-void SfxUndoManager::ImplClearRedo_NoLock( bool const i_currentLevel )
-{
- UndoManagerGuard aGuard( *m_pData );
- ImplClearRedo( aGuard, i_currentLevel );
-}
-
-//------------------------------------------------------------------------
-
-void SfxUndoManager::ClearRedo()
-{
- OSL_ENSURE( !IsInListAction(), "SfxUndoManager::ClearRedo: suspicious call - do you really wish to clear the current level?" );
- ImplClearRedo_NoLock( CurrentLevel );
-}
-
-//------------------------------------------------------------------------
-
-void SfxUndoManager::Reset()
-{
- UndoManagerGuard aGuard( *m_pData );
-
- // clear all locks
- while ( !ImplIsUndoEnabled_Lock() )
- ImplEnableUndo_Lock( true );
-
- // cancel all list actions
- while ( IsInListAction() )
- ImplLeaveListAction( false, aGuard );
-
- // clear both stacks
- ImplClearCurrentLevel_NoNotify( aGuard );
-
- // cancel the notifications scheduled by ImplLeaveListAction,
- // 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 )
- {
- SfxUndoAction* pUndoAction = m_pData->pActUndoArray->aUndoActions[0].pAction;
- m_pData->pActUndoArray->aUndoActions.Remove( 0 );
- i_guard.markForDeletion( pUndoAction );
- --m_pData->pActUndoArray->nCurUndoAction;
- }
- // TODO: notifications? We don't have clearedUndo, only cleared and clearedRedo at the SfxUndoListener
-}
-
-//------------------------------------------------------------------------
-
-void SfxUndoManager::ImplClearRedo( UndoManagerGuard& i_guard, bool const i_currentLevel )
-{
- SfxUndoArray* pUndoArray = ( i_currentLevel == IUndoManager::CurrentLevel ) ? m_pData->pActUndoArray : m_pData->pUndoArray;
-
- // clearance
- while ( pUndoArray->aUndoActions.size() > pUndoArray->nCurUndoAction )
- {
- size_t deletePos = pUndoArray->aUndoActions.size() - 1;
- SfxUndoAction* pAction = pUndoArray->aUndoActions[ deletePos ].pAction;
- pUndoArray->aUndoActions.Remove( deletePos );
- i_guard.markForDeletion( pAction );
- }
-
- // notification - only if the top level's stack was cleared
- if ( i_currentLevel == IUndoManager::TopLevel )
- i_guard.scheduleNotification( &SfxUndoListener::clearedRedo );
-}
-
-//------------------------------------------------------------------------
-
-bool SfxUndoManager::ImplAddUndoAction_NoNotify( SfxUndoAction *pAction, bool bTryMerge, bool bClearRedo, UndoManagerGuard& i_guard )
-{
- if ( !ImplIsUndoEnabled_Lock() || ( m_pData->pActUndoArray->nMaxUndoActions == 0 ) )
- {
- i_guard.markForDeletion( pAction );
- return false;
- }
-
- // merge, if required
- SfxUndoAction* pMergeWithAction = m_pData->pActUndoArray->nCurUndoAction ?
- m_pData->pActUndoArray->aUndoActions[m_pData->pActUndoArray->nCurUndoAction-1].pAction : NULL;
- if ( bTryMerge && ( !pMergeWithAction || !pMergeWithAction->Merge( pAction ) ) )
- {
- i_guard.markForDeletion( pAction );
- return false;
- }
-
- // clear redo stack, if requested
- if ( bClearRedo && ( ImplGetRedoActionCount_Lock( CurrentLevel ) > 0 ) )
- ImplClearRedo( i_guard, IUndoManager::CurrentLevel );
-
- // respect max number
- if( m_pData->pActUndoArray == m_pData->pUndoArray )
- {
- while( m_pData->pActUndoArray->aUndoActions.size() >=
- m_pData->pActUndoArray->nMaxUndoActions &&
- !m_pData->pActUndoArray->aUndoActions[0].pAction->IsLinked() )
- {
- i_guard.markForDeletion( m_pData->pActUndoArray->aUndoActions[0].pAction );
- m_pData->pActUndoArray->aUndoActions.Remove(0);
- --m_pData->pActUndoArray->nCurUndoAction;
- }
- }
-
- // append new action
- m_pData->pActUndoArray->aUndoActions.Insert( pAction, m_pData->pActUndoArray->nCurUndoAction++ );
- return true;
-}
-
-//------------------------------------------------------------------------
-
-void SfxUndoManager::AddUndoAction( SfxUndoAction *pAction, sal_Bool bTryMerge )
-{
- UndoManagerGuard aGuard( *m_pData );
-
- // add
- if ( ImplAddUndoAction_NoNotify( pAction, bTryMerge, true, aGuard ) )
- {
- // notify listeners
- aGuard.scheduleNotification( &SfxUndoListener::undoActionAdded, pAction->GetComment() );
- }
-}
-
-//------------------------------------------------------------------------
-
-size_t SfxUndoManager::GetUndoActionCount( bool const i_currentLevel ) const
-{
- UndoManagerGuard aGuard( *m_pData );
- const SfxUndoArray* pUndoArray = i_currentLevel ? m_pData->pActUndoArray : m_pData->pUndoArray;
- return pUndoArray->nCurUndoAction;
-}
-
-//------------------------------------------------------------------------
-
-XubString SfxUndoManager::GetUndoActionComment( size_t nNo, bool const i_currentLevel ) const
-{
- UndoManagerGuard aGuard( *m_pData );
-
- String sComment;
- const SfxUndoArray* pUndoArray = i_currentLevel ? m_pData->pActUndoArray : m_pData->pUndoArray;
- DBG_ASSERT( nNo < pUndoArray->nCurUndoAction, "svl::SfxUndoManager::GetUndoActionComment: illegal index!" );
- if( nNo < pUndoArray->nCurUndoAction )
- {
- sComment = pUndoArray->aUndoActions[ pUndoArray->nCurUndoAction - 1 - nNo ].pAction->GetComment();
- }
- return sComment;
-}
-
-//------------------------------------------------------------------------
-
-sal_uInt16 SfxUndoManager::GetUndoActionId() const
-{
- UndoManagerGuard aGuard( *m_pData );
-
- DBG_ASSERT( m_pData->pActUndoArray->nCurUndoAction > 0, "svl::SfxUndoManager::GetUndoActionId(), illegal id!" );
- if ( m_pData->pActUndoArray->nCurUndoAction == 0 )
- return 0;
- return m_pData->pActUndoArray->aUndoActions[m_pData->pActUndoArray->nCurUndoAction-1].pAction->GetId();
-}
-
-//------------------------------------------------------------------------
-
-SfxUndoAction* SfxUndoManager::GetUndoAction( size_t nNo ) const
-{
- UndoManagerGuard aGuard( *m_pData );
-
- 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].pAction;
-}
-
-//------------------------------------------------------------------------
-
-/** clears the redo stack and removes the top undo action */
-void SfxUndoManager::RemoveLastUndoAction()
-{
- UndoManagerGuard aGuard( *m_pData );
-
- ENSURE_OR_RETURN_VOID( m_pData->pActUndoArray->nCurUndoAction, "svl::SfxUndoManager::RemoveLastUndoAction(), no action to remove?!" );
-
- m_pData->pActUndoArray->nCurUndoAction--;
-
- // delete redo-actions and top action
- for ( size_t nPos = m_pData->pActUndoArray->aUndoActions.size(); nPos > m_pData->pActUndoArray->nCurUndoAction; --nPos )
- {
- aGuard.markForDeletion( m_pData->pActUndoArray->aUndoActions[nPos-1].pAction );
- }
-
- m_pData->pActUndoArray->aUndoActions.Remove(
- m_pData->pActUndoArray->nCurUndoAction,
- m_pData->pActUndoArray->aUndoActions.size() - m_pData->pActUndoArray->nCurUndoAction );
-}
-
-//------------------------------------------------------------------------
-
-bool SfxUndoManager::IsDoing() const
-{
- UndoManagerGuard aGuard( *m_pData );
- return m_pData->mbDoing;
-}
-
-//------------------------------------------------------------------------
-
-sal_Bool SfxUndoManager::Undo()
-{
- return ImplUndo( NULL );
-}
-
-//------------------------------------------------------------------------
-
-sal_Bool SfxUndoManager::UndoWithContext( SfxUndoContext& i_context )
-{
- return ImplUndo( &i_context );
-}
-
-//------------------------------------------------------------------------
-
-sal_Bool SfxUndoManager::ImplUndo( SfxUndoContext* i_contextOrNull )
-{
- UndoManagerGuard aGuard( *m_pData );
- OSL_ENSURE( !IsDoing(), "SfxUndoManager::Undo: *nested* Undo/Redo actions? How this?" );
-
- ::comphelper::FlagGuard aDoingGuard( m_pData->mbDoing );
- LockGuard aLockGuard( *this );
-
- if ( ImplIsInListAction_Lock() )
- {
- OSL_ENSURE( false, "SfxUndoManager::Undo: not possible when within a list action!" );
- return sal_False;
- }
-
- if ( m_pData->pActUndoArray->nCurUndoAction == 0 )
- {
- OSL_ENSURE( false, "SfxUndoManager::Undo: undo stack is empty!" );
- return sal_False;
- }
-
- SfxUndoAction* pAction = m_pData->pActUndoArray->aUndoActions[ --m_pData->pActUndoArray->nCurUndoAction ].pAction;
- const String sActionComment = pAction->GetComment();
- try
- {
- // clear the guard/mutex before calling into the SfxUndoAction - this can be an extension-implemented UNO component
- // nowadays ...
- aGuard.clear();
- if ( i_contextOrNull != NULL )
- pAction->UndoWithContext( *i_contextOrNull );
- else
- pAction->Undo();
- aGuard.reset();
- }
- catch( ... )
- {
- aGuard.reset();
-
- // 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
- size_t nCurAction = 0;
- while ( nCurAction < m_pData->pActUndoArray->aUndoActions.size() )
- {
- 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
- ImplClearUndo( aGuard );
- throw;
- }
- }
- OSL_ENSURE( false, "SfxUndoManager::Undo: can't clear the Undo stack after the failure - some other party was faster ..." );
- throw;
- }
-
- aGuard.scheduleNotification( &SfxUndoListener::actionUndone, sActionComment );
-
- return sal_True;
-}
-
-//------------------------------------------------------------------------
-
-size_t SfxUndoManager::GetRedoActionCount( bool const i_currentLevel ) const
-{
- UndoManagerGuard aGuard( *m_pData );
- return ImplGetRedoActionCount_Lock( i_currentLevel );
-}
-
-//------------------------------------------------------------------------
-
-size_t SfxUndoManager::ImplGetRedoActionCount_Lock( bool const i_currentLevel ) const
-{
- const SfxUndoArray* pUndoArray = i_currentLevel ? m_pData->pActUndoArray : m_pData->pUndoArray;
- return pUndoArray->aUndoActions.size() - pUndoArray->nCurUndoAction;
-}
-
-//------------------------------------------------------------------------
-
-XubString SfxUndoManager::GetRedoActionComment( size_t nNo, bool const i_currentLevel ) const
-{
- UndoManagerGuard aGuard( *m_pData );
- const SfxUndoArray* pUndoArray = i_currentLevel ? m_pData->pActUndoArray : m_pData->pUndoArray;
- return pUndoArray->aUndoActions[ pUndoArray->nCurUndoAction + nNo ].pAction->GetComment();
-}
-
-//------------------------------------------------------------------------
-
-sal_Bool SfxUndoManager::Redo()
-{
- return ImplRedo( NULL );
-}
-
-//------------------------------------------------------------------------
-
-sal_Bool SfxUndoManager::RedoWithContext( SfxUndoContext& i_context )
-{
- return ImplRedo( &i_context );
-}
-
-//------------------------------------------------------------------------
-
-sal_Bool SfxUndoManager::ImplRedo( SfxUndoContext* i_contextOrNull )
-{
- UndoManagerGuard aGuard( *m_pData );
- OSL_ENSURE( !IsDoing(), "SfxUndoManager::Redo: *nested* Undo/Redo actions? How this?" );
-
- ::comphelper::FlagGuard aDoingGuard( m_pData->mbDoing );
- LockGuard aLockGuard( *this );
-
- if ( ImplIsInListAction_Lock() )
- {
- OSL_ENSURE( false, "SfxUndoManager::Redo: not possible when within a list action!" );
- return sal_False;
- }
-
- if ( m_pData->pActUndoArray->nCurUndoAction >= m_pData->pActUndoArray->aUndoActions.size() )
- {
- OSL_ENSURE( false, "SfxUndoManager::Redo: redo stack is empty!" );
- return sal_False;
- }
-
- SfxUndoAction* pAction = m_pData->pActUndoArray->aUndoActions[ m_pData->pActUndoArray->nCurUndoAction++ ].pAction;
- const String sActionComment = pAction->GetComment();
- try
- {
- // clear the guard/mutex before calling into the SfxUndoAction - this can be a extension-implemented UNO component
- // nowadays ...
- aGuard.clear();
- if ( i_contextOrNull != NULL )
- pAction->RedoWithContext( *i_contextOrNull );
- else
- pAction->Redo();
- aGuard.reset();
- }
- catch( ... )
- {
- aGuard.reset();
-
- // 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
- size_t nCurAction = 0;
- while ( nCurAction < m_pData->pActUndoArray->aUndoActions.size() )
- {
- 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
- ImplClearRedo( aGuard, IUndoManager::CurrentLevel );
- throw;
- }
- ++nCurAction;
- }
- OSL_ENSURE( false, "SfxUndoManager::Redo: can't clear the Undo stack after the failure - some other party was faster ..." );
- throw;
- }
-
- aGuard.scheduleNotification( &SfxUndoListener::actionRedone, sActionComment );
-
- return sal_True;
-}
-
-//------------------------------------------------------------------------
-
-size_t SfxUndoManager::GetRepeatActionCount() const
-{
- UndoManagerGuard aGuard( *m_pData );
- return m_pData->pActUndoArray->aUndoActions.size();
-}
-
-//------------------------------------------------------------------------
-
-XubString SfxUndoManager::GetRepeatActionComment( SfxRepeatTarget &rTarget) const
-{
- UndoManagerGuard aGuard( *m_pData );
- return m_pData->pActUndoArray->aUndoActions[ m_pData->pActUndoArray->aUndoActions.size() - 1 ].pAction
- ->GetRepeatComment(rTarget);
-}
-
-//------------------------------------------------------------------------
-
-sal_Bool SfxUndoManager::Repeat( SfxRepeatTarget &rTarget )
-{
- UndoManagerGuard aGuard( *m_pData );
- if ( !m_pData->pActUndoArray->aUndoActions.empty() )
- {
- SfxUndoAction* pAction = m_pData->pActUndoArray->aUndoActions[ m_pData->pActUndoArray->aUndoActions.size() - 1 ].pAction;
- aGuard.clear();
- if ( pAction->CanRepeat( rTarget ) )
- pAction->Repeat( rTarget );
- return sal_True;
- }
-
- return sal_False;
-}
-
-//------------------------------------------------------------------------
-
-sal_Bool SfxUndoManager::CanRepeat( SfxRepeatTarget &rTarget ) const
-{
- UndoManagerGuard aGuard( *m_pData );
- if ( !m_pData->pActUndoArray->aUndoActions.empty() )
- {
- size_t nActionNo = m_pData->pActUndoArray->aUndoActions.size() - 1;
- return m_pData->pActUndoArray->aUndoActions[nActionNo].pAction->CanRepeat(rTarget);
- }
- return sal_False;
-}
-
-//------------------------------------------------------------------------
-
-void SfxUndoManager::AddUndoListener( SfxUndoListener& i_listener )
-{
- UndoManagerGuard aGuard( *m_pData );
- m_pData->aListeners.push_back( &i_listener );
-}
-
-//------------------------------------------------------------------------
-
-void SfxUndoManager::RemoveUndoListener( SfxUndoListener& i_listener )
-{
- UndoManagerGuard aGuard( *m_pData );
- 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, sal_uInt16 nId )
-
-/* [Beschreibung]
-
- Fuegt eine ListUndoAction ein und setzt dessen UndoArray als aktuelles.
-*/
-
-{
- UndoManagerGuard aGuard( *m_pData );
-
- if( !ImplIsUndoEnabled_Lock() )
- return;
-
- if ( !m_pData->pUndoArray->nMaxUndoActions )
- return;
-
- m_pData->pFatherUndoArray = m_pData->pActUndoArray;
- SfxListUndoAction* pAction = new SfxListUndoAction( rComment, rRepeatComment, nId, m_pData->pActUndoArray );
- OSL_VERIFY( ImplAddUndoAction_NoNotify( pAction, false, false, aGuard ) );
- // expected to succeed: all conditions under which it could fail should have been checked already
- m_pData->pActUndoArray = pAction;
-
- // notification
- aGuard.scheduleNotification( &SfxUndoListener::listActionEntered, rComment );
-}
-
-//------------------------------------------------------------------------
-
-bool SfxUndoManager::IsInListAction() const
-{
- UndoManagerGuard aGuard( *m_pData );
- return ImplIsInListAction_Lock();
-}
-
-//------------------------------------------------------------------------
-
-bool SfxUndoManager::ImplIsInListAction_Lock() const
-{
- return ( m_pData->pActUndoArray != m_pData->pUndoArray );
-}
-
-//------------------------------------------------------------------------
-
-size_t SfxUndoManager::GetListActionDepth() const
-{
- UndoManagerGuard aGuard( *m_pData );
- size_t nDepth(0);
-
- SfxUndoArray* pLookup( m_pData->pActUndoArray );
- while ( pLookup != m_pData->pUndoArray )
- {
- pLookup = pLookup->pFatherUndoArray;
- ++nDepth;
- }
-
- return nDepth;
-}
-
-//------------------------------------------------------------------------
-
-size_t SfxUndoManager::LeaveListAction()
-{
- UndoManagerGuard aGuard( *m_pData );
- 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;
-}
-
-//------------------------------------------------------------------------
-
-size_t SfxUndoManager::LeaveAndMergeListAction()
-{
- UndoManagerGuard aGuard( *m_pData );
- return ImplLeaveListAction( true, aGuard );
-}
-
-//------------------------------------------------------------------------
-
-size_t SfxUndoManager::ImplLeaveListAction( const bool i_merge, UndoManagerGuard& i_guard )
-{
- if ( !ImplIsUndoEnabled_Lock() )
- return 0;
-
- if ( !m_pData->pUndoArray->nMaxUndoActions )
- return 0;
-
- if( !ImplIsInListAction_Lock() )
- {
- OSL_TRACE( "svl::SfxUndoManager::ImplLeaveListAction, called without calling EnterListAction()!" );
- return 0;
- }
-
- 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;
- // one step up
- m_pData->pActUndoArray = m_pData->pActUndoArray->pFatherUndoArray;
-
- // If no undo actions were added to the list, delete the list action
- const size_t nListActionElements = pArrayToLeave->nCurUndoAction;
- if ( nListActionElements == 0 )
- {
- 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 );
-
- i_guard.scheduleNotification( &SfxUndoListener::listActionCancelled );
- return 0;
- }
-
- // now that it is finally clear the list action is non-trivial, and does participate in the Undo stack, clear
- // the redo stack
- ImplClearRedo( i_guard, IUndoManager::CurrentLevel );
-
- 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 );
-
- if ( i_merge )
- {
- // merge the list action with its predecessor on the same level
- OSL_ENSURE( m_pData->pActUndoArray->nCurUndoAction > 1,
- "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 )
- {
- 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 );
- ++pListAction->nCurUndoAction;
-
- pListAction->SetComment( pPreviousAction->GetComment() );
- }
- }
-
- // if the undo array has no comment, try to get it from its children
- if ( pListAction->GetComment().Len() == 0 )
- {
- for( size_t n = 0; n < pListAction->aUndoActions.size(); n++ )
- {
- if( pListAction->aUndoActions[n].pAction->GetComment().Len() )
- {
- pListAction->SetComment( pListAction->aUndoActions[n].pAction->GetComment() );
- break;
- }
- }
- }
-
- // notify listeners
- i_guard.scheduleNotification( &SfxUndoListener::listActionLeft, pListAction->GetComment() );
-
- // outta here
- return nListActionElements;
-}
-
-//------------------------------------------------------------------------
-UndoStackMark SfxUndoManager::MarkTopUndoAction()
-{
- UndoManagerGuard aGuard( *m_pData );
-
- OSL_ENSURE( !IsInListAction(),
- "SfxUndoManager::MarkTopUndoAction(): suspicious call!" );
- OSL_ENSURE((m_pData->mnMarks + 1) < (m_pData->mnEmptyMark - 1),
- "SfxUndoManager::MarkTopUndoAction(): mark overflow!");
-
- size_t const nActionPos = m_pData->pUndoArray->nCurUndoAction;
- if (0 == nActionPos)
- {
- --m_pData->mnEmptyMark;
- return m_pData->mnEmptyMark;
- }
-
- m_pData->pUndoArray->aUndoActions[ nActionPos-1 ].aMarks.push_back(
- ++m_pData->mnMarks );
- return m_pData->mnMarks;
-}
-
-//------------------------------------------------------------------------
-void SfxUndoManager::RemoveMark( UndoStackMark const i_mark )
-{
- UndoManagerGuard aGuard( *m_pData );
-
- if ((m_pData->mnEmptyMark < i_mark) || (MARK_INVALID == i_mark))
- {
- return; // nothing to remove
- }
- else if (i_mark == m_pData->mnEmptyMark)
- {
- --m_pData->mnEmptyMark; // never returned from MarkTop => invalid
- return;
- }
-
- 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 );
-
- size_t nActionPos = m_pData->pUndoArray->nCurUndoAction;
- if ( nActionPos == 0 )
- {
- return (i_mark == m_pData->mnEmptyMark);
- }
-
- const MarkedUndoAction& rAction =
- m_pData->pUndoArray->aUndoActions[ nActionPos-1 ];
- for ( ::std::vector< UndoStackMark >::const_iterator markPos = rAction.aMarks.begin();
- markPos != rAction.aMarks.end();
- ++markPos
- )
- {
- if ( *markPos == i_mark )
- return true;
- }
-
- return false;
-}
-
-//------------------------------------------------------------------------
-
-void SfxUndoManager::RemoveOldestUndoActions( size_t const i_count )
-{
- UndoManagerGuard aGuard( *m_pData );
-
- size_t nActionsToRemove = i_count;
- while ( nActionsToRemove )
- {
- SfxUndoAction* pActionToRemove = m_pData->pUndoArray->aUndoActions[0].pAction;
-
- if ( IsInListAction() && ( m_pData->pUndoArray->nCurUndoAction == 1 ) )
- {
- OSL_ENSURE( false, "SfxUndoManager::RemoveOldestUndoActions: cannot remove a not-yet-closed list action!" );
- return;
- }
-
- aGuard.markForDeletion( pActionToRemove );
- m_pData->pUndoArray->aUndoActions.Remove( 0 );
- --m_pData->pUndoArray->nCurUndoAction;
- --nActionsToRemove;
- }
-}
-
-//------------------------------------------------------------------------
-
-sal_uInt16 SfxListUndoAction::GetId() const
-{
- return nId;
-}
-
-//------------------------------------------------------------------------
-
-XubString SfxListUndoAction::GetComment() const
-{
- return aComment;
-}
-
-//------------------------------------------------------------------------
-
-void SfxListUndoAction::SetComment( const UniString& rComment )
-{
- aComment = rComment;
-}
-
-//------------------------------------------------------------------------
-
-XubString SfxListUndoAction::GetRepeatComment(SfxRepeatTarget &) const
-{
- return aRepeatComment;
-}
-
-
-//------------------------------------------------------------------------
-
-SfxListUndoAction::SfxListUndoAction
-(
- const XubString &rComment,
- const XubString rRepeatComment,
- sal_uInt16 Id,
- SfxUndoArray *pFather
-)
-: nId(Id), aComment(rComment), aRepeatComment(rRepeatComment)
-{
- pFatherUndoArray = pFather;
- nMaxUndoActions = USHRT_MAX;
-}
-
-//------------------------------------------------------------------------
-
-void SfxListUndoAction::Undo()
-{
- for(size_t i=nCurUndoAction;i>0;)
- aUndoActions[--i].pAction->Undo();
- nCurUndoAction=0;
-}
-
-//------------------------------------------------------------------------
-
-void SfxListUndoAction::UndoWithContext( SfxUndoContext& i_context )
-{
- for(size_t i=nCurUndoAction;i>0;)
- aUndoActions[--i].pAction->UndoWithContext( i_context );
- nCurUndoAction=0;
-}
-
-//------------------------------------------------------------------------
-
-void SfxListUndoAction::Redo()
-{
- for(size_t i=nCurUndoAction;i<aUndoActions.size();i++)
- aUndoActions[i].pAction->Redo();
- nCurUndoAction = aUndoActions.size();
-}
-
-//------------------------------------------------------------------------
-
-void SfxListUndoAction::RedoWithContext( SfxUndoContext& i_context )
-{
- for(size_t i=nCurUndoAction;i<aUndoActions.size();i++)
- aUndoActions[i].pAction->RedoWithContext( i_context );
- nCurUndoAction = aUndoActions.size();
-}
-
-//------------------------------------------------------------------------
-
-void SfxListUndoAction::Repeat(SfxRepeatTarget&rTarget)
-{
- for(size_t i=0;i<nCurUndoAction;i++)
- aUndoActions[i].pAction->Repeat(rTarget);
-}
-
-//------------------------------------------------------------------------
-
-sal_Bool SfxListUndoAction::CanRepeat(SfxRepeatTarget&r) const
-{
- for(size_t i=0;i<nCurUndoAction;i++)
- if(!aUndoActions[i].pAction->CanRepeat(r))
- return sal_False;
- return sal_True;
-}
-
-//------------------------------------------------------------------------
-
-sal_Bool SfxListUndoAction::Merge( SfxUndoAction *pNextAction )
-{
- return !aUndoActions.empty() && aUndoActions[aUndoActions.size()-1].pAction->Merge( pNextAction );
-}
-
-//------------------------------------------------------------------------
-
-SfxLinkUndoAction::SfxLinkUndoAction(::svl::IUndoManager *pManager)
-/* [Beschreibung]
-
- Richtet eine LinkAction ein, die auf einen weiteren UndoManager zeigt.
- Holt sich als zugehoerige Action des weiteren UndoManagers dessen
- aktuelle Action.
-*/
-
-{
- pUndoManager = pManager;
- SfxUndoManager* pUndoManagerImplementation = dynamic_cast< SfxUndoManager* >( pManager );
- ENSURE_OR_THROW( pUndoManagerImplementation != NULL, "unsupported undo manager implementation!" );
- // yes, this cast is dirty. But reaching into the the SfxUndoManager's implementation,
- // directly accessing its internal stack, and tampering with an action on that stack
- // is dirty, too.
- if ( pManager->GetMaxUndoActionCount() )
- {
- size_t nPos = pManager->GetUndoActionCount()-1;
- pAction = pUndoManagerImplementation->m_pData->pActUndoArray->aUndoActions[nPos].pAction;
- pAction->SetLinked();
- }
- else
- pAction = 0;
-}
-
-//------------------------------------------------------------------------
-
-void SfxLinkUndoAction::Undo()
-{
- if ( pAction )
- pUndoManager->Undo();
-}
-
-//------------------------------------------------------------------------
-
-void SfxLinkUndoAction::Redo()
-{
- if ( pAction )
- pUndoManager->Redo();
-}
-
-//------------------------------------------------------------------------
-
-
-sal_Bool SfxLinkUndoAction::CanRepeat(SfxRepeatTarget& r) const
-{
- return pAction && pAction->CanRepeat(r);
-}
-
-
-//------------------------------------------------------------------------
-
-
-void SfxLinkUndoAction::Repeat(SfxRepeatTarget&r)
-{
- if ( pAction && pAction->CanRepeat( r ) )
- pAction->Repeat( r );
-}
-
-
-//------------------------------------------------------------------------
-
-XubString SfxLinkUndoAction::GetComment() const
-{
- if ( pAction )
- return pAction->GetComment();
- else
- return XubString();
-}
-
-
-//------------------------------------------------------------------------
-
-XubString SfxLinkUndoAction::GetRepeatComment(SfxRepeatTarget&r) const
-{
- if ( pAction )
- return pAction->GetRepeatComment(r);
- else
- return XubString();
-}
-
-//------------------------------------------------------------------------
-
-SfxLinkUndoAction::~SfxLinkUndoAction()
-{
- if( pAction )
- pAction->SetLinked( sal_False );
-}
-
-
-//------------------------------------------------------------------------
-
-SfxUndoArray::~SfxUndoArray()
-{
- while ( !aUndoActions.empty() )
- {
- SfxUndoAction *pAction = aUndoActions[ aUndoActions.size() - 1 ].pAction;
- aUndoActions.Remove( aUndoActions.size() - 1 );
- delete pAction;
- }
-}
-
-
-sal_uInt16 SfxLinkUndoAction::GetId() const
-{
- return pAction ? pAction->GetId() : 0;
-}
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */