summaryrefslogtreecommitdiff
path: root/sfx2/source/doc/docundomanager.cxx
diff options
context:
space:
mode:
authorFrank Schoenheit [fs] <frank.schoenheit@oracle.com>2010-11-09 21:36:57 +0100
committerFrank Schoenheit [fs] <frank.schoenheit@oracle.com>2010-11-09 21:36:57 +0100
commitd729112009418c02a2659b367bcb35a81ee9307c (patch)
tree0ac612a32368647ba8b7889b1f455edbc3dac40f /sfx2/source/doc/docundomanager.cxx
parent7b8f9e3ecb2d6cae3edd08c824cb551035d93635 (diff)
undoapi: step 1 of the migration of css.chart2.XUndoManager to css.document.XUndoManager: separate the DocumentUndoManager into a (SFX-independent) UndoManagerHelper (which later on can be used in chart2) and the SFX-dependent part
Diffstat (limited to 'sfx2/source/doc/docundomanager.cxx')
-rwxr-xr-xsfx2/source/doc/docundomanager.cxx683
1 files changed, 126 insertions, 557 deletions
diff --git a/sfx2/source/doc/docundomanager.cxx b/sfx2/source/doc/docundomanager.cxx
index ade11d18b05f..39534bf9f90c 100755
--- a/sfx2/source/doc/docundomanager.cxx
+++ b/sfx2/source/doc/docundomanager.cxx
@@ -42,6 +42,7 @@
#include <comphelper/flagguard.hxx>
#include <svl/undo.hxx>
#include <tools/diagnose_ex.h>
+#include <framework/undomanagerhelper.hxx>
#include <stack>
@@ -81,310 +82,135 @@ namespace sfx2
using ::svl::IUndoManager;
//==================================================================================================================
- //= UndoActionWrapper
- //==================================================================================================================
- class UndoActionWrapper : public SfxUndoAction
- {
- public:
- UndoActionWrapper(
- Reference< XUndoAction > const& i_undoAction
- );
- virtual ~UndoActionWrapper();
-
- virtual String GetComment() const;
- virtual void Undo();
- virtual void Redo();
- virtual BOOL CanRepeat(SfxRepeatTarget&) const;
-
- private:
- const Reference< XUndoAction > m_xUndoAction;
- };
-
- //------------------------------------------------------------------------------------------------------------------
- UndoActionWrapper::UndoActionWrapper( Reference< XUndoAction > const& i_undoAction )
- :SfxUndoAction()
- ,m_xUndoAction( i_undoAction )
- {
- ENSURE_OR_THROW( m_xUndoAction.is(), "illegal undo action" );
- }
-
- //------------------------------------------------------------------------------------------------------------------
- UndoActionWrapper::~UndoActionWrapper()
- {
- try
- {
- Reference< XComponent > xComponent( m_xUndoAction, UNO_QUERY );
- if ( xComponent.is() )
- xComponent->dispose();
- }
- catch( const Exception& )
- {
- DBG_UNHANDLED_EXCEPTION();
- }
- }
-
- //------------------------------------------------------------------------------------------------------------------
- String UndoActionWrapper::GetComment() const
- {
- String sComment;
- try
- {
- sComment = m_xUndoAction->getTitle();
- }
- catch( const Exception& )
- {
- DBG_UNHANDLED_EXCEPTION();
- }
- return sComment;
- }
-
- //------------------------------------------------------------------------------------------------------------------
- void UndoActionWrapper::Undo()
- {
- m_xUndoAction->undo();
- }
-
- //------------------------------------------------------------------------------------------------------------------
- void UndoActionWrapper::Redo()
- {
- m_xUndoAction->redo();
- }
-
- //------------------------------------------------------------------------------------------------------------------
- BOOL UndoActionWrapper::CanRepeat(SfxRepeatTarget&) const
- {
- return FALSE;
- }
-
- //==================================================================================================================
//= DocumentUndoManager_Impl
//==================================================================================================================
- struct DocumentUndoManager_Impl : public SfxUndoListener
+ struct DocumentUndoManager_Impl : public ::framework::IUndoManagerImplementation
{
- ::cppu::OInterfaceContainerHelper aUndoListeners;
- IUndoManager* pUndoManager;
DocumentUndoManager& rAntiImpl;
- bool bAPIActionRunning;
- ::std::stack< bool > aContextVisibilities;
-#if OSL_DEBUG_LEVEL > 0
- ::std::stack< bool > aContextAPIFlags;
-#endif
+ IUndoManager* pUndoManager;
+ ::framework::UndoManagerHelper aUndoHelper;
DocumentUndoManager_Impl( DocumentUndoManager& i_antiImpl )
- :aUndoListeners( i_antiImpl.getMutex() )
- ,pUndoManager( NULL )
- ,rAntiImpl( i_antiImpl )
- ,bAPIActionRunning( false )
+ :rAntiImpl( i_antiImpl )
+ ,pUndoManager( impl_retrieveUndoManager( i_antiImpl.getBaseModel() ) )
+ // do this *before* the construction of aUndoHelper (which actually means: put pUndoManager before
+ // aUndoHelper in the member list)!
+ ,aUndoHelper( *this )
{
- SfxObjectShell* pObjectShell = i_antiImpl.getBaseModel().GetObjectShell();
- if ( pObjectShell != NULL )
- pUndoManager = pObjectShell->GetUndoManager();
- if ( !pUndoManager )
- throw NotInitializedException( ::rtl::OUString(), *&i_antiImpl.getBaseModel() );
- // TODO: we probably should add ourself as listener to the SfxObjectShell, in case somebody sets a new
- // UndoManager
- // (well, adding a listener for this is not possible currently, but I also think that setting a new
- // UndoManager does not happen in real life)
- pUndoManager->AddUndoListener( *this );
}
const SfxObjectShell* getObjectShell() const { return rAntiImpl.getBaseModel().GetObjectShell(); }
SfxObjectShell* getObjectShell() { return rAntiImpl.getBaseModel().GetObjectShell(); }
- //..............................................................................................................
- IUndoManager& getUndoManager()
- {
- ENSURE_OR_THROW( pUndoManager != NULL, "DocumentUndoManager_Impl::getUndoManager: no access to the doc's UndoManager implementation!" );
-
-#if OSL_DEBUG_LEVEL > 0
- // in a non-product build, assert if the current UndoManager at the shell is not the same we obtained
- // (and cached) at construction time
- SfxObjectShell* pObjectShell = rAntiImpl.getBaseModel().GetObjectShell();
- OSL_ENSURE( ( pObjectShell != NULL ) && ( pUndoManager == pObjectShell->GetUndoManager() ),
- "DocumentUndoManager_Impl::getUndoManager: the UndoManager changed meanwhile - what about our listener?" );
-#endif
-
- return *pUndoManager;
- }
+ // IUndoManagerImplementation
+ virtual ::osl::Mutex& getMutex();
+ virtual ::svl::IUndoManager& getImplUndoManager();
+ virtual Reference< XUndoManager > getThis();
void disposing()
{
+ aUndoHelper.disposing();
ENSURE_OR_RETURN_VOID( pUndoManager, "DocumentUndoManager_Impl::disposing: already disposed!" );
- pUndoManager->RemoveUndoListener( *this );
pUndoManager = NULL;
}
- // SfxUndoListener
- virtual void actionUndone( SfxUndoAction& i_action );
- virtual void actionRedone( SfxUndoAction& i_action );
- virtual void undoActionAdded( SfxUndoAction& i_action );
- virtual void cleared();
- virtual void clearedRedo();
- virtual void listActionEntered( const String& i_comment );
- virtual void listActionLeft();
- virtual void listActionLeftAndMerged();
- virtual void listActionCancelled();
- virtual void undoManagerDying();
-
- // public operations
- void enterUndoContext( const ::rtl::OUString& i_title, const bool i_hidden );
- };
+ void invalidateXDo_nolck();
+ void enterViewStandardMode();
- //==================================================================================================================
- namespace
- {
- //..............................................................................................................
- void lcl_invalidateXDo( const DocumentUndoManager_Impl& i_impl )
+ private:
+ static IUndoManager* impl_retrieveUndoManager( SfxBaseModel& i_baseModel )
{
- const SfxObjectShell* pDocShell = i_impl.getObjectShell();
- ENSURE_OR_THROW( pDocShell != NULL, "lcl_invalidateUndo: no access to the doc shell!" );
- SfxViewFrame* pViewFrame = SfxViewFrame::GetFirst( pDocShell );
- while ( pViewFrame )
- {
- pViewFrame->GetBindings().Invalidate( SID_UNDO );
- pViewFrame->GetBindings().Invalidate( SID_REDO );
- pViewFrame = SfxViewFrame::GetNext( *pViewFrame, pDocShell );
- }
+ IUndoManager* pUndoManager( NULL );
+ SfxObjectShell* pObjectShell = i_baseModel.GetObjectShell();
+ if ( pObjectShell != NULL )
+ pUndoManager = pObjectShell->GetUndoManager();
+ if ( !pUndoManager )
+ throw NotInitializedException( ::rtl::OUString(), *&i_baseModel );
+ return pUndoManager;
}
-
- }
+ };
//------------------------------------------------------------------------------------------------------------------
- void DocumentUndoManager_Impl::enterUndoContext( const ::rtl::OUString& i_title, const bool i_hidden )
+ ::osl::Mutex& DocumentUndoManager_Impl::getMutex()
{
- // SYNCHRONIZED --->
- SfxModelGuard aGuard( rAntiImpl );
-
- IUndoManager& rUndoManager = getUndoManager();
- if ( !rUndoManager.IsUndoEnabled() )
- // ignore this request if the manager is locked
- return;
-
- if ( i_hidden && ( rUndoManager.GetUndoActionCount( IUndoManager::CurrentLevel ) == 0 ) )
- throw EmptyUndoStackException(
- ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "can't enter a hidden context without a previous Undo action" ) ),
- static_cast< XUndoManager* >( &rAntiImpl )
- );
-
- {
- ::comphelper::FlagGuard aNotificationGuard( bAPIActionRunning );
- rUndoManager.EnterListAction( i_title, ::rtl::OUString() );
- }
-
- aContextVisibilities.push( i_hidden );
-
- rAntiImpl.impl_notify( i_title, i_hidden ? &XUndoManagerListener::enteredHiddenContext : &XUndoManagerListener::enteredContext, aGuard );
- // <--- SYNCHRONIZED
+ return rAntiImpl.getMutex();
}
//------------------------------------------------------------------------------------------------------------------
- void DocumentUndoManager_Impl::actionUndone( SfxUndoAction& i_action )
+ ::svl::IUndoManager& DocumentUndoManager_Impl::getImplUndoManager()
{
- if ( bAPIActionRunning )
- return;
+ ENSURE_OR_THROW( pUndoManager != NULL, "DocumentUndoManager_Impl::getImplUndoManager: no access to the doc's UndoManager implementation!" );
- rAntiImpl.impl_notify( i_action.GetComment(), &XUndoManagerListener::actionUndone );
- }
-
- //------------------------------------------------------------------------------------------------------------------
- void DocumentUndoManager_Impl::actionRedone( SfxUndoAction& i_action )
- {
- if ( bAPIActionRunning )
- return;
-
- rAntiImpl.impl_notify( i_action.GetComment(), &XUndoManagerListener::actionRedone );
- }
-
- //------------------------------------------------------------------------------------------------------------------
- void DocumentUndoManager_Impl::undoActionAdded( SfxUndoAction& i_action )
- {
- if ( bAPIActionRunning )
- return;
-
- rAntiImpl.impl_notify( i_action.GetComment(), &XUndoManagerListener::undoActionAdded );
- }
-
- //------------------------------------------------------------------------------------------------------------------
- void DocumentUndoManager_Impl::cleared()
- {
- if ( bAPIActionRunning )
- return;
-
- rAntiImpl.impl_notify( &XUndoManagerListener::allActionsCleared );
- }
-
- //------------------------------------------------------------------------------------------------------------------
- void DocumentUndoManager_Impl::clearedRedo()
- {
- if ( bAPIActionRunning )
- return;
-
- rAntiImpl.impl_notify( &XUndoManagerListener::redoActionsCleared );
- }
-
- //------------------------------------------------------------------------------------------------------------------
- void DocumentUndoManager_Impl::listActionEntered( const String& i_comment )
- {
#if OSL_DEBUG_LEVEL > 0
- aContextAPIFlags.push( bAPIActionRunning );
+ // in a non-product build, assert if the current UndoManager at the shell is not the same we obtained
+ // (and cached) at construction time
+ SfxObjectShell* pObjectShell = rAntiImpl.getBaseModel().GetObjectShell();
+ OSL_ENSURE( ( pObjectShell != NULL ) && ( pUndoManager == pObjectShell->GetUndoManager() ),
+ "DocumentUndoManager_Impl::getImplUndoManager: the UndoManager changed meanwhile - what about our listener?" );
#endif
- if ( bAPIActionRunning )
- return;
-
- rAntiImpl.impl_notify( i_comment, &XUndoManagerListener::enteredContext );
+ return *pUndoManager;
}
- //------------------------------------------------------------------------------------------------------------------
- void DocumentUndoManager_Impl::listActionLeft()
+ //------------------------------------------------------------------------------------------------------------------
+ Reference< XUndoManager > DocumentUndoManager_Impl::getThis()
{
-#if OSL_DEBUG_LEVEL > 0
- const bool bCurrentContextIsAPIContext = aContextAPIFlags.top();
- aContextAPIFlags.pop();
- OSL_ENSURE( bCurrentContextIsAPIContext == bAPIActionRunning, "DocumentUndoManager_Impl::listActionLeft: API and non-API contexts interwoven!" );
-#endif
-
- if ( bAPIActionRunning )
- return;
-
- rAntiImpl.impl_notify( pUndoManager->GetUndoActionComment( 0, IUndoManager::CurrentLevel ), &XUndoManagerListener::leftContext );
+ return static_cast< XUndoManager* >( &rAntiImpl );
}
- //------------------------------------------------------------------------------------------------------------------
- void DocumentUndoManager_Impl::listActionLeftAndMerged()
+ //------------------------------------------------------------------------------------------------------------------
+ void DocumentUndoManager_Impl::invalidateXDo_nolck()
{
-#if OSL_DEBUG_LEVEL > 0
- const bool bCurrentContextIsAPIContext = aContextAPIFlags.top();
- aContextAPIFlags.pop();
- OSL_ENSURE( bCurrentContextIsAPIContext == bAPIActionRunning, "DocumentUndoManager_Impl::listActionLeftAndMerged: API and non-API contexts interwoven!" );
-#endif
-
- if ( bAPIActionRunning )
- return;
+ SfxModelGuard aGuard( rAntiImpl );
- rAntiImpl.impl_notify( ::rtl::OUString(), &XUndoManagerListener::leftHiddenContext );
+ const SfxObjectShell* pDocShell = getObjectShell();
+ ENSURE_OR_THROW( pDocShell != NULL, "lcl_invalidateUndo: no access to the doc shell!" );
+ SfxViewFrame* pViewFrame = SfxViewFrame::GetFirst( pDocShell );
+ while ( pViewFrame )
+ {
+ pViewFrame->GetBindings().Invalidate( SID_UNDO );
+ pViewFrame->GetBindings().Invalidate( SID_REDO );
+ pViewFrame = SfxViewFrame::GetNext( *pViewFrame, pDocShell );
+ }
}
- //------------------------------------------------------------------------------------------------------------------
- void DocumentUndoManager_Impl::listActionCancelled()
+ //------------------------------------------------------------------------------------------------------------------
+ void DocumentUndoManager_Impl::enterViewStandardMode()
{
-#if OSL_DEBUG_LEVEL > 0
- const bool bCurrentContextIsAPIContext = aContextAPIFlags.top();
- aContextAPIFlags.pop();
- OSL_ENSURE( bCurrentContextIsAPIContext == bAPIActionRunning, "DocumentUndoManager_Impl::listActionCancelled: API and non-API contexts interwoven!" );
-#endif
-
- if ( bAPIActionRunning )
- return;
-
- rAntiImpl.impl_notify( ::rtl::OUString(), &XUndoManagerListener::cancelledContext );
+ // TODO: not sure this is a good idea: This might add another action to the Undo/Redo stack, which
+ // will render the current call somewhat meaningless - finally, the caller can't be sure that really the action
+ // is undone/redone which s/he intended to.
+ SfxObjectShell* pDocShell = getObjectShell();
+ ENSURE_OR_RETURN_VOID( pDocShell, "DocumentUndoManager_Impl::enterViewStandardMode: do doc shell!" );
+ SfxViewFrame* pViewFrame = SfxViewFrame::GetFirst( pDocShell );
+ while ( pViewFrame )
+ {
+ SfxViewShell* pViewShell = pViewFrame->GetViewShell();
+ ENSURE_OR_CONTINUE( pViewShell, "DocumentUndoManager_Impl::enterViewStandardMode: no view shell in the frame!" );
+ pViewShell->EnterStandardMode();
+ pViewFrame = SfxViewFrame::GetNext( *pViewFrame, pDocShell );
+ }
}
- //------------------------------------------------------------------------------------------------------------------
- void DocumentUndoManager_Impl::undoManagerDying()
+ //==================================================================================================================
+ //= SfxModelGuardFacade
+ //==================================================================================================================
+ class SfxModelGuardFacade : public ::framework::IClearableInstanceLock
{
- pUndoManager = NULL;
- }
+ public:
+ SfxModelGuardFacade( SfxModelGuard& i_guard )
+ :m_guard( i_guard )
+ {
+ }
+
+ virtual void clear()
+ {
+ m_guard.clear();
+ }
+
+ private:
+ SfxModelGuard& m_guard;
+ };
//==================================================================================================================
//= DocumentUndoManager
@@ -404,10 +230,6 @@ namespace sfx2
//------------------------------------------------------------------------------------------------------------------
void DocumentUndoManager::disposing()
{
- EventObject aEvent;
- aEvent.Source = static_cast< XUndoManager* >( this );
- m_pImpl->aUndoListeners.disposeAndClear( aEvent );
-
m_pImpl->disposing();
}
@@ -424,66 +246,20 @@ namespace sfx2
}
//------------------------------------------------------------------------------------------------------------------
- void DocumentUndoManager::impl_notify( ::rtl::OUString const& i_title, void ( SAL_CALL XUndoManagerListener::*i_notificationMethod )( const UndoManagerEvent& ),
- SfxModelGuard& i_instanceLock )
- {
- UndoManagerEvent aEvent;
- aEvent.Source = static_cast< XUndoManager* >( this );
- aEvent.UndoActionTitle = i_title;
- aEvent.UndoContextDepth = m_pImpl->getUndoManager().GetListActionDepth();
-
- i_instanceLock.clear();
- m_pImpl->aUndoListeners.notifyEach( i_notificationMethod, aEvent );
- }
-
- //------------------------------------------------------------------------------------------------------------------
- void DocumentUndoManager::impl_notify( void ( SAL_CALL XUndoManagerListener::*i_notificationMethod )( const EventObject& ),
- SfxModelGuard& i_instanceLock )
- {
- EventObject aEvent;
- aEvent.Source = static_cast< XUndoManager* >( this );
- i_instanceLock.clear();
- m_pImpl->aUndoListeners.notifyEach( i_notificationMethod, aEvent );
- }
-
- //------------------------------------------------------------------------------------------------------------------
- void DocumentUndoManager::impl_notify( ::rtl::OUString const& i_title, void ( SAL_CALL XUndoManagerListener::*i_notificationMethod )( const UndoManagerEvent& ) )
- {
- UndoManagerEvent aEvent;
- aEvent.Source = static_cast< XUndoManager* >( this );
- aEvent.UndoActionTitle = i_title;
- aEvent.UndoContextDepth = m_pImpl->getUndoManager().GetListActionDepth();
-
- // TODO: this notification method here is used by DocumentUndoManager_Impl, to multiplex the notifications we
- // receive from the IUndoManager. Those notitications are sent with a locked SolarMutex, which means
- // we're doing the multiplexing here with a locked SM, too. Which is Bad (TM).
- // Fixing this properly would require outsourcing all the notifications into an own thread - which might lead
- // to problems of its own, since clients might expect synchronous notifications.
-
- m_pImpl->aUndoListeners.notifyEach( i_notificationMethod, aEvent );
- }
-
- //------------------------------------------------------------------------------------------------------------------
- void DocumentUndoManager::impl_notify( void ( SAL_CALL XUndoManagerListener::*i_notificationMethod )( const EventObject& ) )
- {
- EventObject aEvent;
- aEvent.Source = static_cast< XUndoManager* >( this );
-
- // TODO: the same comment as in the other impl_notify, regarding SM locking applies here ...
-
- m_pImpl->aUndoListeners.notifyEach( i_notificationMethod, aEvent );
- }
-
- //------------------------------------------------------------------------------------------------------------------
void SAL_CALL DocumentUndoManager::enterUndoContext( const ::rtl::OUString& i_title ) throw (RuntimeException)
{
- m_pImpl->enterUndoContext( i_title, false );
+ SfxModelGuard aGuard( *this );
+ m_pImpl->aUndoHelper.enterUndoContext( i_title, SfxModelGuardFacade( aGuard ) );
}
//------------------------------------------------------------------------------------------------------------------
void SAL_CALL DocumentUndoManager::enterHiddenUndoContext( ) throw (EmptyUndoStackException, RuntimeException)
{
- m_pImpl->enterUndoContext( ::rtl::OUString(), true );
+ // SYNCHRONIZED --->
+ SfxModelGuard aGuard( *this );
+ m_pImpl->aUndoHelper.enterHiddenUndoContext( SfxModelGuardFacade( aGuard ) );
+ // <--- SYNCHRONIZED
+ m_pImpl->invalidateXDo_nolck();
}
//------------------------------------------------------------------------------------------------------------------
@@ -491,38 +267,9 @@ namespace sfx2
{
// SYNCHRONIZED --->
SfxModelGuard aGuard( *this );
-
- IUndoManager& rUndoManager = m_pImpl->getUndoManager();
- if ( !rUndoManager.IsUndoEnabled() )
- // ignore this request if the manager is locked
- return;
-
- if ( !rUndoManager.IsInListAction() )
- throw InvalidStateException(
- ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "no active undo context" ) ),
- static_cast< XUndoManager* >( this )
- );
-
- USHORT nContextElements = 0;
- bool isHiddenContext = false;
- {
- ::comphelper::FlagGuard aNotificationGuard( m_pImpl->bAPIActionRunning );
-
- isHiddenContext = m_pImpl->aContextVisibilities.top();
- m_pImpl->aContextVisibilities.pop();
- if ( isHiddenContext )
- nContextElements = rUndoManager.LeaveAndMergeListAction();
- else
- nContextElements = rUndoManager.LeaveListAction();
- }
-
- if ( nContextElements == 0 )
- impl_notify( ::rtl::OUString(), &XUndoManagerListener::cancelledContext, aGuard );
- else if ( isHiddenContext )
- impl_notify( ::rtl::OUString(), &XUndoManagerListener::leftHiddenContext, aGuard );
- else
- impl_notify( rUndoManager.GetUndoActionComment( 0, IUndoManager::CurrentLevel ), &XUndoManagerListener::leftContext, aGuard );
+ m_pImpl->aUndoHelper.leaveUndoContext( SfxModelGuardFacade( aGuard ) );
// <--- SYNCHRONIZED
+ m_pImpl->invalidateXDo_nolck();
}
//------------------------------------------------------------------------------------------------------------------
@@ -530,207 +277,73 @@ namespace sfx2
{
// SYNCHRONIZED --->
SfxModelGuard aGuard( *this );
-
- if ( !i_action.is() )
- throw IllegalArgumentException(
- ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "illegal undo action object" ) ),
- static_cast< XUndoManager* >( this ),
- 1
- );
-
- IUndoManager& rUndoManager = m_pImpl->getUndoManager();
- if ( !rUndoManager.IsUndoEnabled() )
- // ignore the request if the manager is locked
- return;
-
- const bool bHadRedoActions = ( rUndoManager.GetRedoActionCount( IUndoManager::CurrentLevel ) > 0 );
- {
- ::comphelper::FlagGuard aNotificationGuard( m_pImpl->bAPIActionRunning );
- rUndoManager.AddUndoAction( new UndoActionWrapper( i_action ) );
- }
- const bool bHasRedoActions = ( rUndoManager.GetRedoActionCount( IUndoManager::CurrentLevel ) > 0 );
-
- lcl_invalidateXDo( *m_pImpl );
- impl_notify( i_action->getTitle(), &XUndoManagerListener::undoActionAdded, aGuard );
+ m_pImpl->aUndoHelper.addUndoAction( i_action, SfxModelGuardFacade( aGuard ) );
// <--- SYNCHRONIZED
-
- if ( bHadRedoActions && !bHasRedoActions )
- impl_notify( &XUndoManagerListener::redoActionsCleared );
+ m_pImpl->invalidateXDo_nolck();
}
//------------------------------------------------------------------------------------------------------------------
- void DocumentUndoManager::impl_do_nolck(
- USHORT ( IUndoManager::*i_checkMethod )( bool const ) const, BOOL ( IUndoManager::*i_doMethod )(),
- String ( IUndoManager::*i_titleRetriever )( USHORT, bool const ) const,
- void ( SAL_CALL XUndoManagerListener::*i_notificationMethod )( const UndoManagerEvent& ) )
+ void SAL_CALL DocumentUndoManager::undo( ) throw (EmptyUndoStackException, UndoContextNotClosedException, UndoFailedException, RuntimeException)
{
// SYNCHRONIZED --->
SfxModelGuard aGuard( *this );
-
- IUndoManager& rUndoManager = m_pImpl->getUndoManager();
- if ( rUndoManager.IsInListAction() )
- throw UndoContextNotClosedException( ::rtl::OUString(), static_cast< XUndoManager* >( this ) );
-
- if ( (rUndoManager.*i_checkMethod)( IUndoManager::TopLevel ) == 0 )
- throw EmptyUndoStackException( ::rtl::OUString::createFromAscii( "stack is empty" ), static_cast< XUndoManager* >( this ) );
-
- // let all views enter the standard mode
- // TODO: not sure this is a good idea: This might add another action to the Undo/Redo stack, which
- // will render the call somewhat meaningless - finally, the caller can't be sure that really the action
- // is undone/redone which s/he intended to.
- SfxObjectShell* pDocShell = m_pImpl->getObjectShell();
- OSL_ENSURE( pDocShell, "DocumentUndoManager::impl_do_nolck: do doc shell!" );
- if ( pDocShell )
- {
- SfxViewFrame* pViewFrame = SfxViewFrame::GetFirst( pDocShell );
- while ( pViewFrame )
- {
- SfxViewShell* pViewShell = pViewFrame->GetViewShell();
- ENSURE_OR_CONTINUE( pViewShell, "DocumentUndoManager::impl_do_nolck: no view shell in the frame!" );
- pViewShell->EnterStandardMode();
- pViewFrame = SfxViewFrame::GetNext( *pViewFrame, pDocShell );
- }
- }
-
- const ::rtl::OUString sUndoActionTitle = (rUndoManager.*i_titleRetriever)( 0, IUndoManager::TopLevel );
- {
- ::comphelper::FlagGuard aNotificationGuard( m_pImpl->bAPIActionRunning );
- try
- {
- (rUndoManager.*i_doMethod)();
- }
- catch( const RuntimeException& ) { /* allowed to leave here */ throw; }
- catch( const UndoFailedException& ) { /* allowed to leave here */ throw; }
- catch( const Exception& )
- {
- // not allowed to leave
- const Any aError( ::cppu::getCaughtException() );
- throw UndoFailedException( ::rtl::OUString(), static_cast< XUndoManager* >( this ), aError );
- }
- }
-
- impl_notify( sUndoActionTitle, i_notificationMethod, aGuard );
+ m_pImpl->enterViewStandardMode();
+ m_pImpl->aUndoHelper.undo( SfxModelGuardFacade( aGuard ) );
// <--- SYNCHRONIZED
- }
-
- //------------------------------------------------------------------------------------------------------------------
- void SAL_CALL DocumentUndoManager::undo( ) throw (EmptyUndoStackException, UndoContextNotClosedException, UndoFailedException, RuntimeException)
- {
- impl_do_nolck(
- &IUndoManager::GetUndoActionCount,
- &IUndoManager::Undo,
- &IUndoManager::GetUndoActionComment,
- &XUndoManagerListener::actionUndone
- );
+ m_pImpl->invalidateXDo_nolck();
}
//------------------------------------------------------------------------------------------------------------------
void SAL_CALL DocumentUndoManager::redo( ) throw (EmptyUndoStackException, UndoContextNotClosedException, UndoFailedException, RuntimeException)
{
- impl_do_nolck(
- &IUndoManager::GetRedoActionCount,
- &IUndoManager::Redo,
- &IUndoManager::GetRedoActionComment,
- &XUndoManagerListener::actionRedone
- );
- }
-
- //------------------------------------------------------------------------------------------------------------------
- ::sal_Bool SAL_CALL DocumentUndoManager::isUndoPossible( ) throw (RuntimeException)
- {
// SYNCHRONIZED --->
SfxModelGuard aGuard( *this );
-
- IUndoManager& rUndoManager = m_pImpl->getUndoManager();
- if ( rUndoManager.IsInListAction() )
- return sal_False;
- return rUndoManager.GetUndoActionCount( IUndoManager::TopLevel ) > 0;
+ m_pImpl->enterViewStandardMode();
+ m_pImpl->aUndoHelper.redo( SfxModelGuardFacade( aGuard ) );
// <--- SYNCHRONIZED
+ m_pImpl->invalidateXDo_nolck();
}
//------------------------------------------------------------------------------------------------------------------
- ::sal_Bool SAL_CALL DocumentUndoManager::isRedoPossible( ) throw (RuntimeException)
+ ::sal_Bool SAL_CALL DocumentUndoManager::isUndoPossible( ) throw (RuntimeException)
{
- // SYNCHRONIZED --->
SfxModelGuard aGuard( *this );
-
- IUndoManager& rUndoManager = m_pImpl->getUndoManager();
- if ( rUndoManager.IsInListAction() )
- return sal_False;
- return rUndoManager.GetRedoActionCount( IUndoManager::TopLevel ) > 0;
- // <--- SYNCHRONIZED
+ return m_pImpl->aUndoHelper.isUndoPossible();
}
//------------------------------------------------------------------------------------------------------------------
- namespace
+ ::sal_Bool SAL_CALL DocumentUndoManager::isRedoPossible( ) throw (RuntimeException)
{
- //..............................................................................................................
- ::rtl::OUString lcl_getCurrentActionTitle( DocumentUndoManager_Impl& i_impl, const bool i_undo )
- {
- // SYNCHRONIZED --->
- SfxModelGuard aGuard( i_impl.rAntiImpl );
-
- const IUndoManager& rUndoManager = i_impl.getUndoManager();
- const USHORT nActionCount = i_undo
- ? rUndoManager.GetUndoActionCount( IUndoManager::TopLevel )
- : rUndoManager.GetRedoActionCount( IUndoManager::TopLevel );
- if ( nActionCount == 0 )
- throw EmptyUndoStackException(
- i_undo ? ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "no action on the undo stack" ) )
- : ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "no action on the redo stack" ) ),
- static_cast< XUndoManager* >( &i_impl.rAntiImpl )
- );
- return i_undo
- ? rUndoManager.GetUndoActionComment( 0, IUndoManager::TopLevel )
- : rUndoManager.GetRedoActionComment( 0, IUndoManager::TopLevel );
- // <--- SYNCHRONIZED
- }
-
- //..............................................................................................................
- Sequence< ::rtl::OUString > lcl_getAllActionTitles( DocumentUndoManager_Impl& i_impl, const bool i_undo )
- {
- // SYNCHRONIZED --->
- SfxModelGuard aGuard( i_impl.rAntiImpl );
-
- const IUndoManager& rUndoManager = i_impl.getUndoManager();
- const sal_Int32 nCount = i_undo
- ? rUndoManager.GetUndoActionCount( IUndoManager::TopLevel )
- : rUndoManager.GetRedoActionCount( IUndoManager::TopLevel );
-
- Sequence< ::rtl::OUString > aTitles( nCount );
- for ( sal_Int32 i=0; i<nCount; ++i )
- {
- aTitles[i] = i_undo
- ? rUndoManager.GetUndoActionComment( i, IUndoManager::TopLevel )
- : rUndoManager.GetRedoActionComment( i, IUndoManager::TopLevel );
- }
- return aTitles;
- // <--- SYNCHRONIZED
- }
+ SfxModelGuard aGuard( *this );
+ return m_pImpl->aUndoHelper.isRedoPossible();
}
//------------------------------------------------------------------------------------------------------------------
::rtl::OUString SAL_CALL DocumentUndoManager::getCurrentUndoActionTitle( ) throw (EmptyUndoStackException, RuntimeException)
{
- return lcl_getCurrentActionTitle( *m_pImpl, true );
+ SfxModelGuard aGuard( *this );
+ return m_pImpl->aUndoHelper.getCurrentUndoActionTitle();
}
//------------------------------------------------------------------------------------------------------------------
::rtl::OUString SAL_CALL DocumentUndoManager::getCurrentRedoActionTitle( ) throw (EmptyUndoStackException, RuntimeException)
{
- return lcl_getCurrentActionTitle( *m_pImpl, false );
+ SfxModelGuard aGuard( *this );
+ return m_pImpl->aUndoHelper.getCurrentRedoActionTitle();
}
//------------------------------------------------------------------------------------------------------------------
Sequence< ::rtl::OUString > SAL_CALL DocumentUndoManager::getAllUndoActionTitles( ) throw (RuntimeException)
{
- return lcl_getAllActionTitles( *m_pImpl, true );
+ SfxModelGuard aGuard( *this );
+ return m_pImpl->aUndoHelper.getAllUndoActionTitles();
}
//------------------------------------------------------------------------------------------------------------------
Sequence< ::rtl::OUString > SAL_CALL DocumentUndoManager::getAllRedoActionTitles( ) throw (RuntimeException)
{
- return lcl_getAllActionTitles( *m_pImpl, false );
+ SfxModelGuard aGuard( *this );
+ return m_pImpl->aUndoHelper.getAllRedoActionTitles();
}
//------------------------------------------------------------------------------------------------------------------
@@ -738,17 +351,9 @@ namespace sfx2
{
// SYNCHRONIZED --->
SfxModelGuard aGuard( *this );
-
- IUndoManager& rUndoManager = m_pImpl->getUndoManager();
- if ( rUndoManager.IsInListAction() )
- throw UndoContextNotClosedException( ::rtl::OUString(), static_cast< XUndoManager* >( this ) );
-
- {
- ::comphelper::FlagGuard aNotificationGuard( m_pImpl->bAPIActionRunning );
- rUndoManager.Clear();
- }
- impl_notify( &XUndoManagerListener::allActionsCleared, aGuard );
+ m_pImpl->aUndoHelper.clear( SfxModelGuardFacade( aGuard ) );
// <--- SYNCHRONIZED
+ m_pImpl->invalidateXDo_nolck();
}
//------------------------------------------------------------------------------------------------------------------
@@ -756,17 +361,9 @@ namespace sfx2
{
// SYNCHRONIZED --->
SfxModelGuard aGuard( *this );
-
- IUndoManager& rUndoManager = m_pImpl->getUndoManager();
- if ( rUndoManager.IsInListAction() )
- throw UndoContextNotClosedException( ::rtl::OUString(), static_cast< XUndoManager* >( this ) );
-
- {
- ::comphelper::FlagGuard aNotificationGuard( m_pImpl->bAPIActionRunning );
- rUndoManager.ClearRedo();
- }
- impl_notify( &XUndoManagerListener::redoActionsCleared, aGuard );
+ m_pImpl->aUndoHelper.clearRedo( SfxModelGuardFacade( aGuard ) );
// <--- SYNCHRONIZED
+ m_pImpl->invalidateXDo_nolck();
}
//------------------------------------------------------------------------------------------------------------------
@@ -774,72 +371,44 @@ namespace sfx2
{
// SYNCHRONIZED --->
SfxModelGuard aGuard( *this );
-
- IUndoManager& rUndoManager = m_pImpl->getUndoManager();
- {
- ::comphelper::FlagGuard aNotificationGuard( m_pImpl->bAPIActionRunning );
- while ( rUndoManager.IsInListAction() )
- rUndoManager.LeaveListAction();
- rUndoManager.Clear();
- }
-
- impl_notify( &XUndoManagerListener::resetAll, aGuard );
+ m_pImpl->aUndoHelper.reset( SfxModelGuardFacade( aGuard ) );
// <--- SYNCHRONIZED
+ m_pImpl->invalidateXDo_nolck();
}
//------------------------------------------------------------------------------------------------------------------
void SAL_CALL DocumentUndoManager::lock( ) throw (RuntimeException)
{
- // SYNCHRONIZED --->
SfxModelGuard aGuard( *this );
-
- IUndoManager& rUndoManager = m_pImpl->getUndoManager();
- rUndoManager.EnableUndo( false );
- // <--- SYNCHRONIZED
+ m_pImpl->aUndoHelper.lock();
}
//------------------------------------------------------------------------------------------------------------------
void SAL_CALL DocumentUndoManager::unlock( ) throw (RuntimeException, NotLockedException)
{
- // SYNCHRONIZED --->
SfxModelGuard aGuard( *this );
-
- IUndoManager& rUndoManager = m_pImpl->getUndoManager();
- if ( rUndoManager.IsUndoEnabled() )
- throw NotLockedException( ::rtl::OUString::createFromAscii( "Undo manager is not locked" ), static_cast< XUndoManager* >( this ) );
- rUndoManager.EnableUndo( true );
- // <--- SYNCHRONIZED
+ m_pImpl->aUndoHelper.unlock();
}
//------------------------------------------------------------------------------------------------------------------
::sal_Bool SAL_CALL DocumentUndoManager::isLocked( ) throw (RuntimeException)
{
- // SYNCHRONIZED --->
SfxModelGuard aGuard( *this );
-
- IUndoManager& rUndoManager = m_pImpl->getUndoManager();
- return !rUndoManager.IsUndoEnabled();
- // <--- SYNCHRONIZED
+ return m_pImpl->aUndoHelper.isLocked();
}
//------------------------------------------------------------------------------------------------------------------
void SAL_CALL DocumentUndoManager::addUndoManagerListener( const Reference< XUndoManagerListener >& i_listener ) throw (RuntimeException)
{
- // SYNCHRONIZED --->
SfxModelGuard aGuard( *this );
- if ( i_listener.is() )
- m_pImpl->aUndoListeners.addInterface( i_listener );
- // <--- SYNCHRONIZED
+ return m_pImpl->aUndoHelper.addUndoManagerListener( i_listener );
}
//------------------------------------------------------------------------------------------------------------------
void SAL_CALL DocumentUndoManager::removeUndoManagerListener( const Reference< XUndoManagerListener >& i_listener ) throw (RuntimeException)
{
- // SYNCHRONIZED --->
SfxModelGuard aGuard( *this );
- if ( i_listener.is() )
- m_pImpl->aUndoListeners.removeInterface( i_listener );
- // <--- SYNCHRONIZED
+ return m_pImpl->aUndoHelper.removeUndoManagerListener( i_listener );
}
//......................................................................................................................