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

Generated by: LCOV version 1.10