/**************************************************************
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * 
 *************************************************************/



#include "precompiled_framework.hxx"

#include "framework/undomanagerhelper.hxx"

/** === begin UNO includes === **/
#include <com/sun/star/lang/XComponent.hpp>
/** === 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 <queue>
#include <boost/function.hpp>

//......................................................................................................................
namespace framework
{
//......................................................................................................................

	/** === begin UNO using === **/
	using ::com::sun::star::uno::Reference;
	using ::com::sun::star::uno::XInterface;
	using ::com::sun::star::uno::UNO_QUERY;
	using ::com::sun::star::uno::UNO_QUERY_THROW;
	using ::com::sun::star::uno::UNO_SET_THROW;
	using ::com::sun::star::uno::Exception;
	using ::com::sun::star::uno::RuntimeException;
	using ::com::sun::star::uno::Any;
	using ::com::sun::star::uno::makeAny;
	using ::com::sun::star::uno::Sequence;
	using ::com::sun::star::uno::Type;
    using ::com::sun::star::document::XUndoManagerListener;
    using ::com::sun::star::document::UndoManagerEvent;
    using ::com::sun::star::document::EmptyUndoStackException;
    using ::com::sun::star::document::UndoContextNotClosedException;
    using ::com::sun::star::document::UndoFailedException;
    using ::com::sun::star::util::NotLockedException;
    using ::com::sun::star::lang::EventObject;
    using ::com::sun::star::document::XUndoAction;
    using ::com::sun::star::lang::XComponent;
    using ::com::sun::star::document::XUndoManager;
    using ::com::sun::star::util::InvalidStateException;
    using ::com::sun::star::lang::IllegalArgumentException;
    using ::com::sun::star::util::XModifyListener;
	/** === end UNO using === **/
    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 sal_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();
    }

	//------------------------------------------------------------------------------------------------------------------
    sal_Bool UndoActionWrapper::CanRepeat(SfxRepeatTarget&) const
    {
        return sal_False;
    }

	//==================================================================================================================
	//= UndoManagerRequest
	//==================================================================================================================
    class UndoManagerRequest : public ::comphelper::AnyEvent
    {
    public:
        UndoManagerRequest( ::boost::function0< void > const& i_request )
            :m_request( i_request )
            ,m_caughtException()
            ,m_finishCondition()
        {
            m_finishCondition.reset();
        }

        void execute()
        {
            try
            {
                m_request();
            }
            catch( const Exception& )
            {
                m_caughtException = ::cppu::getCaughtException();
            }
            m_finishCondition.set();
        }

        void wait()
        {
            m_finishCondition.wait();
            if ( m_caughtException.hasValue() )
                ::cppu::throwException( m_caughtException );
        }

        void cancel( const Reference< XInterface >& i_context )
        {
            m_caughtException <<= RuntimeException(
                ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Concurrency error: an earlier operation on the stack failed." ) ),
                i_context
            );
            m_finishCondition.set();
        }

    protected:
        ~UndoManagerRequest()
        {
        }

    private:
        ::boost::function0< void >  m_request;
        Any                         m_caughtException;
        ::osl::Condition            m_finishCondition;
    };

	//------------------------------------------------------------------------------------------------------------------

	//==================================================================================================================
	//= UndoManagerHelper_Impl
	//==================================================================================================================
    class UndoManagerHelper_Impl : public SfxUndoListener
    {
    private:
        ::osl::Mutex                        m_aMutex;
        ::osl::Mutex                        m_aQueueMutex;
        bool                                m_disposed;
        bool                                m_bAPIActionRunning;
        bool                                m_bProcessingEvents;
        sal_Int32                           m_nLockCount;
        ::cppu::OInterfaceContainerHelper   m_aUndoListeners;
        ::cppu::OInterfaceContainerHelper   m_aModifyListeners;
        IUndoManagerImplementation&         m_rUndoManagerImplementation;
        UndoManagerHelper&                  m_rAntiImpl;
        ::std::stack< bool >                m_aContextVisibilities;
#if OSL_DEBUG_LEVEL > 0
        ::std::stack< bool >                m_aContextAPIFlags;
#endif
        ::std::queue< ::rtl::Reference< UndoManagerRequest > >
                                            m_aEventQueue;

    public:
        ::osl::Mutex&   getMutex() { return m_aMutex; }

    public:
        UndoManagerHelper_Impl( UndoManagerHelper& i_antiImpl, IUndoManagerImplementation& i_undoManagerImpl )
            :m_aMutex()
            ,m_aQueueMutex()
            ,m_disposed( false )
            ,m_bAPIActionRunning( false )
            ,m_bProcessingEvents( false )
            ,m_nLockCount( 0 )
            ,m_aUndoListeners( m_aMutex )
            ,m_aModifyListeners( m_aMutex )
            ,m_rUndoManagerImplementation( i_undoManagerImpl )
            ,m_rAntiImpl( i_antiImpl )
        {
            getUndoManager().AddUndoListener( *this );
        }

        virtual ~UndoManagerHelper_Impl()
        {
        }

        //..............................................................................................................
        IUndoManager& getUndoManager() const
        {
            return m_rUndoManagerImplementation.getImplUndoManager();
        }

        //..............................................................................................................
        Reference< XUndoManager > getXUndoManager() const
        {
            return m_rUndoManagerImplementation.getThis();
        }

        // SfxUndoListener
        virtual void actionUndone( const String& i_actionComment );
        virtual void actionRedone( const String& i_actionComment );
        virtual void undoActionAdded( const String& i_actionComment );
        virtual void cleared();
        virtual void clearedRedo();
        virtual void resetAll();
        virtual void listActionEntered( const String& i_comment );
        virtual void listActionLeft( const String& i_comment );
        virtual void listActionLeftAndMerged();
        virtual void listActionCancelled();
        virtual void undoManagerDying();

        // public operations
        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 lock();
        void unlock();

        void addUndoManagerListener( const Reference< XUndoManagerListener >& i_listener )
        {
            m_aUndoListeners.addInterface( i_listener );
        }

        void removeUndoManagerListener( const Reference< XUndoManagerListener >& i_listener )
        {
            m_aUndoListeners.removeInterface( i_listener );
        }

        void addModifyListener( const Reference< XModifyListener >& i_listener )
        {
            m_aModifyListeners.addInterface( i_listener );
        }

        void removeModifyListener( const Reference< XModifyListener >& i_listener )
        {
            m_aModifyListeners.removeInterface( i_listener );
        }

        UndoManagerEvent
            buildEvent( ::rtl::OUString const& i_title ) const;

        void impl_notifyModified();
        void notify(    ::rtl::OUString const& i_title,
                        void ( SAL_CALL XUndoManagerListener::*i_notificationMethod )( const UndoManagerEvent& )
                    );
        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:
        /// 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.
        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::disposing()
    {
        EventObject aEvent;
        aEvent.Source = getXUndoManager();
        m_aUndoListeners.disposeAndClear( aEvent );
        m_aModifyListeners.disposeAndClear( aEvent );

        ::osl::MutexGuard aGuard( m_aMutex );

        getUndoManager().RemoveUndoListener( *this );

        m_disposed = true;
    }

    //------------------------------------------------------------------------------------------------------------------
    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::impl_notifyModified()
    {
        const EventObject aEvent( getXUndoManager() );
        m_aModifyListeners.notifyEach( &XModifyListener::modified, 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
        // 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_aUndoListeners.notifyEach( i_notificationMethod, aEvent );
        impl_notifyModified();
    }

    //------------------------------------------------------------------------------------------------------------------
    void UndoManagerHelper_Impl::notify( void ( SAL_CALL XUndoManagerListener::*i_notificationMethod )( const EventObject& ) )
    {
        const EventObject aEvent( getXUndoManager() );

        // TODO: the same comment as in the other notify, regarding SM locking applies here ...

        m_aUndoListeners.notifyEach( i_notificationMethod, aEvent );
        impl_notifyModified();
    }

    //------------------------------------------------------------------------------------------------------------------
    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::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::lock()
    {
        // SYNCHRONIZED --->
        ::osl::MutexGuard aGuard( getMutex() );

        if ( ++m_nLockCount == 1 )
        {
            IUndoManager& rUndoManager = getUndoManager();
            rUndoManager.EnableUndo( false );
        }
        // <--- SYNCHRONIZED
    }

    //------------------------------------------------------------------------------------------------------------------
    void UndoManagerHelper_Impl::unlock()
    {
        // SYNCHRONIZED --->
        ::osl::MutexGuard aGuard( getMutex() );

        if ( m_nLockCount == 0 )
            throw NotLockedException( ::rtl::OUString::createFromAscii( "Undo manager is not locked" ), getXUndoManager() );

        if ( --m_nLockCount == 0 )
        {
            IUndoManager& rUndoManager = getUndoManager();
            rUndoManager.EnableUndo( true );
        }
        // <--- SYNCHRONIZED
    }

    //------------------------------------------------------------------------------------------------------------------
    void UndoManagerHelper_Impl::impl_processRequest( ::boost::function0< void > const& i_request, IMutexGuard& i_instanceLock )
    {
        // create the request, and add it to our queue
        ::rtl::Reference< UndoManagerRequest > pRequest( new UndoManagerRequest( i_request ) );
        {
            ::osl::MutexGuard aQueueGuard( m_aQueueMutex );
            m_aEventQueue.push( pRequest );
        }

        i_instanceLock.clear();

        if ( m_bProcessingEvents )
        {
            // another thread is processing the event queue currently => it will also process the event which we just added
            pRequest->wait();
            return;
        }

        m_bProcessingEvents = true;
        do
        {
            pRequest.clear();
            {
                ::osl::MutexGuard aQueueGuard( m_aQueueMutex );
                if ( m_aEventQueue.empty() )
                {
                    // reset the flag before releasing the queue mutex, otherwise it's possible that another thread
                    // could add an event after we release the mutex, but before we reset the flag. If then this other
                    // thread checks the flag before be reset it, this thread's event would starve.
                    m_bProcessingEvents = false;
                    return;
                }
                pRequest = m_aEventQueue.front();
                m_aEventQueue.pop();
            }
            try
            {
                pRequest->execute();
                pRequest->wait();
            }
            catch( ... )
            {
                {
                    // no chance to process further requests, if the current one failed
                    // => discard them
                    ::osl::MutexGuard aQueueGuard( m_aQueueMutex );
                    while ( !m_aEventQueue.empty() )
                    {
                        pRequest = m_aEventQueue.front();
                        m_aEventQueue.pop();
                        pRequest->cancel( getXUndoManager() );
                    }
                    m_bProcessingEvents = false;
                }
                // re-throw the error
                throw;
            }
        }
        while ( true );
    }

    //------------------------------------------------------------------------------------------------------------------
    void UndoManagerHelper_Impl::impl_enterUndoContext( const ::rtl::OUString& i_title, const bool i_hidden )
    {
        // SYNCHRONIZED --->
        ::osl::ClearableMutexGuard aGuard( m_aMutex );

        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" ) ),
                m_rUndoManagerImplementation.getThis()
            );

        {
            ::comphelper::FlagGuard aNotificationGuard( m_bAPIActionRunning );
            rUndoManager.EnterListAction( i_title, ::rtl::OUString() );
        }

        m_aContextVisibilities.push( i_hidden );

        const UndoManagerEvent aEvent( buildEvent( i_title ) );
        aGuard.clear();
        // <--- SYNCHRONIZED

        m_aUndoListeners.notifyEach( i_hidden ? &XUndoManagerListener::enteredHiddenContext : &XUndoManagerListener::enteredContext, aEvent );
        impl_notifyModified();
    }

    //------------------------------------------------------------------------------------------------------------------
    void UndoManagerHelper_Impl::impl_leaveUndoContext()
    {
        // SYNCHRONIZED --->
        ::osl::ClearableMutexGuard aGuard( m_aMutex );

        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()
            );

        size_t nContextElements = 0;

        const bool isHiddenContext = m_aContextVisibilities.top();;
        m_aContextVisibilities.pop();

        const bool bHadRedoActions = ( rUndoManager.GetRedoActionCount( IUndoManager::TopLevel ) > 0 );
        {
            ::comphelper::FlagGuard aNotificationGuard( m_bAPIActionRunning );
            if ( isHiddenContext )
                nContextElements = rUndoManager.LeaveAndMergeListAction();
            else
                nContextElements = rUndoManager.LeaveListAction();
        }
        const bool bHasRedoActions = ( rUndoManager.GetRedoActionCount( IUndoManager::TopLevel ) > 0 );

        // prepare notification
        void ( SAL_CALL XUndoManagerListener::*notificationMethod )( const UndoManagerEvent& ) = NULL;

        UndoManagerEvent aContextEvent( buildEvent( ::rtl::OUString() ) );
        const EventObject aClearedEvent( getXUndoManager() );
        if ( nContextElements == 0 )
        {
            notificationMethod = &XUndoManagerListener::cancelledContext;
        }
        else if ( isHiddenContext )
        {
            notificationMethod = &XUndoManagerListener::leftHiddenContext;
        }
        else
        {
            aContextEvent.UndoActionTitle = rUndoManager.GetUndoActionComment( 0, IUndoManager::CurrentLevel );
            notificationMethod = &XUndoManagerListener::leftContext;
        }

        aGuard.clear();
        // <--- SYNCHRONIZED

        if ( bHadRedoActions && !bHasRedoActions )
            m_aUndoListeners.notifyEach( &XUndoManagerListener::redoActionsCleared, aClearedEvent );
        m_aUndoListeners.notifyEach( notificationMethod, aContextEvent );
        impl_notifyModified();
    }

    //------------------------------------------------------------------------------------------------------------------
    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 );

        IUndoManager& rUndoManager = getUndoManager();
        if ( rUndoManager.IsInListAction() )
            throw UndoContextNotClosedException( ::rtl::OUString(), getXUndoManager() );

        const size_t nElements  =   i_undo
                                ?   rUndoManager.GetUndoActionCount( IUndoManager::TopLevel )
                                :   rUndoManager.GetRedoActionCount( IUndoManager::TopLevel );
        if ( nElements == 0 )
            throw EmptyUndoStackException( ::rtl::OUString::createFromAscii( "stack is empty" ), getXUndoManager() );

        aGuard.clear();
        // <--- SYNCHRONIZED

        try
        {
            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 );
        }

        // 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::impl_addUndoAction( const Reference< XUndoAction >& i_action )
    {
        // SYNCHRONIZED --->
        ::osl::ClearableMutexGuard aGuard( m_aMutex );

        IUndoManager& rUndoManager = getUndoManager();
        if ( !rUndoManager.IsUndoEnabled() )
            // ignore the request if the manager is locked
            return;

        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 );
        impl_notifyModified();
    }

    //------------------------------------------------------------------------------------------------------------------
    void UndoManagerHelper_Impl::impl_clear()
    {
        // SYNCHRONIZED --->
        ::osl::ClearableMutexGuard aGuard( m_aMutex );

        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 );
        impl_notifyModified();
    }

    //------------------------------------------------------------------------------------------------------------------
    void UndoManagerHelper_Impl::impl_clearRedo()
    {
        // SYNCHRONIZED --->
        ::osl::ClearableMutexGuard aGuard( m_aMutex );

        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 );
        impl_notifyModified();
    }

    //------------------------------------------------------------------------------------------------------------------
    void UndoManagerHelper_Impl::impl_reset()
    {
        // SYNCHRONIZED --->
        ::osl::ClearableMutexGuard aGuard( m_aMutex );

        IUndoManager& rUndoManager = getUndoManager();
        {
            ::comphelper::FlagGuard aNotificationGuard( m_bAPIActionRunning );
            rUndoManager.Reset();
        }

        const EventObject aEvent( getXUndoManager() );
        aGuard.clear();
        // <--- SYNCHRONIZED

        m_aUndoListeners.notifyEach( &XUndoManagerListener::resetAll, aEvent );
        impl_notifyModified();
    }

    //------------------------------------------------------------------------------------------------------------------
    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 );
        impl_notifyModified();
    }

 	//------------------------------------------------------------------------------------------------------------------
    void UndoManagerHelper_Impl::actionRedone( const String& i_actionComment )
    {
        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 );
        impl_notifyModified();
    }

 	//------------------------------------------------------------------------------------------------------------------
    void UndoManagerHelper_Impl::undoActionAdded( const String& i_actionComment )
    {
        if ( m_bAPIActionRunning )
            return;

        notify( i_actionComment, &XUndoManagerListener::undoActionAdded );
    }

 	//------------------------------------------------------------------------------------------------------------------
    void UndoManagerHelper_Impl::cleared()
    {
        if ( m_bAPIActionRunning )
            return;

        notify( &XUndoManagerListener::allActionsCleared );
    }

 	//------------------------------------------------------------------------------------------------------------------
    void UndoManagerHelper_Impl::clearedRedo()
    {
        if ( m_bAPIActionRunning )
            return;

        notify( &XUndoManagerListener::redoActionsCleared );
    }

 	//------------------------------------------------------------------------------------------------------------------
    void UndoManagerHelper_Impl::resetAll()
    {
        if ( m_bAPIActionRunning )
            return;

        notify( &XUndoManagerListener::resetAll );
    }

 	//------------------------------------------------------------------------------------------------------------------
    void UndoManagerHelper_Impl::listActionEntered( const String& i_comment )
    {
#if OSL_DEBUG_LEVEL > 0
        m_aContextAPIFlags.push( m_bAPIActionRunning );
#endif

        if ( m_bAPIActionRunning )
            return;

        notify( i_comment, &XUndoManagerListener::enteredContext );
    }

 	//------------------------------------------------------------------------------------------------------------------
    void UndoManagerHelper_Impl::listActionLeft( const String& i_comment )
    {
#if OSL_DEBUG_LEVEL > 0
        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 ( m_bAPIActionRunning )
            return;

        notify( i_comment, &XUndoManagerListener::leftContext );
    }

 	//------------------------------------------------------------------------------------------------------------------
    void UndoManagerHelper_Impl::listActionLeftAndMerged()
    {
#if OSL_DEBUG_LEVEL > 0
        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 ( m_bAPIActionRunning )
            return;

        notify( &XUndoManagerListener::leftHiddenContext );
    }

 	//------------------------------------------------------------------------------------------------------------------
    void UndoManagerHelper_Impl::listActionCancelled()
    {
#if OSL_DEBUG_LEVEL > 0
        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 ( m_bAPIActionRunning )
            return;

        notify( &XUndoManagerListener::cancelledContext );
    }

 	//------------------------------------------------------------------------------------------------------------------
    void UndoManagerHelper_Impl::undoManagerDying()
    {
        // TODO: do we need to care? Or is this the responsibility of our owner?
    }

	//==================================================================================================================
	//= UndoManagerHelper
	//==================================================================================================================
	//------------------------------------------------------------------------------------------------------------------
    UndoManagerHelper::UndoManagerHelper( IUndoManagerImplementation& i_undoManagerImpl )
        :m_pImpl( new UndoManagerHelper_Impl( *this, i_undoManagerImpl ) )
    {
    }

	//------------------------------------------------------------------------------------------------------------------
    UndoManagerHelper::~UndoManagerHelper()
    {
    }

	//------------------------------------------------------------------------------------------------------------------
    void UndoManagerHelper::disposing()
    {
        m_pImpl->disposing();
    }

    //------------------------------------------------------------------------------------------------------------------
    void UndoManagerHelper::enterUndoContext( const ::rtl::OUString& i_title, IMutexGuard& i_instanceLock )
    {
        m_pImpl->enterUndoContext( i_title, false, i_instanceLock );
    }

    //------------------------------------------------------------------------------------------------------------------
    void UndoManagerHelper::enterHiddenUndoContext( IMutexGuard& i_instanceLock )
    {
        m_pImpl->enterUndoContext( ::rtl::OUString(), true, i_instanceLock );
    }

    //------------------------------------------------------------------------------------------------------------------
    void UndoManagerHelper::leaveUndoContext( IMutexGuard& i_instanceLock )
    {
        m_pImpl->leaveUndoContext( i_instanceLock );
    }

    //------------------------------------------------------------------------------------------------------------------
    void UndoManagerHelper_Impl::undo( IMutexGuard& i_instanceLock )
    {
        impl_processRequest(
            ::boost::bind(
                &UndoManagerHelper_Impl::impl_doUndoRedo,
                this,
                ::boost::ref( i_instanceLock ),
                true
            ),
            i_instanceLock
        );
    }

    //------------------------------------------------------------------------------------------------------------------
    void UndoManagerHelper_Impl::redo( IMutexGuard& i_instanceLock )
    {
        impl_processRequest(
            ::boost::bind(
                &UndoManagerHelper_Impl::impl_doUndoRedo,
                this,
                ::boost::ref( i_instanceLock ),
                false
            ),
            i_instanceLock
        );
    }

    //------------------------------------------------------------------------------------------------------------------
    void UndoManagerHelper::addUndoAction( const Reference< XUndoAction >& i_action, IMutexGuard& 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
    }
    
    //------------------------------------------------------------------------------------------------------------------
    namespace
    {
        //..............................................................................................................
        ::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 size_t 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" ) ),
                    i_impl.getXUndoManager()
                );
            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 size_t nCount =   i_undo
                                ?   rUndoManager.GetUndoActionCount( IUndoManager::TopLevel )
                                :   rUndoManager.GetRedoActionCount( IUndoManager::TopLevel );

            Sequence< ::rtl::OUString > aTitles( nCount );
            for ( size_t i=0; i<nCount; ++i )
            {
                aTitles[i] =    i_undo
                            ?   rUndoManager.GetUndoActionComment( i, IUndoManager::TopLevel )
                            :   rUndoManager.GetRedoActionComment( i, IUndoManager::TopLevel );
            }
            return aTitles;
            // <--- SYNCHRONIZED
        }
    }

    //------------------------------------------------------------------------------------------------------------------
    ::rtl::OUString UndoManagerHelper::getCurrentUndoActionTitle() const
    {
        return lcl_getCurrentActionTitle( *m_pImpl, true );
    }
    
    //------------------------------------------------------------------------------------------------------------------
    ::rtl::OUString UndoManagerHelper::getCurrentRedoActionTitle() const
    {
        return lcl_getCurrentActionTitle( *m_pImpl, false );
    }
    
    //------------------------------------------------------------------------------------------------------------------
    Sequence< ::rtl::OUString > UndoManagerHelper::getAllUndoActionTitles() const
    {
        return lcl_getAllActionTitles( *m_pImpl, true );
    }
    
    //------------------------------------------------------------------------------------------------------------------
    Sequence< ::rtl::OUString > UndoManagerHelper::getAllRedoActionTitles() const
    {
        return lcl_getAllActionTitles( *m_pImpl, false );
    }

    //------------------------------------------------------------------------------------------------------------------
    void UndoManagerHelper::clear( IMutexGuard& i_instanceLock )
    {
        m_pImpl->clear( i_instanceLock );
    }

    //------------------------------------------------------------------------------------------------------------------
    void UndoManagerHelper::clearRedo( IMutexGuard& i_instanceLock )
    {
        m_pImpl->clearRedo( i_instanceLock );
    }

    //------------------------------------------------------------------------------------------------------------------
    void UndoManagerHelper::reset( IMutexGuard& i_instanceLock )
    {
        m_pImpl->reset( i_instanceLock );
    }

    //------------------------------------------------------------------------------------------------------------------
    void UndoManagerHelper::lock()
    {
        m_pImpl->lock();
    }

    //------------------------------------------------------------------------------------------------------------------
    void UndoManagerHelper::unlock()
    {
        m_pImpl->unlock();
    }

    //------------------------------------------------------------------------------------------------------------------
    ::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->addUndoManagerListener( i_listener );
    }

    //------------------------------------------------------------------------------------------------------------------
    void UndoManagerHelper::removeUndoManagerListener( const Reference< XUndoManagerListener >& i_listener )
    {
        if ( i_listener.is() )
            m_pImpl->removeUndoManagerListener( i_listener );
    }

    //------------------------------------------------------------------------------------------------------------------
    void UndoManagerHelper::addModifyListener( const Reference< XModifyListener >& i_listener )
    {
        if ( i_listener.is() )
            m_pImpl->addModifyListener( i_listener );
    }

    //------------------------------------------------------------------------------------------------------------------
    void UndoManagerHelper::removeModifyListener( const Reference< XModifyListener >& i_listener )
    {
        if ( i_listener.is() )
            m_pImpl->removeModifyListener( i_listener );
    }

//......................................................................................................................
} // namespace framework
//......................................................................................................................
