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

Generated by: LCOV version 1.10