LCOV - code coverage report
Current view: top level - sfx2/source/doc - docundomanager.cxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 1 159 0.6 %
Date: 2014-04-14 Functions: 2 50 4.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : 
      21             : #include "docundomanager.hxx"
      22             : #include <sfx2/sfxbasemodel.hxx>
      23             : #include <sfx2/objsh.hxx>
      24             : #include <sfx2/viewfrm.hxx>
      25             : #include <sfx2/viewsh.hxx>
      26             : #include <sfx2/bindings.hxx>
      27             : 
      28             : #include <com/sun/star/lang/XComponent.hpp>
      29             : 
      30             : #include <comphelper/anytostring.hxx>
      31             : #include <comphelper/flagguard.hxx>
      32             : #include <svl/undo.hxx>
      33             : #include <tools/diagnose_ex.h>
      34             : #include <framework/undomanagerhelper.hxx>
      35             : 
      36             : #include <boost/noncopyable.hpp>
      37             : #include <stack>
      38             : 
      39             : 
      40             : namespace sfx2
      41             : {
      42             : 
      43             : 
      44             :     using ::com::sun::star::uno::Reference;
      45             :     using ::com::sun::star::uno::XInterface;
      46             :     using ::com::sun::star::uno::UNO_QUERY;
      47             :     using ::com::sun::star::uno::UNO_QUERY_THROW;
      48             :     using ::com::sun::star::uno::UNO_SET_THROW;
      49             :     using ::com::sun::star::uno::Exception;
      50             :     using ::com::sun::star::uno::RuntimeException;
      51             :     using ::com::sun::star::uno::Any;
      52             :     using ::com::sun::star::uno::makeAny;
      53             :     using ::com::sun::star::uno::Sequence;
      54             :     using ::com::sun::star::uno::Type;
      55             :     using ::com::sun::star::util::InvalidStateException;
      56             :     using ::com::sun::star::document::EmptyUndoStackException;
      57             :     using ::com::sun::star::util::NotLockedException;
      58             :     using ::com::sun::star::document::UndoContextNotClosedException;
      59             :     using ::com::sun::star::document::XUndoAction;
      60             :     using ::com::sun::star::document::XUndoManagerSupplier;
      61             :     using ::com::sun::star::lang::XComponent;
      62             :     using ::com::sun::star::lang::IllegalArgumentException;
      63             :     using ::com::sun::star::lang::NotInitializedException;
      64             :     using ::com::sun::star::lang::EventObject;
      65             :     using ::com::sun::star::document::UndoManagerEvent;
      66             :     using ::com::sun::star::document::XUndoManagerListener;
      67             :     using ::com::sun::star::document::UndoFailedException;
      68             :     using ::com::sun::star::document::XUndoManager;
      69             :     using ::com::sun::star::lang::NoSupportException;
      70             :     using ::com::sun::star::frame::XModel;
      71             : 
      72             :     using ::svl::IUndoManager;
      73             : 
      74             : 
      75             :     //= DocumentUndoManager_Impl
      76             : 
      77             :     struct DocumentUndoManager_Impl : public ::framework::IUndoManagerImplementation
      78             :     {
      79             :         DocumentUndoManager&                rAntiImpl;
      80             :         IUndoManager*                       pUndoManager;
      81             :         ::framework::UndoManagerHelper      aUndoHelper;
      82             : 
      83           0 :         DocumentUndoManager_Impl( DocumentUndoManager& i_antiImpl )
      84             :             :rAntiImpl( i_antiImpl )
      85           0 :             ,pUndoManager( impl_retrieveUndoManager( i_antiImpl.getBaseModel() ) )
      86             :                 // do this *before* the construction of aUndoHelper (which actually means: put pUndoManager before
      87             :                 // aUndoHelper in the member list)!
      88           0 :             ,aUndoHelper( *this )
      89             :         {
      90           0 :         }
      91             : 
      92           0 :         virtual ~DocumentUndoManager_Impl()
      93           0 :         {
      94           0 :         };
      95             : 
      96           0 :               SfxObjectShell* getObjectShell()       { return rAntiImpl.getBaseModel().GetObjectShell(); }
      97             : 
      98             :         // IUndoManagerImplementation
      99             :         virtual ::svl::IUndoManager&        getImplUndoManager() SAL_OVERRIDE;
     100             :         virtual Reference< XUndoManager >   getThis() SAL_OVERRIDE;
     101             : 
     102           0 :         void disposing()
     103             :         {
     104           0 :             aUndoHelper.disposing();
     105           0 :             ENSURE_OR_RETURN_VOID( pUndoManager, "DocumentUndoManager_Impl::disposing: already disposed!" );
     106           0 :             pUndoManager = NULL;
     107             :         }
     108             : 
     109             :         void invalidateXDo_nolck();
     110             : 
     111             :     private:
     112           0 :         static IUndoManager* impl_retrieveUndoManager( SfxBaseModel& i_baseModel )
     113             :         {
     114           0 :             IUndoManager* pUndoManager( NULL );
     115           0 :             SfxObjectShell* pObjectShell = i_baseModel.GetObjectShell();
     116           0 :             if ( pObjectShell != NULL )
     117           0 :                 pUndoManager = pObjectShell->GetUndoManager();
     118           0 :             if ( !pUndoManager )
     119           0 :                 throw NotInitializedException( OUString(), *&i_baseModel );
     120           0 :             return pUndoManager;
     121             :         }
     122             :     };
     123             : 
     124             : 
     125           0 :     ::svl::IUndoManager& DocumentUndoManager_Impl::getImplUndoManager()
     126             :     {
     127           0 :         ENSURE_OR_THROW( pUndoManager != NULL, "DocumentUndoManager_Impl::getImplUndoManager: no access to the doc's UndoManager implementation!" );
     128             : 
     129             : #if OSL_DEBUG_LEVEL > 0
     130             :         // in a non-product build, assert if the current UndoManager at the shell is not the same we obtained
     131             :         // (and cached) at construction time
     132             :         SfxObjectShell* pObjectShell = rAntiImpl.getBaseModel().GetObjectShell();
     133             :         OSL_ENSURE( ( pObjectShell != NULL ) && ( pUndoManager == pObjectShell->GetUndoManager() ),
     134             :             "DocumentUndoManager_Impl::getImplUndoManager: the UndoManager changed meanwhile - what about our listener?" );
     135             : #endif
     136             : 
     137           0 :         return *pUndoManager;
     138             :     }
     139             : 
     140             : 
     141           0 :     Reference< XUndoManager > DocumentUndoManager_Impl::getThis()
     142             :     {
     143           0 :         return static_cast< XUndoManager* >( &rAntiImpl );
     144             :     }
     145             : 
     146             : 
     147           0 :     void DocumentUndoManager_Impl::invalidateXDo_nolck()
     148             :     {
     149           0 :         SfxModelGuard aGuard( rAntiImpl );
     150             : 
     151           0 :         const SfxObjectShell* pDocShell = getObjectShell();
     152           0 :         ENSURE_OR_THROW( pDocShell != NULL, "lcl_invalidateUndo: no access to the doc shell!" );
     153           0 :         SfxViewFrame* pViewFrame = SfxViewFrame::GetFirst( pDocShell );
     154           0 :         while ( pViewFrame )
     155             :         {
     156           0 :             pViewFrame->GetBindings().Invalidate( SID_UNDO );
     157           0 :             pViewFrame->GetBindings().Invalidate( SID_REDO );
     158           0 :             pViewFrame = SfxViewFrame::GetNext( *pViewFrame, pDocShell );
     159           0 :         }
     160           0 :     }
     161             : 
     162             : 
     163             :     //= SolarMutexFacade
     164             : 
     165             :     /** a facade for the SolarMutex, implementing ::framework::IMutex (as opposed to ::vos::IMutex)
     166             :     */
     167             :     class SolarMutexFacade : public ::framework::IMutex
     168             :     {
     169             :     public:
     170           0 :         SolarMutexFacade()
     171           0 :         {
     172           0 :         }
     173             : 
     174           0 :         virtual ~SolarMutexFacade() {}
     175             : 
     176           0 :         virtual void acquire() SAL_OVERRIDE
     177             :         {
     178           0 :             Application::GetSolarMutex().acquire();
     179           0 :         }
     180             : 
     181           0 :         virtual void release() SAL_OVERRIDE
     182             :         {
     183           0 :             Application::GetSolarMutex().release();
     184           0 :         }
     185             :     };
     186             : 
     187             : 
     188             :     //= UndoManagerGuard
     189             : 
     190             :     class UndoManagerGuard  :public ::framework::IMutexGuard
     191             :                             ,public ::boost::noncopyable
     192             :     {
     193             :     public:
     194           0 :         UndoManagerGuard( DocumentUndoManager& i_undoManager )
     195             :             :m_guard( i_undoManager )
     196           0 :             ,m_solarMutexFacade()
     197             :         {
     198           0 :         }
     199             : 
     200           0 :         virtual ~UndoManagerGuard()
     201           0 :         {
     202           0 :         }
     203             : 
     204           0 :         virtual void clear() SAL_OVERRIDE
     205             :         {
     206           0 :             m_guard.clear();
     207           0 :         }
     208             : 
     209           0 :         virtual ::framework::IMutex& getGuardedMutex() SAL_OVERRIDE
     210             :         {
     211             :             // note that this means that we *know* that SfxModelGuard also locks the SolarMutex (nothing more, nothing less).
     212             :             // If this ever changes, we need to adjust this code here, too.
     213           0 :             return m_solarMutexFacade;
     214             :         }
     215             : 
     216             :     private:
     217             :         SfxModelGuard       m_guard;
     218             :         SolarMutexFacade    m_solarMutexFacade;
     219             :     };
     220             : 
     221             : 
     222             :     //= DocumentUndoManager
     223             : 
     224             : 
     225           0 :     DocumentUndoManager::DocumentUndoManager( SfxBaseModel& i_document )
     226             :         :SfxModelSubComponent( i_document )
     227           0 :         ,m_pImpl( new DocumentUndoManager_Impl( *this ) )
     228             :     {
     229           0 :     }
     230             : 
     231             : 
     232           0 :     DocumentUndoManager::~DocumentUndoManager()
     233             :     {
     234           0 :     }
     235             : 
     236             : 
     237           0 :     void DocumentUndoManager::disposing()
     238             :     {
     239           0 :         m_pImpl->disposing();
     240           0 :     }
     241             : 
     242             : 
     243           0 :     bool DocumentUndoManager::isInContext() const
     244             :     {
     245             :         // No mutex locking within this method, no disposal check - this is the responsibility of the owner.
     246           0 :         return m_pImpl->getImplUndoManager().IsInListAction();
     247             :     }
     248             : 
     249             : 
     250           0 :     void SAL_CALL DocumentUndoManager::acquire(  ) throw ()
     251             :     {
     252           0 :         SfxModelSubComponent::acquire();
     253           0 :     }
     254             : 
     255             : 
     256           0 :     void SAL_CALL DocumentUndoManager::release(  ) throw ()
     257             :     {
     258           0 :         SfxModelSubComponent::release();
     259           0 :     }
     260             : 
     261             : 
     262           0 :     void SAL_CALL DocumentUndoManager::enterUndoContext( const OUString& i_title ) throw (RuntimeException, std::exception)
     263             :     {
     264             :         // SYNCHRONIZED --->
     265           0 :         UndoManagerGuard aGuard( *this );
     266           0 :         m_pImpl->aUndoHelper.enterUndoContext( i_title, aGuard );
     267             :         // <--- SYNCHRONIZED
     268           0 :         m_pImpl->invalidateXDo_nolck();
     269           0 :     }
     270             : 
     271             : 
     272           0 :     void SAL_CALL DocumentUndoManager::enterHiddenUndoContext(  ) throw (EmptyUndoStackException, RuntimeException, std::exception)
     273             :     {
     274             :         // SYNCHRONIZED --->
     275           0 :         UndoManagerGuard aGuard( *this );
     276           0 :         m_pImpl->aUndoHelper.enterHiddenUndoContext( aGuard );
     277             :         // <--- SYNCHRONIZED
     278           0 :         m_pImpl->invalidateXDo_nolck();
     279           0 :     }
     280             : 
     281             : 
     282           0 :     void SAL_CALL DocumentUndoManager::leaveUndoContext(  ) throw (InvalidStateException, RuntimeException, std::exception)
     283             :     {
     284             :         // SYNCHRONIZED --->
     285           0 :         UndoManagerGuard aGuard( *this );
     286           0 :         m_pImpl->aUndoHelper.leaveUndoContext( aGuard );
     287             :         // <--- SYNCHRONIZED
     288           0 :         m_pImpl->invalidateXDo_nolck();
     289           0 :     }
     290             : 
     291             : 
     292           0 :     void SAL_CALL DocumentUndoManager::addUndoAction( const Reference< XUndoAction >& i_action ) throw (RuntimeException, IllegalArgumentException, std::exception)
     293             :     {
     294             :         // SYNCHRONIZED --->
     295           0 :         UndoManagerGuard aGuard( *this );
     296           0 :         m_pImpl->aUndoHelper.addUndoAction( i_action, aGuard );
     297             :         // <--- SYNCHRONIZED
     298           0 :         m_pImpl->invalidateXDo_nolck();
     299           0 :     }
     300             : 
     301             : 
     302           0 :     void SAL_CALL DocumentUndoManager::undo(  ) throw (EmptyUndoStackException, UndoContextNotClosedException, UndoFailedException, RuntimeException, std::exception)
     303             :     {
     304             :         // SYNCHRONIZED --->
     305           0 :         UndoManagerGuard aGuard( *this );
     306           0 :         m_pImpl->aUndoHelper.undo( aGuard );
     307             :         // <--- SYNCHRONIZED
     308           0 :         m_pImpl->invalidateXDo_nolck();
     309           0 :     }
     310             : 
     311             : 
     312           0 :     void SAL_CALL DocumentUndoManager::redo(  ) throw (EmptyUndoStackException, UndoContextNotClosedException, UndoFailedException, RuntimeException, std::exception)
     313             :     {
     314             :         // SYNCHRONIZED --->
     315           0 :         UndoManagerGuard aGuard( *this );
     316           0 :         m_pImpl->aUndoHelper.redo( aGuard );
     317             :         // <--- SYNCHRONIZED
     318           0 :         m_pImpl->invalidateXDo_nolck();
     319           0 :     }
     320             : 
     321             : 
     322           0 :     sal_Bool SAL_CALL DocumentUndoManager::isUndoPossible(  ) throw (RuntimeException, std::exception)
     323             :     {
     324           0 :         UndoManagerGuard aGuard( *this );
     325           0 :         return m_pImpl->aUndoHelper.isUndoPossible();
     326             :     }
     327             : 
     328             : 
     329           0 :     sal_Bool SAL_CALL DocumentUndoManager::isRedoPossible(  ) throw (RuntimeException, std::exception)
     330             :     {
     331           0 :         UndoManagerGuard aGuard( *this );
     332           0 :         return m_pImpl->aUndoHelper.isRedoPossible();
     333             :     }
     334             : 
     335             : 
     336           0 :     OUString SAL_CALL DocumentUndoManager::getCurrentUndoActionTitle(  ) throw (EmptyUndoStackException, RuntimeException, std::exception)
     337             :     {
     338           0 :         UndoManagerGuard aGuard( *this );
     339           0 :         return m_pImpl->aUndoHelper.getCurrentUndoActionTitle();
     340             :     }
     341             : 
     342             : 
     343           0 :     OUString SAL_CALL DocumentUndoManager::getCurrentRedoActionTitle(  ) throw (EmptyUndoStackException, RuntimeException, std::exception)
     344             :     {
     345           0 :         UndoManagerGuard aGuard( *this );
     346           0 :         return m_pImpl->aUndoHelper.getCurrentRedoActionTitle();
     347             :     }
     348             : 
     349             : 
     350           0 :     Sequence< OUString > SAL_CALL DocumentUndoManager::getAllUndoActionTitles(  ) throw (RuntimeException, std::exception)
     351             :     {
     352           0 :         UndoManagerGuard aGuard( *this );
     353           0 :         return m_pImpl->aUndoHelper.getAllUndoActionTitles();
     354             :     }
     355             : 
     356             : 
     357           0 :     Sequence< OUString > SAL_CALL DocumentUndoManager::getAllRedoActionTitles(  ) throw (RuntimeException, std::exception)
     358             :     {
     359           0 :         UndoManagerGuard aGuard( *this );
     360           0 :         return m_pImpl->aUndoHelper.getAllRedoActionTitles();
     361             :     }
     362             : 
     363             : 
     364           0 :     void SAL_CALL DocumentUndoManager::clear(  ) throw (UndoContextNotClosedException, RuntimeException, std::exception)
     365             :     {
     366             :         // SYNCHRONIZED --->
     367           0 :         UndoManagerGuard aGuard( *this );
     368           0 :         m_pImpl->aUndoHelper.clear( aGuard );
     369             :         // <--- SYNCHRONIZED
     370           0 :         m_pImpl->invalidateXDo_nolck();
     371           0 :     }
     372             : 
     373             : 
     374           0 :     void SAL_CALL DocumentUndoManager::clearRedo(  ) throw (UndoContextNotClosedException, RuntimeException, std::exception)
     375             :     {
     376             :         // SYNCHRONIZED --->
     377           0 :         UndoManagerGuard aGuard( *this );
     378           0 :         m_pImpl->aUndoHelper.clearRedo( aGuard );
     379             :         // <--- SYNCHRONIZED
     380           0 :         m_pImpl->invalidateXDo_nolck();
     381           0 :     }
     382             : 
     383             : 
     384           0 :     void SAL_CALL DocumentUndoManager::reset() throw (RuntimeException, std::exception)
     385             :     {
     386             :         // SYNCHRONIZED --->
     387           0 :         UndoManagerGuard aGuard( *this );
     388           0 :         m_pImpl->aUndoHelper.reset( aGuard );
     389             :         // <--- SYNCHRONIZED
     390           0 :         m_pImpl->invalidateXDo_nolck();
     391           0 :     }
     392             : 
     393             : 
     394           0 :     void SAL_CALL DocumentUndoManager::lock(  ) throw (RuntimeException, std::exception)
     395             :     {
     396           0 :         UndoManagerGuard aGuard( *this );
     397           0 :         m_pImpl->aUndoHelper.lock();
     398           0 :     }
     399             : 
     400             : 
     401           0 :     void SAL_CALL DocumentUndoManager::unlock(  ) throw (RuntimeException, NotLockedException, std::exception)
     402             :     {
     403           0 :         UndoManagerGuard aGuard( *this );
     404           0 :         m_pImpl->aUndoHelper.unlock();
     405           0 :     }
     406             : 
     407             : 
     408           0 :     sal_Bool SAL_CALL DocumentUndoManager::isLocked(  ) throw (RuntimeException, std::exception)
     409             :     {
     410           0 :         UndoManagerGuard aGuard( *this );
     411           0 :         return m_pImpl->aUndoHelper.isLocked();
     412             :     }
     413             : 
     414             : 
     415           0 :     void SAL_CALL DocumentUndoManager::addUndoManagerListener( const Reference< XUndoManagerListener >& i_listener ) throw (RuntimeException, std::exception)
     416             :     {
     417           0 :         UndoManagerGuard aGuard( *this );
     418           0 :         return m_pImpl->aUndoHelper.addUndoManagerListener( i_listener );
     419             :     }
     420             : 
     421             : 
     422           0 :     void SAL_CALL DocumentUndoManager::removeUndoManagerListener( const Reference< XUndoManagerListener >& i_listener ) throw (RuntimeException, std::exception)
     423             :     {
     424           0 :         UndoManagerGuard aGuard( *this );
     425           0 :         return m_pImpl->aUndoHelper.removeUndoManagerListener( i_listener );
     426             :     }
     427             : 
     428             : 
     429           0 :     Reference< XInterface > SAL_CALL DocumentUndoManager::getParent(  ) throw (RuntimeException, std::exception)
     430             :     {
     431           0 :         UndoManagerGuard aGuard( *this );
     432           0 :         return static_cast< XModel* >( &getBaseModel() );
     433             :     }
     434             : 
     435             : 
     436           0 :     void SAL_CALL DocumentUndoManager::setParent( const Reference< XInterface >& i_parent ) throw (NoSupportException, RuntimeException, std::exception)
     437             :     {
     438             :         (void)i_parent;
     439           0 :         throw NoSupportException( OUString(), m_pImpl->getThis() );
     440             :     }
     441             : 
     442             : 
     443           3 : } // namespace sfx2
     444             : 
     445             : 
     446             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10