summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xframework/inc/framework/iguard.hxx69
-rwxr-xr-xframework/inc/helper/undomanagerhelper.hxx85
-rw-r--r--framework/prj/d.lst1
-rwxr-xr-xframework/source/helper/undomanagerhelper.cxx828
-rw-r--r--framework/util/makefile.mk1
-rw-r--r--sfx2/inc/sfx2/sfxbasemodel.hxx7
-rwxr-xr-xsfx2/qa/complex/sfx2/UndoManager.java3
-rwxr-xr-xsfx2/source/doc/docundomanager.cxx121
8 files changed, 798 insertions, 317 deletions
diff --git a/framework/inc/framework/iguard.hxx b/framework/inc/framework/iguard.hxx
new file mode 100755
index 000000000000..7c00858b208d
--- /dev/null
+++ b/framework/inc/framework/iguard.hxx
@@ -0,0 +1,69 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef __FRAMEWORK_THREADHELP_IGUARD_H_
+#define __FRAMEWORK_THREADHELP_IGUARD_H_
+
+//_________________________________________________________________________________________________________________
+// includes
+//_________________________________________________________________________________________________________________
+
+#include <sal/types.h>
+
+//_________________________________________________________________________________________________________________
+// namespace
+//_________________________________________________________________________________________________________________
+
+namespace framework{
+
+//_________________________________________________________________________________________________________________
+// declarations
+//_________________________________________________________________________________________________________________
+
+/*-************************************************************************************************************//**
+ @descr interface for guarding a lock
+*//*-*************************************************************************************************************/
+class SAL_NO_VTABLE IGuard
+{
+ //-------------------------------------------------------------------------------------------------------------
+ // public methods
+ //-------------------------------------------------------------------------------------------------------------
+ public:
+
+ /** clears the lock. If the guard does not currently hold the lock, nothing happens.
+ */
+ virtual void clear() = 0;
+
+ /** attempts to re-establishes the lock, blocking until the attempt is successful.
+ */
+ virtual void reset() = 0;
+
+}; // class IGuard
+
+} // namespace framework
+
+#endif // #ifndef __FRAMEWORK_THREADHELP_IGUARD_H_
diff --git a/framework/inc/helper/undomanagerhelper.hxx b/framework/inc/helper/undomanagerhelper.hxx
index 98503e08144f..462aaa740af3 100755
--- a/framework/inc/helper/undomanagerhelper.hxx
+++ b/framework/inc/helper/undomanagerhelper.hxx
@@ -27,16 +27,14 @@
#ifndef FRAMEWORK_UNDOMANAGERHELPER_HXX
#define FRAMEWORK_UNDOMANAGERHELPER_HXX
+#include "framework/iguard.hxx"
+#include "framework/imutex.hxx"
+
/** === begin UNO includes === **/
#include <com/sun/star/document/XUndoManager.hpp>
/** === end UNO includes === **/
-#include <boost/scoped_ptr.hpp>
-
-namespace osl
-{
- class Mutex;
-}
+#include <rtl/ref.hxx>
namespace svl
{
@@ -49,17 +47,24 @@ namespace framework
//......................................................................................................................
//==================================================================================================================
- //= IUndoManagerImplementation
+ //= IMutexGuard
//==================================================================================================================
- class SAL_NO_VTABLE IUndoManagerImplementation
+ class SAL_NO_VTABLE IMutexGuard : public IGuard
{
public:
- /** returns the mutex which is protecting the instance. Needed for listener administration synchronization.
+ /** returns the mutex guarded by the instance.
- Note that the mutex will <em>not</em> be used for multi-threading safety of the UndoManagerHelper.
+ Even if the guard currently has not a lock on the mutex, this method must succeed.
*/
- virtual ::osl::Mutex& getMutex() = 0;
+ virtual IMutex& getGuardedMutex() = 0;
+ };
+ //==================================================================================================================
+ //= IUndoManagerImplementation
+ //==================================================================================================================
+ class SAL_NO_VTABLE IUndoManagerImplementation
+ {
+ public:
/** returns the IUndoManager interface to the actual Undo stack
@throws com::sun::star::lang::DisposedException
@@ -77,29 +82,31 @@ namespace framework
};
//==================================================================================================================
- //= IClearableInstanceLock
- //==================================================================================================================
- /** helper class for releasing a lock
-
- Since clients of UndoManagerHelper are responsible for locking their instance, but the UndoManagerHelper
- needs to notify its listeners, and this needs to happen without any instance lock, all affected methods
- take an IClearableInstanceLock parameter, to be able to clear the owner's lock before doing any notifications.
- */
- class SAL_NO_VTABLE IClearableInstanceLock
- {
- public:
- virtual void clear() = 0;
- };
-
- //==================================================================================================================
//= UndoManagerHelper
//==================================================================================================================
class UndoManagerHelper_Impl;
/** helper class for implementing an XUndoManager
- The class defines the same methods as an XUndoManager does, but lacks certain aspects of a full-blown UNO
- component. In particular, it is the responsibility of the owner of the instance to care for multi-threading
- safety, and for disposal checks.
+ Several of the methods of the class take an IMutexGuard instance. It is assumed that this guard has a lock on
+ its mutext at the moment the method is entered. The lock will be released before any notifications to the
+ registered XUndoManagerListeners happen.
+
+ The following locking strategy is used for this mutex:
+ <ul><li>Any notifications to the registered XUndoManagerListeners are after the guard has been cleared. i.e.
+ without the mutex being locked.</p>
+ <li>Any calls into the <code>IUndoManager</code> implementation is made without the mutex being locked.
+ Note that this implies that the <code>IUndoManager</code> implementation must be thread-safe in itself
+ (which is true for the default implementation, SfxUndoManager).</li>
+ <li>An exception to the previous item are the <member>IUndoManager::Undo</member> and
+ <member>IUndoManager::Redo</member> methods: They're called with the given external mutex being
+ locked.</li>
+ </ul>
+
+ The reason for the exception for IUndoManager::Undo and IUndoManager::Redo is that those are expected to
+ modify the actual document which the UndoManager works for. And as long as our documents are not thread-safe,
+ and as long as we do not re-fit <strong>all</strong> existing SfxUndoImplementations to <em>not</em> expect
+ the dreaded SolarMutex being locked when they're called, the above behavior is a compromise between "how it should
+ be" and "how it can realistically be".
*/
class UndoManagerHelper
{
@@ -111,12 +118,12 @@ namespace framework
void disposing();
// XUndoManager equivalents
- void enterUndoContext( const ::rtl::OUString& i_title, IClearableInstanceLock& i_instanceLock );
- void enterHiddenUndoContext( IClearableInstanceLock& i_instanceLock );
- void leaveUndoContext( IClearableInstanceLock& i_instanceLock );
- void addUndoAction( const ::com::sun::star::uno::Reference< ::com::sun::star::document::XUndoAction >& i_action, IClearableInstanceLock& i_instanceLock );
- void undo( IClearableInstanceLock& i_instanceLock );
- void redo( IClearableInstanceLock& i_instanceLock );
+ void enterUndoContext( const ::rtl::OUString& i_title, IMutexGuard& i_instanceLock );
+ void enterHiddenUndoContext( IMutexGuard& i_instanceLock );
+ void leaveUndoContext( IMutexGuard& i_instanceLock );
+ void addUndoAction( const ::com::sun::star::uno::Reference< ::com::sun::star::document::XUndoAction >& i_action, IMutexGuard& i_instanceLock );
+ void undo( IMutexGuard& i_instanceLock );
+ void redo( IMutexGuard& i_instanceLock );
::sal_Bool isUndoPossible() const;
::sal_Bool isRedoPossible() const;
::rtl::OUString getCurrentUndoActionTitle() const;
@@ -125,9 +132,9 @@ namespace framework
getAllUndoActionTitles() const;
::com::sun::star::uno::Sequence< ::rtl::OUString >
getAllRedoActionTitles() const;
- void clear( IClearableInstanceLock& i_instanceLock );
- void clearRedo( IClearableInstanceLock& i_instanceLock );
- void reset( IClearableInstanceLock& i_instanceLock );
+ void clear( IMutexGuard& i_instanceLock );
+ void clearRedo( IMutexGuard& i_instanceLock );
+ void reset( IMutexGuard& i_instanceLock );
void addUndoManagerListener( const ::com::sun::star::uno::Reference< ::com::sun::star::document::XUndoManagerListener >& i_listener );
void removeUndoManagerListener( const ::com::sun::star::uno::Reference< ::com::sun::star::document::XUndoManagerListener >& i_listener );
@@ -137,7 +144,7 @@ namespace framework
::sal_Bool isLocked();
private:
- ::boost::scoped_ptr< UndoManagerHelper_Impl > m_pImpl;
+ ::rtl::Reference< UndoManagerHelper_Impl > m_pImpl;
};
//......................................................................................................................
diff --git a/framework/prj/d.lst b/framework/prj/d.lst
index b7d996eec53f..a3c3f382da1e 100644
--- a/framework/prj/d.lst
+++ b/framework/prj/d.lst
@@ -46,6 +46,7 @@ mkdir: %_DEST%\xml%_EXT%\uiconfig\modules\StartModule\statusbar
..\inc\helper\documentundoguard.hxx %_DEST%\inc%_EXT%\framework\documentundoguard.hxx
..\inc\helper\undomanagerhelper.hxx %_DEST%\inc%_EXT%\framework\undomanagerhelper.hxx
..\inc\framework\imutex.hxx %_DEST%\inc%_EXT%\framework\imutex.hxx
+..\inc\framework\iguard.hxx %_DEST%\inc%_EXT%\framework\iguard.hxx
..\uiconfig\startmodule\menubar\*.xml %_DEST%\xml%_EXT%\uiconfig\modules\StartModule\menubar\*.xml
..\uiconfig\startmodule\toolbar\*.xml %_DEST%\xml%_EXT%\uiconfig\modules\StartModule\toolbar\*.xml
diff --git a/framework/source/helper/undomanagerhelper.cxx b/framework/source/helper/undomanagerhelper.cxx
index f7f297f6cdee..81b1a30c289c 100755
--- a/framework/source/helper/undomanagerhelper.cxx
+++ b/framework/source/helper/undomanagerhelper.cxx
@@ -33,11 +33,15 @@
/** === end UNO includes === **/
#include <cppuhelper/interfacecontainer.hxx>
+#include <cppuhelper/exc_hlp.hxx>
#include <comphelper/flagguard.hxx>
+#include <comphelper/asyncnotification.hxx>
#include <svl/undo.hxx>
#include <tools/diagnose_ex.h>
+#include <osl/conditn.hxx>
#include <stack>
+#include <boost/function.hpp>
//......................................................................................................................
namespace framework
@@ -148,55 +152,108 @@ namespace framework
}
//==================================================================================================================
- //= UndoManagerHelper_Impl
+ //= UndoManagerRequest
//==================================================================================================================
- class UndoManagerHelper_Impl : public SfxUndoListener
+ class UndoManagerRequest : public ::comphelper::AnyEvent
{
public:
- ::cppu::OInterfaceContainerHelper aUndoListeners;
- IUndoManagerImplementation& rUndoManagerImplementation;
- UndoManagerHelper& rAntiImpl;
- bool bAPIActionRunning;
- ::std::stack< bool > aContextVisibilities;
-#if OSL_DEBUG_LEVEL > 0
- ::std::stack< bool > aContextAPIFlags;
-#endif
+ UndoManagerRequest( ::boost::function0< void > const& i_request )
+ :m_request( i_request )
+ ,m_caughtException()
+ ,m_finishCondition()
+ {
+ m_finishCondition.reset();
+ }
- UndoManagerHelper_Impl( UndoManagerHelper& i_antiImpl, IUndoManagerImplementation& i_undoManagerImpl )
- :aUndoListeners( i_undoManagerImpl.getMutex() )
- ,rUndoManagerImplementation( i_undoManagerImpl )
- ,rAntiImpl( i_antiImpl )
- ,bAPIActionRunning( false )
+ void execute()
{
- getUndoManager().AddUndoListener( *this );
+ try
+ {
+ m_request();
+ }
+ catch( const Exception& )
+ {
+ m_caughtException = ::cppu::getCaughtException();
+ }
+ m_finishCondition.set();
}
- virtual ~UndoManagerHelper_Impl()
+ void wait()
{
+ m_finishCondition.wait();
+ if ( m_caughtException.hasValue() )
+ ::cppu::throwException( m_caughtException );
}
- //..............................................................................................................
- IUndoManager& getUndoManager()
+ protected:
+ ~UndoManagerRequest()
{
- return rUndoManagerImplementation.getImplUndoManager();
}
- //..............................................................................................................
- Reference< XUndoManager > getXUndoManager()
+ private:
+ ::boost::function0< void > m_request;
+ Any m_caughtException;
+ ::osl::Condition m_finishCondition;
+ };
+
+ //------------------------------------------------------------------------------------------------------------------
+
+ //==================================================================================================================
+ //= UndoManagerHelper_Impl
+ //==================================================================================================================
+ class UndoManagerHelper_Impl :public SfxUndoListener
+ ,public ::comphelper::IEventProcessor
+ {
+ private:
+ ::osl::Mutex m_aMutex;
+ oslInterlockedCount m_refCount;
+ ::rtl::Reference< ::comphelper::AsyncEventNotifier >
+ m_pRequestProcessor;
+ bool m_disposed;
+ bool m_bAPIActionRunning;
+ ::cppu::OInterfaceContainerHelper m_aUndoListeners;
+ IUndoManagerImplementation& m_rUndoManagerImplementation;
+ UndoManagerHelper& m_rAntiImpl;
+ ::std::stack< bool > m_aContextVisibilities;
+#if OSL_DEBUG_LEVEL > 0
+ ::std::stack< bool > m_aContextAPIFlags;
+#endif
+
+ public:
+ ::osl::Mutex& getMutex() { return m_aMutex; }
+
+ public:
+ UndoManagerHelper_Impl( UndoManagerHelper& i_antiImpl, IUndoManagerImplementation& i_undoManagerImpl )
+ :m_aMutex()
+ ,m_refCount( 0 )
+ ,m_pRequestProcessor()
+ ,m_disposed( false )
+ ,m_bAPIActionRunning( false )
+ ,m_aUndoListeners( m_aMutex )
+ ,m_rUndoManagerImplementation( i_undoManagerImpl )
+ ,m_rAntiImpl( i_antiImpl )
{
- return rUndoManagerImplementation.getThis();
+ getUndoManager().AddUndoListener( *this );
}
//..............................................................................................................
- void disposing()
+ IUndoManager& getUndoManager() const
{
- EventObject aEvent;
- aEvent.Source = getXUndoManager();
- aUndoListeners.disposeAndClear( aEvent );
+ return m_rUndoManagerImplementation.getImplUndoManager();
+ }
- getUndoManager().RemoveUndoListener( *this );
+ //..............................................................................................................
+ Reference< XUndoManager > getXUndoManager() const
+ {
+ return m_rUndoManagerImplementation.getThis();
}
+ //..............................................................................................................
+ // ::comphelper::IEventProcessor
+ virtual void SAL_CALL acquire();
+ virtual void SAL_CALL release();
+ virtual void processEvent( const ::comphelper::AnyEvent& _rEvent );
+
// SfxUndoListener
virtual void actionUndone( const String& i_actionComment );
virtual void actionRedone( const String& i_actionComment );
@@ -204,67 +261,114 @@ namespace framework
virtual void cleared();
virtual void clearedRedo();
virtual void listActionEntered( const String& i_comment );
- virtual void listActionLeft();
+ virtual void listActionLeft( const String& i_comment );
virtual void listActionLeftAndMerged();
virtual void listActionCancelled();
virtual void undoManagerDying();
// public operations
- void enterUndoContext( const ::rtl::OUString& i_title, const bool i_hidden, IClearableInstanceLock& i_instanceLock );
-
- void doUndoRedo(
- USHORT ( ::svl::IUndoManager::*i_checkMethod )( bool const ) const,
- BOOL ( ::svl::IUndoManager::*i_doMethod )(),
- UniString ( ::svl::IUndoManager::*i_titleRetriever )( USHORT, bool const ) const,
- void ( SAL_CALL ::com::sun::star::document::XUndoManagerListener::*i_notificationMethod )( const ::com::sun::star::document::UndoManagerEvent& ),
- IClearableInstanceLock& i_instanceLock
- );
- void notify( ::rtl::OUString const& i_title,
- void ( SAL_CALL XUndoManagerListener::*i_notificationMethod )( const UndoManagerEvent& ),
- IClearableInstanceLock& i_instanceLock
- );
- void notify( void ( SAL_CALL XUndoManagerListener::*i_notificationMethod )( const EventObject& ),
- IClearableInstanceLock& i_instanceLock
- );
+ void disposing();
+
+ void enterUndoContext( const ::rtl::OUString& i_title, const bool i_hidden, IMutexGuard& i_instanceLock );
+ void leaveUndoContext( IMutexGuard& i_instanceLock );
+ void addUndoAction( const Reference< XUndoAction >& i_action, IMutexGuard& i_instanceLock );
+ void undo( IMutexGuard& i_instanceLock );
+ void redo( IMutexGuard& i_instanceLock );
+ void clear( IMutexGuard& i_instanceLock );
+ void clearRedo( IMutexGuard& i_instanceLock );
+ void reset( IMutexGuard& i_instanceLock );
+
+ void addUndoManagerListener( const Reference< XUndoManagerListener >& i_listener )
+ {
+ m_aUndoListeners.addInterface( i_listener );
+ }
+
+ void removeUndoManagerListener( const Reference< XUndoManagerListener >& i_listener )
+ {
+ m_aUndoListeners.removeInterface( i_listener );
+ }
+
+ UndoManagerEvent
+ buildEvent( ::rtl::OUString const& i_title ) const;
+
void notify( ::rtl::OUString const& i_title,
void ( SAL_CALL XUndoManagerListener::*i_notificationMethod )( const UndoManagerEvent& )
);
- void notify(
- void ( SAL_CALL XUndoManagerListener::*i_notificationMethod )( const EventObject& )
- );
+ void notify( void ( SAL_CALL XUndoManagerListener::*i_notificationMethod )( const UndoManagerEvent& ) )
+ {
+ notify( ::rtl::OUString(), i_notificationMethod );
+ }
+
+ void notify( void ( SAL_CALL XUndoManagerListener::*i_notificationMethod )( const EventObject& ) );
+
+ private:
+ virtual ~UndoManagerHelper_Impl()
+ {
+ }
+
+ /// adds a function to be called to the request processor's queue
+ void impl_processRequest( ::boost::function0< void > const& i_request, IMutexGuard& i_instanceLock );
+
+ /// impl-versions of the XUndoManager API. Those methods are executed in the dedicated thread defined by m_pRequestProcessor
+ void impl_enterUndoContext( const ::rtl::OUString& i_title, const bool i_hidden );
+ void impl_leaveUndoContext();
+ void impl_addUndoAction( const Reference< XUndoAction >& i_action );
+ void impl_doUndoRedo( IMutexGuard& i_externalLock, const bool i_undo );
+ void impl_clear();
+ void impl_clearRedo();
+ void impl_reset();
};
//------------------------------------------------------------------------------------------------------------------
- void UndoManagerHelper_Impl::notify( ::rtl::OUString const& i_title, void ( SAL_CALL XUndoManagerListener::*i_notificationMethod )( const UndoManagerEvent& ),
- IClearableInstanceLock& i_instanceLock )
+ void UndoManagerHelper_Impl::acquire()
{
- UndoManagerEvent aEvent;
- aEvent.Source = getXUndoManager();
- aEvent.UndoActionTitle = i_title;
- aEvent.UndoContextDepth = getUndoManager().GetListActionDepth();
+ osl_incrementInterlockedCount( &m_refCount );
+ }
- i_instanceLock.clear();
- aUndoListeners.notifyEach( i_notificationMethod, aEvent );
+ //------------------------------------------------------------------------------------------------------------------
+ void UndoManagerHelper_Impl::release()
+ {
+ if ( 0 == osl_decrementInterlockedCount( &m_refCount ) )
+ delete this;
}
//------------------------------------------------------------------------------------------------------------------
- void UndoManagerHelper_Impl::notify( void ( SAL_CALL XUndoManagerListener::*i_notificationMethod )( const EventObject& ),
- IClearableInstanceLock& i_instanceLock )
+ void UndoManagerHelper_Impl::disposing()
{
EventObject aEvent;
aEvent.Source = getXUndoManager();
- i_instanceLock.clear();
- aUndoListeners.notifyEach( i_notificationMethod, aEvent );
+ m_aUndoListeners.disposeAndClear( aEvent );
+
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ getUndoManager().RemoveUndoListener( *this );
+
+ if ( m_pRequestProcessor.is() )
+ {
+ m_pRequestProcessor->removeEventsForProcessor( this );
+ m_pRequestProcessor->terminate();
+ m_pRequestProcessor->join();
+ m_pRequestProcessor.clear();
+ }
+
+ m_disposed = true;
}
//------------------------------------------------------------------------------------------------------------------
- void UndoManagerHelper_Impl::notify( ::rtl::OUString const& i_title,
- void ( SAL_CALL XUndoManagerListener::*i_notificationMethod )( const UndoManagerEvent& ) )
+ UndoManagerEvent UndoManagerHelper_Impl::buildEvent( ::rtl::OUString const& i_title ) const
{
UndoManagerEvent aEvent;
aEvent.Source = getXUndoManager();
aEvent.UndoActionTitle = i_title;
aEvent.UndoContextDepth = getUndoManager().GetListActionDepth();
+ return aEvent;
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void UndoManagerHelper_Impl::notify( ::rtl::OUString const& i_title,
+ void ( SAL_CALL XUndoManagerListener::*i_notificationMethod )( const UndoManagerEvent& ) )
+ {
+ const UndoManagerEvent aEvent( buildEvent( i_title ) );
// TODO: this notification method here is used by UndoManagerHelper_Impl, to multiplex the notifications we
// receive from the IUndoManager. Those notitications are sent with a locked SolarMutex, which means
@@ -272,24 +376,131 @@ namespace framework
// 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.
- aUndoListeners.notifyEach( i_notificationMethod, aEvent );
+ m_aUndoListeners.notifyEach( i_notificationMethod, aEvent );
}
//------------------------------------------------------------------------------------------------------------------
void UndoManagerHelper_Impl::notify( void ( SAL_CALL XUndoManagerListener::*i_notificationMethod )( const EventObject& ) )
{
- EventObject aEvent;
- aEvent.Source = getXUndoManager();
+ const EventObject aEvent( getXUndoManager() );
// TODO: the same comment as in the other notify, regarding SM locking applies here ...
- aUndoListeners.notifyEach( i_notificationMethod, aEvent );
+ m_aUndoListeners.notifyEach( i_notificationMethod, aEvent );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void UndoManagerHelper_Impl::enterUndoContext( const ::rtl::OUString& i_title, const bool i_hidden, IMutexGuard& i_instanceLock )
+ {
+ impl_processRequest(
+ ::boost::bind(
+ &UndoManagerHelper_Impl::impl_enterUndoContext,
+ this,
+ ::boost::cref( i_title ),
+ i_hidden
+ ),
+ i_instanceLock
+ );
}
//------------------------------------------------------------------------------------------------------------------
- void UndoManagerHelper_Impl::enterUndoContext( const ::rtl::OUString& i_title, const bool i_hidden, IClearableInstanceLock& i_instanceLock )
+ void UndoManagerHelper_Impl::leaveUndoContext( IMutexGuard& i_instanceLock )
+ {
+ impl_processRequest(
+ ::boost::bind(
+ &UndoManagerHelper_Impl::impl_leaveUndoContext,
+ this
+ ),
+ i_instanceLock
+ );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void UndoManagerHelper_Impl::addUndoAction( const Reference< XUndoAction >& i_action, IMutexGuard& i_instanceLock )
+ {
+ if ( !i_action.is() )
+ throw IllegalArgumentException(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "illegal undo action object" ) ),
+ getXUndoManager(),
+ 1
+ );
+
+ impl_processRequest(
+ ::boost::bind(
+ &UndoManagerHelper_Impl::impl_addUndoAction,
+ this,
+ ::boost::ref( i_action )
+ ),
+ i_instanceLock
+ );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void UndoManagerHelper_Impl::clear( IMutexGuard& i_instanceLock )
+ {
+ impl_processRequest(
+ ::boost::bind(
+ &UndoManagerHelper_Impl::impl_clear,
+ this
+ ),
+ i_instanceLock
+ );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void UndoManagerHelper_Impl::clearRedo( IMutexGuard& i_instanceLock )
+ {
+ impl_processRequest(
+ ::boost::bind(
+ &UndoManagerHelper_Impl::impl_clearRedo,
+ this
+ ),
+ i_instanceLock
+ );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void UndoManagerHelper_Impl::reset( IMutexGuard& i_instanceLock )
+ {
+ impl_processRequest(
+ ::boost::bind(
+ &UndoManagerHelper_Impl::impl_reset,
+ this
+ ),
+ i_instanceLock
+ );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void UndoManagerHelper_Impl::impl_processRequest( ::boost::function0< void > const& i_request, IMutexGuard& i_instanceLock )
+ {
+ // SYNCHRONIZED --->
+ ::osl::ClearableMutexGuard aGuard( m_aMutex );
+ if ( !m_pRequestProcessor.is() )
+ {
+ m_pRequestProcessor.set( new ::comphelper::AsyncEventNotifier );
+ m_pRequestProcessor->create();
+ }
+
+ ::rtl::Reference< UndoManagerRequest > pRequest( new UndoManagerRequest( i_request ) );
+ m_pRequestProcessor->addEvent( pRequest.get(), this );
+
+ aGuard.clear();
+ i_instanceLock.clear();
+ // <--- SYNCHRONIZED
+
+ pRequest->wait();
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void UndoManagerHelper_Impl::impl_enterUndoContext( const ::rtl::OUString& i_title, const bool i_hidden )
{
// SYNCHRONIZED --->
+ ::osl::ClearableMutexGuard aGuard( m_aMutex );
+
+ OSL_PRECOND( ::osl::Thread::getCurrentIdentifier() == m_pRequestProcessor->getIdentifier(),
+ "UndoManagerHelper_Impl::impl_enterUndoContext: expected to be executed serialized, in a dedicated thread!" );
+
IUndoManager& rUndoManager = getUndoManager();
if ( !rUndoManager.IsUndoEnabled() )
// ignore this request if the manager is locked
@@ -298,78 +509,268 @@ namespace framework
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" ) ),
- rUndoManagerImplementation.getThis()
+ m_rUndoManagerImplementation.getThis()
);
{
- ::comphelper::FlagGuard aNotificationGuard( bAPIActionRunning );
+ ::comphelper::FlagGuard aNotificationGuard( m_bAPIActionRunning );
rUndoManager.EnterListAction( i_title, ::rtl::OUString() );
}
- aContextVisibilities.push( i_hidden );
+ m_aContextVisibilities.push( i_hidden );
- notify( i_title, i_hidden ? &XUndoManagerListener::enteredHiddenContext : &XUndoManagerListener::enteredContext, i_instanceLock );
+ const UndoManagerEvent aEvent( buildEvent( i_title ) );
+ aGuard.clear();
// <--- SYNCHRONIZED
+
+ m_aUndoListeners.notifyEach( i_hidden ? &XUndoManagerListener::enteredHiddenContext : &XUndoManagerListener::enteredContext, aEvent );
}
//------------------------------------------------------------------------------------------------------------------
- void UndoManagerHelper_Impl::doUndoRedo(
- 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& ),
- IClearableInstanceLock& i_instanceLock )
+ void UndoManagerHelper_Impl::impl_leaveUndoContext()
{
// SYNCHRONIZED --->
+ ::osl::ClearableMutexGuard aGuard( m_aMutex );
+
+ OSL_PRECOND( ::osl::Thread::getCurrentIdentifier() == m_pRequestProcessor->getIdentifier(),
+ "UndoManagerHelper_Impl::impl_leaveUndoContext: expected to be executed serialized, in a dedicated thread!" );
+
+ IUndoManager& rUndoManager = 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" ) ),
+ getXUndoManager()
+ );
+
+ USHORT nContextElements = 0;
+
+ const bool isHiddenContext = m_aContextVisibilities.top();;
+ m_aContextVisibilities.pop();
+
+ {
+ ::comphelper::FlagGuard aNotificationGuard( m_bAPIActionRunning );
+ if ( isHiddenContext )
+ nContextElements = rUndoManager.LeaveAndMergeListAction();
+ else
+ nContextElements = rUndoManager.LeaveListAction();
+ }
+
+ // prepare notification
+ void ( SAL_CALL XUndoManagerListener::*notificationMethod )( const UndoManagerEvent& ) = NULL;
+
+ UndoManagerEvent aEvent( buildEvent( ::rtl::OUString() ) );
+ if ( nContextElements == 0 )
+ {
+ notificationMethod = &XUndoManagerListener::cancelledContext;
+ }
+ else if ( isHiddenContext )
+ {
+ notificationMethod = &XUndoManagerListener::leftHiddenContext;
+ }
+ else
+ {
+ aEvent.UndoActionTitle = rUndoManager.GetUndoActionComment( 0, IUndoManager::CurrentLevel );
+ notificationMethod = &XUndoManagerListener::leftContext;
+ }
+
+ aGuard.clear();
+ // <--- SYNCHRONIZED
+
+ m_aUndoListeners.notifyEach( notificationMethod, aEvent );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void UndoManagerHelper_Impl::impl_doUndoRedo( IMutexGuard& i_externalLock, const bool i_undo )
+ {
+ ::osl::Guard< ::framework::IMutex > aExternalGuard( i_externalLock.getGuardedMutex() );
+ // note that this assumes that the mutex has been released in the thread which added the
+ // Undo/Redo request, so we can successfully acquire it
+
+ // SYNCHRONIZED --->
+ ::osl::ClearableMutexGuard aGuard( m_aMutex );
+
+ OSL_PRECOND( ::osl::Thread::getCurrentIdentifier() == m_pRequestProcessor->getIdentifier(),
+ "UndoManagerHelper_Impl::impl_doUndoRedo: expected to be executed serialized, in a dedicated thread!" );
+
IUndoManager& rUndoManager = getUndoManager();
if ( rUndoManager.IsInListAction() )
throw UndoContextNotClosedException( ::rtl::OUString(), getXUndoManager() );
- if ( (rUndoManager.*i_checkMethod)( IUndoManager::TopLevel ) == 0 )
+ const USHORT nElements = i_undo
+ ? rUndoManager.GetUndoActionCount( IUndoManager::TopLevel )
+ : rUndoManager.GetRedoActionCount( IUndoManager::TopLevel );
+ if ( nElements == 0 )
throw EmptyUndoStackException( ::rtl::OUString::createFromAscii( "stack is empty" ), getXUndoManager() );
- const ::rtl::OUString sUndoActionTitle = (rUndoManager.*i_titleRetriever)( 0, IUndoManager::TopLevel );
+ aGuard.clear();
+ // <--- SYNCHRONIZED
+
+ try
{
- ::comphelper::FlagGuard aNotificationGuard( 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(), getXUndoManager(), aError );
- }
+ if ( i_undo )
+ rUndoManager.Undo();
+ else
+ rUndoManager.Redo();
+ }
+ 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(), getXUndoManager(), aError );
}
- notify( sUndoActionTitle, i_notificationMethod, i_instanceLock );
- // <--- SYNCHRONIZED
+ // note that in opposite to all of the other methods, we do *not* have our mutex locked when calling
+ // into the IUndoManager implementation. This ensures that an actual XUndoAction::undo/redo is also
+ // called without our mutex being locked.
+ // As a consequence, we do not set m_bAPIActionRunning here. Instead, our actionUndone/actionRedone methods
+ // *always* multiplex the event to our XUndoManagerListeners, not only when m_bAPIActionRunning is FALSE (This
+ // again is different from all other SfxUndoListener methods).
+ // So, we do not need to do this notification here ourself.
}
//------------------------------------------------------------------------------------------------------------------
- void UndoManagerHelper_Impl::actionUndone( const String& i_actionComment )
+ void UndoManagerHelper_Impl::impl_addUndoAction( const Reference< XUndoAction >& i_action )
{
- if ( bAPIActionRunning )
+ // SYNCHRONIZED --->
+ ::osl::ClearableMutexGuard aGuard( m_aMutex );
+
+ OSL_PRECOND( ::osl::Thread::getCurrentIdentifier() == m_pRequestProcessor->getIdentifier(),
+ "UndoManagerHelper_Impl::impl_addUndoAction: expected to be executed serialized, in a dedicated thread!" );
+
+ IUndoManager& rUndoManager = getUndoManager();
+ if ( !rUndoManager.IsUndoEnabled() )
+ // ignore the request if the manager is locked
return;
- notify( i_actionComment, &XUndoManagerListener::actionUndone );
+ const UndoManagerEvent aEventAdd( buildEvent( i_action->getTitle() ) );
+ const EventObject aEventClear( getXUndoManager() );
+
+ const bool bHadRedoActions = ( rUndoManager.GetRedoActionCount( IUndoManager::CurrentLevel ) > 0 );
+ {
+ ::comphelper::FlagGuard aNotificationGuard( m_bAPIActionRunning );
+ rUndoManager.AddUndoAction( new UndoActionWrapper( i_action ) );
+ }
+ const bool bHasRedoActions = ( rUndoManager.GetRedoActionCount( IUndoManager::CurrentLevel ) > 0 );
+
+ aGuard.clear();
+ // <--- SYNCHRONIZED
+
+ m_aUndoListeners.notifyEach( &XUndoManagerListener::undoActionAdded, aEventAdd );
+ if ( bHadRedoActions && !bHasRedoActions )
+ m_aUndoListeners.notifyEach( &XUndoManagerListener::redoActionsCleared , aEventClear );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void UndoManagerHelper_Impl::impl_clear()
+ {
+ // SYNCHRONIZED --->
+ ::osl::ClearableMutexGuard aGuard( m_aMutex );
+
+ OSL_PRECOND( ::osl::Thread::getCurrentIdentifier() == m_pRequestProcessor->getIdentifier(),
+ "UndoManagerHelper_Impl::impl_clear: expected to be executed serialized, in a dedicated thread!" );
+
+ IUndoManager& rUndoManager = getUndoManager();
+ if ( rUndoManager.IsInListAction() )
+ throw UndoContextNotClosedException( ::rtl::OUString(), getXUndoManager() );
+
+ {
+ ::comphelper::FlagGuard aNotificationGuard( m_bAPIActionRunning );
+ rUndoManager.Clear();
+ }
+
+ const EventObject aEvent( getXUndoManager() );
+ aGuard.clear();
+ // <--- SYNCHRONIZED
+
+ m_aUndoListeners.notifyEach( &XUndoManagerListener::allActionsCleared, aEvent );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void UndoManagerHelper_Impl::impl_clearRedo()
+ {
+ // SYNCHRONIZED --->
+ ::osl::ClearableMutexGuard aGuard( m_aMutex );
+
+ OSL_PRECOND( ::osl::Thread::getCurrentIdentifier() == m_pRequestProcessor->getIdentifier(),
+ "UndoManagerHelper_Impl::impl_clearRedo: expected to be executed serialized, in a dedicated thread!" );
+
+ IUndoManager& rUndoManager = getUndoManager();
+ if ( rUndoManager.IsInListAction() )
+ throw UndoContextNotClosedException( ::rtl::OUString(), getXUndoManager() );
+
+ {
+ ::comphelper::FlagGuard aNotificationGuard( m_bAPIActionRunning );
+ rUndoManager.ClearRedo();
+ }
+
+ const EventObject aEvent( getXUndoManager() );
+ aGuard.clear();
+ // <--- SYNCHRONIZED
+
+ m_aUndoListeners.notifyEach( &XUndoManagerListener::redoActionsCleared, aEvent );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void UndoManagerHelper_Impl::impl_reset()
+ {
+ // SYNCHRONIZED --->
+ ::osl::ClearableMutexGuard aGuard( m_aMutex );
+
+ OSL_PRECOND( ::osl::Thread::getCurrentIdentifier() == m_pRequestProcessor->getIdentifier(),
+ "UndoManagerHelper_Impl::impl_reset: expected to be executed serialized, in a dedicated thread!" );
+
+ IUndoManager& rUndoManager = getUndoManager();
+ {
+ ::comphelper::FlagGuard aNotificationGuard( m_bAPIActionRunning );
+ while ( rUndoManager.IsInListAction() )
+ rUndoManager.LeaveListAction();
+ rUndoManager.Clear();
+ }
+
+ const EventObject aEvent( getXUndoManager() );
+ aGuard.clear();
+ // <--- SYNCHRONIZED
+
+ m_aUndoListeners.notifyEach( &XUndoManagerListener::resetAll, aEvent );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void UndoManagerHelper_Impl::processEvent( const ::comphelper::AnyEvent& i_event )
+ {
+ UndoManagerRequest& rRequest( dynamic_cast< UndoManagerRequest& >( const_cast< ::comphelper::AnyEvent& >( i_event ) ) );
+ rRequest.execute();
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void UndoManagerHelper_Impl::actionUndone( const String& i_actionComment )
+ {
+ UndoManagerEvent aEvent;
+ aEvent.Source = getXUndoManager();
+ aEvent.UndoActionTitle = i_actionComment;
+ aEvent.UndoContextDepth = 0; // Undo can happen on level 0 only
+ m_aUndoListeners.notifyEach( &XUndoManagerListener::actionUndone, aEvent );
}
//------------------------------------------------------------------------------------------------------------------
void UndoManagerHelper_Impl::actionRedone( const String& i_actionComment )
{
- if ( bAPIActionRunning )
- return;
-
- notify( i_actionComment, &XUndoManagerListener::actionRedone );
+ UndoManagerEvent aEvent;
+ aEvent.Source = getXUndoManager();
+ aEvent.UndoActionTitle = i_actionComment;
+ aEvent.UndoContextDepth = 0; // Redo can happen on level 0 only
+ m_aUndoListeners.notifyEach( &XUndoManagerListener::actionRedone, aEvent );
}
//------------------------------------------------------------------------------------------------------------------
void UndoManagerHelper_Impl::undoActionAdded( const String& i_actionComment )
{
- if ( bAPIActionRunning )
+ if ( m_bAPIActionRunning )
return;
notify( i_actionComment, &XUndoManagerListener::undoActionAdded );
@@ -378,7 +779,7 @@ namespace framework
//------------------------------------------------------------------------------------------------------------------
void UndoManagerHelper_Impl::cleared()
{
- if ( bAPIActionRunning )
+ if ( m_bAPIActionRunning )
return;
notify( &XUndoManagerListener::allActionsCleared );
@@ -387,7 +788,7 @@ namespace framework
//------------------------------------------------------------------------------------------------------------------
void UndoManagerHelper_Impl::clearedRedo()
{
- if ( bAPIActionRunning )
+ if ( m_bAPIActionRunning )
return;
notify( &XUndoManagerListener::redoActionsCleared );
@@ -397,58 +798,58 @@ namespace framework
void UndoManagerHelper_Impl::listActionEntered( const String& i_comment )
{
#if OSL_DEBUG_LEVEL > 0
- aContextAPIFlags.push( bAPIActionRunning );
+ m_aContextAPIFlags.push( m_bAPIActionRunning );
#endif
- if ( bAPIActionRunning )
+ if ( m_bAPIActionRunning )
return;
notify( i_comment, &XUndoManagerListener::enteredContext );
}
//------------------------------------------------------------------------------------------------------------------
- void UndoManagerHelper_Impl::listActionLeft()
+ void UndoManagerHelper_Impl::listActionLeft( const String& i_comment )
{
#if OSL_DEBUG_LEVEL > 0
- const bool bCurrentContextIsAPIContext = aContextAPIFlags.top();
- aContextAPIFlags.pop();
- OSL_ENSURE( bCurrentContextIsAPIContext == bAPIActionRunning, "UndoManagerHelper_Impl::listActionLeft: API and non-API contexts interwoven!" );
+ const bool bCurrentContextIsAPIContext = m_aContextAPIFlags.top();
+ m_aContextAPIFlags.pop();
+ OSL_ENSURE( bCurrentContextIsAPIContext == m_bAPIActionRunning, "UndoManagerHelper_Impl::listActionLeft: API and non-API contexts interwoven!" );
#endif
- if ( bAPIActionRunning )
+ if ( m_bAPIActionRunning )
return;
- notify( getUndoManager().GetUndoActionComment( 0, IUndoManager::CurrentLevel ), &XUndoManagerListener::leftContext );
+ notify( i_comment, &XUndoManagerListener::leftContext );
}
//------------------------------------------------------------------------------------------------------------------
void UndoManagerHelper_Impl::listActionLeftAndMerged()
{
#if OSL_DEBUG_LEVEL > 0
- const bool bCurrentContextIsAPIContext = aContextAPIFlags.top();
- aContextAPIFlags.pop();
- OSL_ENSURE( bCurrentContextIsAPIContext == bAPIActionRunning, "UndoManagerHelper_Impl::listActionLeftAndMerged: API and non-API contexts interwoven!" );
+ const bool bCurrentContextIsAPIContext = m_aContextAPIFlags.top();
+ m_aContextAPIFlags.pop();
+ OSL_ENSURE( bCurrentContextIsAPIContext == m_bAPIActionRunning, "UndoManagerHelper_Impl::listActionLeftAndMerged: API and non-API contexts interwoven!" );
#endif
- if ( bAPIActionRunning )
+ if ( m_bAPIActionRunning )
return;
- notify( ::rtl::OUString(), &XUndoManagerListener::leftHiddenContext );
+ notify( &XUndoManagerListener::leftHiddenContext );
}
//------------------------------------------------------------------------------------------------------------------
void UndoManagerHelper_Impl::listActionCancelled()
{
#if OSL_DEBUG_LEVEL > 0
- const bool bCurrentContextIsAPIContext = aContextAPIFlags.top();
- aContextAPIFlags.pop();
- OSL_ENSURE( bCurrentContextIsAPIContext == bAPIActionRunning, "UndoManagerHelper_Impl::listActionCancelled: API and non-API contexts interwoven!" );
+ const bool bCurrentContextIsAPIContext = m_aContextAPIFlags.top();
+ m_aContextAPIFlags.pop();
+ OSL_ENSURE( bCurrentContextIsAPIContext == m_bAPIActionRunning, "UndoManagerHelper_Impl::listActionCancelled: API and non-API contexts interwoven!" );
#endif
- if ( bAPIActionRunning )
+ if ( m_bAPIActionRunning )
return;
- notify( ::rtl::OUString(), &XUndoManagerListener::cancelledContext );
+ notify( &XUndoManagerListener::cancelledContext );
}
//------------------------------------------------------------------------------------------------------------------
@@ -478,124 +879,91 @@ namespace framework
}
//------------------------------------------------------------------------------------------------------------------
- void UndoManagerHelper::enterUndoContext( const ::rtl::OUString& i_title, IClearableInstanceLock& i_instanceLock )
+ void UndoManagerHelper::enterUndoContext( const ::rtl::OUString& i_title, IMutexGuard& i_instanceLock )
{
m_pImpl->enterUndoContext( i_title, false, i_instanceLock );
}
//------------------------------------------------------------------------------------------------------------------
- void UndoManagerHelper::enterHiddenUndoContext( IClearableInstanceLock& i_instanceLock )
+ void UndoManagerHelper::enterHiddenUndoContext( IMutexGuard& i_instanceLock )
{
m_pImpl->enterUndoContext( ::rtl::OUString(), true, i_instanceLock );
}
//------------------------------------------------------------------------------------------------------------------
- void UndoManagerHelper::leaveUndoContext( IClearableInstanceLock& i_instanceLock )
+ void UndoManagerHelper::leaveUndoContext( IMutexGuard& i_instanceLock )
{
- // SYNCHRONIZED --->
- 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" ) ),
- m_pImpl->getXUndoManager()
- );
-
- 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 )
- m_pImpl->notify( ::rtl::OUString(), &XUndoManagerListener::cancelledContext, i_instanceLock );
- else if ( isHiddenContext )
- m_pImpl->notify( ::rtl::OUString(), &XUndoManagerListener::leftHiddenContext, i_instanceLock );
- else
- m_pImpl->notify( rUndoManager.GetUndoActionComment( 0, IUndoManager::CurrentLevel ), &XUndoManagerListener::leftContext, i_instanceLock );
- // <--- SYNCHRONIZED
+ m_pImpl->leaveUndoContext( i_instanceLock );
}
//------------------------------------------------------------------------------------------------------------------
- void UndoManagerHelper::addUndoAction( const Reference< XUndoAction >& i_action, IClearableInstanceLock& i_instanceLock )
+ void UndoManagerHelper_Impl::undo( IMutexGuard& i_instanceLock )
{
- // SYNCHRONIZED --->
- if ( !i_action.is() )
- throw IllegalArgumentException(
- ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "illegal undo action object" ) ),
- m_pImpl->getXUndoManager(),
- 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 );
-
- m_pImpl->notify( i_action->getTitle(), &XUndoManagerListener::undoActionAdded, i_instanceLock );
- // <--- SYNCHRONIZED
-
- if ( bHadRedoActions && !bHasRedoActions )
- m_pImpl->notify( &XUndoManagerListener::redoActionsCleared );
+ impl_processRequest(
+ ::boost::bind(
+ &UndoManagerHelper_Impl::impl_doUndoRedo,
+ this,
+ ::boost::ref( i_instanceLock ),
+ true
+ ),
+ i_instanceLock
+ );
}
//------------------------------------------------------------------------------------------------------------------
- void UndoManagerHelper::undo( IClearableInstanceLock& i_instanceLock )
+ void UndoManagerHelper_Impl::redo( IMutexGuard& i_instanceLock )
{
- m_pImpl->doUndoRedo(
- &IUndoManager::GetUndoActionCount,
- &IUndoManager::Undo,
- &IUndoManager::GetUndoActionComment,
- &XUndoManagerListener::actionUndone,
+ impl_processRequest(
+ ::boost::bind(
+ &UndoManagerHelper_Impl::impl_doUndoRedo,
+ this,
+ ::boost::ref( i_instanceLock ),
+ false
+ ),
i_instanceLock
);
}
//------------------------------------------------------------------------------------------------------------------
- void UndoManagerHelper::redo( IClearableInstanceLock& i_instanceLock )
+ void UndoManagerHelper::addUndoAction( const Reference< XUndoAction >& i_action, IMutexGuard& i_instanceLock )
{
- m_pImpl->doUndoRedo(
- &IUndoManager::GetRedoActionCount,
- &IUndoManager::Redo,
- &IUndoManager::GetRedoActionComment,
- &XUndoManagerListener::actionRedone,
- i_instanceLock
- );
+ m_pImpl->addUndoAction( i_action, i_instanceLock );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void UndoManagerHelper::undo( IMutexGuard& i_instanceLock )
+ {
+ m_pImpl->undo( i_instanceLock );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void UndoManagerHelper::redo( IMutexGuard& i_instanceLock )
+ {
+ m_pImpl->redo( i_instanceLock );
}
//------------------------------------------------------------------------------------------------------------------
::sal_Bool UndoManagerHelper::isUndoPossible() const
{
+ // SYNCHRONIZED --->
+ ::osl::MutexGuard aGuard( m_pImpl->getMutex() );
IUndoManager& rUndoManager = m_pImpl->getUndoManager();
if ( rUndoManager.IsInListAction() )
return sal_False;
return rUndoManager.GetUndoActionCount( IUndoManager::TopLevel ) > 0;
+ // <--- SYNCHRONIZED
}
//------------------------------------------------------------------------------------------------------------------
::sal_Bool UndoManagerHelper::isRedoPossible() const
{
+ // SYNCHRONIZED --->
+ ::osl::MutexGuard aGuard( m_pImpl->getMutex() );
const IUndoManager& rUndoManager = m_pImpl->getUndoManager();
if ( rUndoManager.IsInListAction() )
return sal_False;
return rUndoManager.GetRedoActionCount( IUndoManager::TopLevel ) > 0;
+ // <--- SYNCHRONIZED
}
//------------------------------------------------------------------------------------------------------------------
@@ -604,6 +972,9 @@ namespace framework
//..............................................................................................................
::rtl::OUString lcl_getCurrentActionTitle( UndoManagerHelper_Impl& i_impl, const bool i_undo )
{
+ // SYNCHRONIZED --->
+ ::osl::MutexGuard aGuard( i_impl.getMutex() );
+
const IUndoManager& rUndoManager = i_impl.getUndoManager();
const USHORT nActionCount = i_undo
? rUndoManager.GetUndoActionCount( IUndoManager::TopLevel )
@@ -617,11 +988,15 @@ namespace framework
return i_undo
? rUndoManager.GetUndoActionComment( 0, IUndoManager::TopLevel )
: rUndoManager.GetRedoActionComment( 0, IUndoManager::TopLevel );
+ // <--- SYNCHRONIZED
}
//..............................................................................................................
Sequence< ::rtl::OUString > lcl_getAllActionTitles( UndoManagerHelper_Impl& i_impl, const bool i_undo )
{
+ // SYNCHRONIZED --->
+ ::osl::MutexGuard aGuard( i_impl.getMutex() );
+
const IUndoManager& rUndoManager = i_impl.getUndoManager();
const USHORT nCount = i_undo
? rUndoManager.GetUndoActionCount( IUndoManager::TopLevel )
@@ -635,6 +1010,7 @@ namespace framework
: rUndoManager.GetRedoActionComment( i, IUndoManager::TopLevel );
}
return aTitles;
+ // <--- SYNCHRONIZED
}
}
@@ -663,90 +1039,70 @@ namespace framework
}
//------------------------------------------------------------------------------------------------------------------
- void UndoManagerHelper::clear( IClearableInstanceLock& i_instanceLock )
+ void UndoManagerHelper::clear( IMutexGuard& i_instanceLock )
{
- // SYNCHRONIZED --->
- IUndoManager& rUndoManager = m_pImpl->getUndoManager();
- if ( rUndoManager.IsInListAction() )
- throw UndoContextNotClosedException( ::rtl::OUString(), m_pImpl->getXUndoManager() );
-
- {
- ::comphelper::FlagGuard aNotificationGuard( m_pImpl->bAPIActionRunning );
- rUndoManager.Clear();
- }
-
- m_pImpl->notify( &XUndoManagerListener::allActionsCleared, i_instanceLock );
- // <--- SYNCHRONIZED
+ m_pImpl->clear( i_instanceLock );
}
//------------------------------------------------------------------------------------------------------------------
- void UndoManagerHelper::clearRedo( IClearableInstanceLock& i_instanceLock )
+ void UndoManagerHelper::clearRedo( IMutexGuard& i_instanceLock )
{
- // SYNCHRONIZED --->
- IUndoManager& rUndoManager = m_pImpl->getUndoManager();
- if ( rUndoManager.IsInListAction() )
- throw UndoContextNotClosedException( ::rtl::OUString(), m_pImpl->getXUndoManager() );
-
- {
- ::comphelper::FlagGuard aNotificationGuard( m_pImpl->bAPIActionRunning );
- rUndoManager.ClearRedo();
- }
-
- m_pImpl->notify( &XUndoManagerListener::redoActionsCleared, i_instanceLock );
- // <--- SYNCHRONIZED
+ m_pImpl->clearRedo( i_instanceLock );
}
//------------------------------------------------------------------------------------------------------------------
- void UndoManagerHelper::reset( IClearableInstanceLock& i_instanceLock )
+ void UndoManagerHelper::reset( IMutexGuard& i_instanceLock )
{
- // SYNCHRONIZED --->
- IUndoManager& rUndoManager = m_pImpl->getUndoManager();
- {
- ::comphelper::FlagGuard aNotificationGuard( m_pImpl->bAPIActionRunning );
- while ( rUndoManager.IsInListAction() )
- rUndoManager.LeaveListAction();
- rUndoManager.Clear();
- }
-
- m_pImpl->notify( &XUndoManagerListener::resetAll, i_instanceLock );
- // <--- SYNCHRONIZED
+ m_pImpl->reset( i_instanceLock );
}
//------------------------------------------------------------------------------------------------------------------
void UndoManagerHelper::lock()
{
+ // SYNCHRONIZED --->
+ ::osl::MutexGuard aGuard( m_pImpl->getMutex() );
+
IUndoManager& rUndoManager = m_pImpl->getUndoManager();
rUndoManager.EnableUndo( false );
+ // <--- SYNCHRONIZED
}
//------------------------------------------------------------------------------------------------------------------
void UndoManagerHelper::unlock()
{
+ // SYNCHRONIZED --->
+ ::osl::MutexGuard aGuard( m_pImpl->getMutex() );
+
IUndoManager& rUndoManager = m_pImpl->getUndoManager();
if ( rUndoManager.IsUndoEnabled() )
throw NotLockedException( ::rtl::OUString::createFromAscii( "Undo manager is not locked" ), m_pImpl->getXUndoManager() );
rUndoManager.EnableUndo( true );
+ // <--- SYNCHRONIZED
}
//------------------------------------------------------------------------------------------------------------------
::sal_Bool UndoManagerHelper::isLocked()
{
+ // SYNCHRONIZED --->
+ ::osl::MutexGuard aGuard( m_pImpl->getMutex() );
+
IUndoManager& rUndoManager = m_pImpl->getUndoManager();
return !rUndoManager.IsUndoEnabled();
+ // <--- SYNCHRONIZED
}
//------------------------------------------------------------------------------------------------------------------
void UndoManagerHelper::addUndoManagerListener( const Reference< XUndoManagerListener >& i_listener )
{
if ( i_listener.is() )
- m_pImpl->aUndoListeners.addInterface( i_listener );
+ m_pImpl->addUndoManagerListener( i_listener );
}
//------------------------------------------------------------------------------------------------------------------
void UndoManagerHelper::removeUndoManagerListener( const Reference< XUndoManagerListener >& i_listener )
{
if ( i_listener.is() )
- m_pImpl->aUndoListeners.removeInterface( i_listener );
+ m_pImpl->removeUndoManagerListener( i_listener );
}
//......................................................................................................................
diff --git a/framework/util/makefile.mk b/framework/util/makefile.mk
index 13c3d70d0d3c..012077dbc7ab 100644
--- a/framework/util/makefile.mk
+++ b/framework/util/makefile.mk
@@ -424,6 +424,7 @@ $(MISC)$/$(SHL2TARGET).flt: makefile.mk
@echo m_pLoader>$@
@echo _TI2>>$@
@echo _TI3>>$@
+ @echo _TI8>>$@
@echo LIBMAIN>>$@
@echo LibMain>>$@
diff --git a/sfx2/inc/sfx2/sfxbasemodel.hxx b/sfx2/inc/sfx2/sfxbasemodel.hxx
index 4367810e1675..2ba73f4034fc 100644
--- a/sfx2/inc/sfx2/sfxbasemodel.hxx
+++ b/sfx2/inc/sfx2/sfxbasemodel.hxx
@@ -1616,13 +1616,18 @@ public:
{
}
+ void reset()
+ {
+ m_aGuard.reset();
+ }
+
void clear()
{
m_aGuard.clear();
}
private:
- ::vos::OClearableGuard m_aGuard;
+ ::osl::ResettableGuard< ::vos::IMutex > m_aGuard;
};
#undef css
diff --git a/sfx2/qa/complex/sfx2/UndoManager.java b/sfx2/qa/complex/sfx2/UndoManager.java
index 421111e88f4e..c86ceef5a1ac 100755
--- a/sfx2/qa/complex/sfx2/UndoManager.java
+++ b/sfx2/qa/complex/sfx2/UndoManager.java
@@ -456,6 +456,7 @@ public class UndoManager
public void leftHiddenContext( UndoManagerEvent i_event )
{
assertFalse( "|leftHiddenContext| called after document was disposed", m_isDisposed );
+ assertEquals( "|leftHiddenContext| is not expected to notify an action title", 0, i_event.UndoActionTitle.length() );
m_activeUndoContexts.pop();
assertEquals( "different opinions on the context nesting level (after leaving)",
@@ -467,6 +468,7 @@ public class UndoManager
public void cancelledContext( UndoManagerEvent i_event )
{
assertFalse( "|cancelledContext| called after document was disposed", m_isDisposed );
+ assertEquals( "|cancelledContext| is not expected to notify an action title", 0, i_event.UndoActionTitle.length() );
m_activeUndoContexts.pop();
assertEquals( "different opinions on the context nesting level (after cancelling)",
@@ -590,6 +592,7 @@ public class UndoManager
// close the document, ensure the Undo manager listener gets notified
m_currentDocument.close();
+ m_currentDocument = null;
assertTrue( "document is closed, but the UndoManagerListener has not been notified of the disposal", m_undoListener.isDisposed() );
}
diff --git a/sfx2/source/doc/docundomanager.cxx b/sfx2/source/doc/docundomanager.cxx
index 39534bf9f90c..6fbe1996d85d 100755
--- a/sfx2/source/doc/docundomanager.cxx
+++ b/sfx2/source/doc/docundomanager.cxx
@@ -44,6 +44,7 @@
#include <tools/diagnose_ex.h>
#include <framework/undomanagerhelper.hxx>
+#include <boost/noncopyable.hpp>
#include <stack>
//......................................................................................................................
@@ -103,7 +104,6 @@ namespace sfx2
SfxObjectShell* getObjectShell() { return rAntiImpl.getBaseModel().GetObjectShell(); }
// IUndoManagerImplementation
- virtual ::osl::Mutex& getMutex();
virtual ::svl::IUndoManager& getImplUndoManager();
virtual Reference< XUndoManager > getThis();
@@ -131,12 +131,6 @@ namespace sfx2
};
//------------------------------------------------------------------------------------------------------------------
- ::osl::Mutex& DocumentUndoManager_Impl::getMutex()
- {
- return rAntiImpl.getMutex();
- }
-
- //------------------------------------------------------------------------------------------------------------------
::svl::IUndoManager& DocumentUndoManager_Impl::getImplUndoManager()
{
ENSURE_OR_THROW( pUndoManager != NULL, "DocumentUndoManager_Impl::getImplUndoManager: no access to the doc's UndoManager implementation!" );
@@ -193,23 +187,65 @@ namespace sfx2
}
//==================================================================================================================
- //= SfxModelGuardFacade
+ //= SolarMutexFacade
+ //==================================================================================================================
+ /** a facade for the SolarMutex, implementing ::framework::IMutex (as opposed to ::vos::IMutex)
+ */
+ class SolarMutexFacade : public ::framework::IMutex
+ {
+ public:
+ SolarMutexFacade()
+ {
+ }
+
+ virtual void acquire()
+ {
+ Application::GetSolarMutex().acquire();
+ }
+
+ virtual void release()
+ {
+ Application::GetSolarMutex().release();
+ }
+ };
+
+ //==================================================================================================================
+ //= UndoManagerGuard
//==================================================================================================================
- class SfxModelGuardFacade : public ::framework::IClearableInstanceLock
+ class UndoManagerGuard :public ::framework::IMutexGuard
+ ,public ::boost::noncopyable
{
public:
- SfxModelGuardFacade( SfxModelGuard& i_guard )
- :m_guard( i_guard )
+ UndoManagerGuard( DocumentUndoManager& i_undoManager )
+ :m_guard( i_undoManager )
+ ,m_solarMutexFacade()
+ {
+ }
+
+ ~UndoManagerGuard()
{
}
+ virtual void reset()
+ {
+ m_guard.reset();
+ }
+
virtual void clear()
{
m_guard.clear();
}
+ virtual ::framework::IMutex& getGuardedMutex()
+ {
+ // note that this means that we *know* that SfxModelGuard also locks the SolarMutex (nothing more, nothing less).
+ // If this ever changes, we need to adjust this code here, too.
+ return m_solarMutexFacade;
+ }
+
private:
- SfxModelGuard& m_guard;
+ SfxModelGuard m_guard;
+ SolarMutexFacade m_solarMutexFacade;
};
//==================================================================================================================
@@ -248,16 +284,19 @@ namespace sfx2
//------------------------------------------------------------------------------------------------------------------
void SAL_CALL DocumentUndoManager::enterUndoContext( const ::rtl::OUString& i_title ) throw (RuntimeException)
{
- SfxModelGuard aGuard( *this );
- m_pImpl->aUndoHelper.enterUndoContext( i_title, SfxModelGuardFacade( aGuard ) );
+ // SYNCHRONIZED --->
+ UndoManagerGuard aGuard( *this );
+ m_pImpl->aUndoHelper.enterUndoContext( i_title, aGuard );
+ // <--- SYNCHRONIZED
+ m_pImpl->invalidateXDo_nolck();
}
//------------------------------------------------------------------------------------------------------------------
void SAL_CALL DocumentUndoManager::enterHiddenUndoContext( ) throw (EmptyUndoStackException, RuntimeException)
{
// SYNCHRONIZED --->
- SfxModelGuard aGuard( *this );
- m_pImpl->aUndoHelper.enterHiddenUndoContext( SfxModelGuardFacade( aGuard ) );
+ UndoManagerGuard aGuard( *this );
+ m_pImpl->aUndoHelper.enterHiddenUndoContext( aGuard );
// <--- SYNCHRONIZED
m_pImpl->invalidateXDo_nolck();
}
@@ -266,8 +305,8 @@ namespace sfx2
void SAL_CALL DocumentUndoManager::leaveUndoContext( ) throw (InvalidStateException, RuntimeException)
{
// SYNCHRONIZED --->
- SfxModelGuard aGuard( *this );
- m_pImpl->aUndoHelper.leaveUndoContext( SfxModelGuardFacade( aGuard ) );
+ UndoManagerGuard aGuard( *this );
+ m_pImpl->aUndoHelper.leaveUndoContext( aGuard );
// <--- SYNCHRONIZED
m_pImpl->invalidateXDo_nolck();
}
@@ -276,8 +315,8 @@ namespace sfx2
void SAL_CALL DocumentUndoManager::addUndoAction( const Reference< XUndoAction >& i_action ) throw (RuntimeException, IllegalArgumentException)
{
// SYNCHRONIZED --->
- SfxModelGuard aGuard( *this );
- m_pImpl->aUndoHelper.addUndoAction( i_action, SfxModelGuardFacade( aGuard ) );
+ UndoManagerGuard aGuard( *this );
+ m_pImpl->aUndoHelper.addUndoAction( i_action, aGuard );
// <--- SYNCHRONIZED
m_pImpl->invalidateXDo_nolck();
}
@@ -286,9 +325,9 @@ namespace sfx2
void SAL_CALL DocumentUndoManager::undo( ) throw (EmptyUndoStackException, UndoContextNotClosedException, UndoFailedException, RuntimeException)
{
// SYNCHRONIZED --->
- SfxModelGuard aGuard( *this );
+ UndoManagerGuard aGuard( *this );
m_pImpl->enterViewStandardMode();
- m_pImpl->aUndoHelper.undo( SfxModelGuardFacade( aGuard ) );
+ m_pImpl->aUndoHelper.undo( aGuard );
// <--- SYNCHRONIZED
m_pImpl->invalidateXDo_nolck();
}
@@ -297,9 +336,9 @@ namespace sfx2
void SAL_CALL DocumentUndoManager::redo( ) throw (EmptyUndoStackException, UndoContextNotClosedException, UndoFailedException, RuntimeException)
{
// SYNCHRONIZED --->
- SfxModelGuard aGuard( *this );
+ UndoManagerGuard aGuard( *this );
m_pImpl->enterViewStandardMode();
- m_pImpl->aUndoHelper.redo( SfxModelGuardFacade( aGuard ) );
+ m_pImpl->aUndoHelper.redo( aGuard );
// <--- SYNCHRONIZED
m_pImpl->invalidateXDo_nolck();
}
@@ -307,42 +346,42 @@ namespace sfx2
//------------------------------------------------------------------------------------------------------------------
::sal_Bool SAL_CALL DocumentUndoManager::isUndoPossible( ) throw (RuntimeException)
{
- SfxModelGuard aGuard( *this );
+ UndoManagerGuard aGuard( *this );
return m_pImpl->aUndoHelper.isUndoPossible();
}
//------------------------------------------------------------------------------------------------------------------
::sal_Bool SAL_CALL DocumentUndoManager::isRedoPossible( ) throw (RuntimeException)
{
- SfxModelGuard aGuard( *this );
+ UndoManagerGuard aGuard( *this );
return m_pImpl->aUndoHelper.isRedoPossible();
}
//------------------------------------------------------------------------------------------------------------------
::rtl::OUString SAL_CALL DocumentUndoManager::getCurrentUndoActionTitle( ) throw (EmptyUndoStackException, RuntimeException)
{
- SfxModelGuard aGuard( *this );
+ UndoManagerGuard aGuard( *this );
return m_pImpl->aUndoHelper.getCurrentUndoActionTitle();
}
//------------------------------------------------------------------------------------------------------------------
::rtl::OUString SAL_CALL DocumentUndoManager::getCurrentRedoActionTitle( ) throw (EmptyUndoStackException, RuntimeException)
{
- SfxModelGuard aGuard( *this );
+ UndoManagerGuard aGuard( *this );
return m_pImpl->aUndoHelper.getCurrentRedoActionTitle();
}
//------------------------------------------------------------------------------------------------------------------
Sequence< ::rtl::OUString > SAL_CALL DocumentUndoManager::getAllUndoActionTitles( ) throw (RuntimeException)
{
- SfxModelGuard aGuard( *this );
+ UndoManagerGuard aGuard( *this );
return m_pImpl->aUndoHelper.getAllUndoActionTitles();
}
//------------------------------------------------------------------------------------------------------------------
Sequence< ::rtl::OUString > SAL_CALL DocumentUndoManager::getAllRedoActionTitles( ) throw (RuntimeException)
{
- SfxModelGuard aGuard( *this );
+ UndoManagerGuard aGuard( *this );
return m_pImpl->aUndoHelper.getAllRedoActionTitles();
}
@@ -350,8 +389,8 @@ namespace sfx2
void SAL_CALL DocumentUndoManager::clear( ) throw (UndoContextNotClosedException, RuntimeException)
{
// SYNCHRONIZED --->
- SfxModelGuard aGuard( *this );
- m_pImpl->aUndoHelper.clear( SfxModelGuardFacade( aGuard ) );
+ UndoManagerGuard aGuard( *this );
+ m_pImpl->aUndoHelper.clear( aGuard );
// <--- SYNCHRONIZED
m_pImpl->invalidateXDo_nolck();
}
@@ -360,8 +399,8 @@ namespace sfx2
void SAL_CALL DocumentUndoManager::clearRedo( ) throw (UndoContextNotClosedException, RuntimeException)
{
// SYNCHRONIZED --->
- SfxModelGuard aGuard( *this );
- m_pImpl->aUndoHelper.clearRedo( SfxModelGuardFacade( aGuard ) );
+ UndoManagerGuard aGuard( *this );
+ m_pImpl->aUndoHelper.clearRedo( aGuard );
// <--- SYNCHRONIZED
m_pImpl->invalidateXDo_nolck();
}
@@ -370,8 +409,8 @@ namespace sfx2
void SAL_CALL DocumentUndoManager::reset() throw (RuntimeException)
{
// SYNCHRONIZED --->
- SfxModelGuard aGuard( *this );
- m_pImpl->aUndoHelper.reset( SfxModelGuardFacade( aGuard ) );
+ UndoManagerGuard aGuard( *this );
+ m_pImpl->aUndoHelper.reset( aGuard );
// <--- SYNCHRONIZED
m_pImpl->invalidateXDo_nolck();
}
@@ -379,35 +418,35 @@ namespace sfx2
//------------------------------------------------------------------------------------------------------------------
void SAL_CALL DocumentUndoManager::lock( ) throw (RuntimeException)
{
- SfxModelGuard aGuard( *this );
+ UndoManagerGuard aGuard( *this );
m_pImpl->aUndoHelper.lock();
}
//------------------------------------------------------------------------------------------------------------------
void SAL_CALL DocumentUndoManager::unlock( ) throw (RuntimeException, NotLockedException)
{
- SfxModelGuard aGuard( *this );
+ UndoManagerGuard aGuard( *this );
m_pImpl->aUndoHelper.unlock();
}
//------------------------------------------------------------------------------------------------------------------
::sal_Bool SAL_CALL DocumentUndoManager::isLocked( ) throw (RuntimeException)
{
- SfxModelGuard aGuard( *this );
+ UndoManagerGuard aGuard( *this );
return m_pImpl->aUndoHelper.isLocked();
}
//------------------------------------------------------------------------------------------------------------------
void SAL_CALL DocumentUndoManager::addUndoManagerListener( const Reference< XUndoManagerListener >& i_listener ) throw (RuntimeException)
{
- SfxModelGuard aGuard( *this );
+ UndoManagerGuard aGuard( *this );
return m_pImpl->aUndoHelper.addUndoManagerListener( i_listener );
}
//------------------------------------------------------------------------------------------------------------------
void SAL_CALL DocumentUndoManager::removeUndoManagerListener( const Reference< XUndoManagerListener >& i_listener ) throw (RuntimeException)
{
- SfxModelGuard aGuard( *this );
+ UndoManagerGuard aGuard( *this );
return m_pImpl->aUndoHelper.removeUndoManagerListener( i_listener );
}