1*6d739b60SAndrew Rist /************************************************************** 2*6d739b60SAndrew Rist * 3*6d739b60SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4*6d739b60SAndrew Rist * or more contributor license agreements. See the NOTICE file 5*6d739b60SAndrew Rist * distributed with this work for additional information 6*6d739b60SAndrew Rist * regarding copyright ownership. The ASF licenses this file 7*6d739b60SAndrew Rist * to you under the Apache License, Version 2.0 (the 8*6d739b60SAndrew Rist * "License"); you may not use this file except in compliance 9*6d739b60SAndrew Rist * with the License. You may obtain a copy of the License at 10*6d739b60SAndrew Rist * 11*6d739b60SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12*6d739b60SAndrew Rist * 13*6d739b60SAndrew Rist * Unless required by applicable law or agreed to in writing, 14*6d739b60SAndrew Rist * software distributed under the License is distributed on an 15*6d739b60SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*6d739b60SAndrew Rist * KIND, either express or implied. See the License for the 17*6d739b60SAndrew Rist * specific language governing permissions and limitations 18*6d739b60SAndrew Rist * under the License. 19*6d739b60SAndrew Rist * 20*6d739b60SAndrew Rist *************************************************************/ 21*6d739b60SAndrew Rist 22*6d739b60SAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir #include "precompiled_framework.hxx" 25cdf0e10cSrcweir 26cdf0e10cSrcweir #include "framework/documentundoguard.hxx" 27cdf0e10cSrcweir 28cdf0e10cSrcweir /** === begin UNO includes === **/ 29cdf0e10cSrcweir #include <com/sun/star/document/XUndoManagerSupplier.hpp> 30cdf0e10cSrcweir /** === end UNO includes === **/ 31cdf0e10cSrcweir 32cdf0e10cSrcweir #include <cppuhelper/implbase1.hxx> 33cdf0e10cSrcweir #include <rtl/ref.hxx> 34cdf0e10cSrcweir #include <tools/diagnose_ex.h> 35cdf0e10cSrcweir 36cdf0e10cSrcweir //...................................................................................................................... 37cdf0e10cSrcweir namespace framework 38cdf0e10cSrcweir { 39cdf0e10cSrcweir //...................................................................................................................... 40cdf0e10cSrcweir 41cdf0e10cSrcweir /** === begin UNO using === **/ 42cdf0e10cSrcweir using ::com::sun::star::uno::Reference; 43cdf0e10cSrcweir using ::com::sun::star::uno::XInterface; 44cdf0e10cSrcweir using ::com::sun::star::uno::UNO_QUERY; 45cdf0e10cSrcweir using ::com::sun::star::uno::UNO_QUERY_THROW; 46cdf0e10cSrcweir using ::com::sun::star::uno::Exception; 47cdf0e10cSrcweir using ::com::sun::star::uno::RuntimeException; 48cdf0e10cSrcweir using ::com::sun::star::uno::Any; 49cdf0e10cSrcweir using ::com::sun::star::uno::makeAny; 50cdf0e10cSrcweir using ::com::sun::star::uno::Sequence; 51cdf0e10cSrcweir using ::com::sun::star::uno::Type; 52cdf0e10cSrcweir using ::com::sun::star::document::XUndoManagerSupplier; 53cdf0e10cSrcweir using ::com::sun::star::document::XUndoManager; 54cdf0e10cSrcweir using ::com::sun::star::document::XUndoManagerListener; 55cdf0e10cSrcweir using ::com::sun::star::document::UndoManagerEvent; 56cdf0e10cSrcweir using ::com::sun::star::lang::EventObject; 57cdf0e10cSrcweir /** === end UNO using === **/ 58cdf0e10cSrcweir 59cdf0e10cSrcweir //================================================================================================================== 60cdf0e10cSrcweir //= UndoManagerContextListener 61cdf0e10cSrcweir //================================================================================================================== 62cdf0e10cSrcweir typedef ::cppu::WeakImplHelper1 < XUndoManagerListener 63cdf0e10cSrcweir > UndoManagerContextListener_Base; 64cdf0e10cSrcweir class UndoManagerContextListener : public UndoManagerContextListener_Base 65cdf0e10cSrcweir { 66cdf0e10cSrcweir public: UndoManagerContextListener(const Reference<XUndoManager> & i_undoManager)67cdf0e10cSrcweir UndoManagerContextListener( const Reference< XUndoManager >& i_undoManager ) 68cdf0e10cSrcweir :m_xUndoManager( i_undoManager, UNO_QUERY_THROW ) 69cdf0e10cSrcweir ,m_nRelativeContextDepth( 0 ) 70cdf0e10cSrcweir ,m_documentDisposed( false ) 71cdf0e10cSrcweir { 72cdf0e10cSrcweir osl_incrementInterlockedCount( &m_refCount ); 73cdf0e10cSrcweir { 74cdf0e10cSrcweir m_xUndoManager->addUndoManagerListener( this ); 75cdf0e10cSrcweir } 76cdf0e10cSrcweir osl_decrementInterlockedCount( &m_refCount ); 77cdf0e10cSrcweir } 78cdf0e10cSrcweir UndoManagerContextListener()79cdf0e10cSrcweir UndoManagerContextListener() 80cdf0e10cSrcweir { 81cdf0e10cSrcweir } 82cdf0e10cSrcweir finish()83cdf0e10cSrcweir void finish() 84cdf0e10cSrcweir { 85cdf0e10cSrcweir OSL_ENSURE( m_nRelativeContextDepth >= 0, "UndoManagerContextListener: more contexts left than entered?" ); 86cdf0e10cSrcweir 87cdf0e10cSrcweir if ( m_documentDisposed ) 88cdf0e10cSrcweir return; 89cdf0e10cSrcweir 90cdf0e10cSrcweir // work with a copy of m_nRelativeContextDepth, to be independent from possible bugs in the 91cdf0e10cSrcweir // listener notifications (where it would be decremented with every leaveUndoContext) 92cdf0e10cSrcweir sal_Int32 nDepth = m_nRelativeContextDepth; 93cdf0e10cSrcweir while ( nDepth-- > 0 ) 94cdf0e10cSrcweir { 95cdf0e10cSrcweir m_xUndoManager->leaveUndoContext(); 96cdf0e10cSrcweir } 97cdf0e10cSrcweir m_xUndoManager->removeUndoManagerListener( this ); 98cdf0e10cSrcweir } 99cdf0e10cSrcweir 100cdf0e10cSrcweir // XUndoManagerListener 101cdf0e10cSrcweir virtual void SAL_CALL undoActionAdded( const UndoManagerEvent& i_event ) throw (RuntimeException); 102cdf0e10cSrcweir virtual void SAL_CALL actionUndone( const UndoManagerEvent& i_event ) throw (RuntimeException); 103cdf0e10cSrcweir virtual void SAL_CALL actionRedone( const UndoManagerEvent& i_event ) throw (RuntimeException); 104cdf0e10cSrcweir virtual void SAL_CALL allActionsCleared( const EventObject& i_event ) throw (RuntimeException); 105cdf0e10cSrcweir virtual void SAL_CALL redoActionsCleared( const EventObject& i_event ) throw (RuntimeException); 106cdf0e10cSrcweir virtual void SAL_CALL resetAll( const EventObject& i_event ) throw (RuntimeException); 107cdf0e10cSrcweir virtual void SAL_CALL enteredContext( const UndoManagerEvent& i_event ) throw (RuntimeException); 108cdf0e10cSrcweir virtual void SAL_CALL enteredHiddenContext( const UndoManagerEvent& i_event ) throw (RuntimeException); 109cdf0e10cSrcweir virtual void SAL_CALL leftContext( const UndoManagerEvent& i_event ) throw (RuntimeException); 110cdf0e10cSrcweir virtual void SAL_CALL leftHiddenContext( const UndoManagerEvent& i_event ) throw (RuntimeException); 111cdf0e10cSrcweir virtual void SAL_CALL cancelledContext( const UndoManagerEvent& i_event ) throw (RuntimeException); 112cdf0e10cSrcweir 113cdf0e10cSrcweir // XEventListener 114cdf0e10cSrcweir virtual void SAL_CALL disposing( const EventObject& i_event ) throw (RuntimeException); 115cdf0e10cSrcweir 116cdf0e10cSrcweir private: 117cdf0e10cSrcweir Reference< XUndoManager > const m_xUndoManager; 118cdf0e10cSrcweir oslInterlockedCount m_nRelativeContextDepth; 119cdf0e10cSrcweir bool m_documentDisposed; 120cdf0e10cSrcweir }; 121cdf0e10cSrcweir 122cdf0e10cSrcweir //------------------------------------------------------------------------------------------------------------------ undoActionAdded(const UndoManagerEvent & i_event)123cdf0e10cSrcweir void SAL_CALL UndoManagerContextListener::undoActionAdded( const UndoManagerEvent& i_event ) throw (RuntimeException) 124cdf0e10cSrcweir { 125cdf0e10cSrcweir (void)i_event; 126cdf0e10cSrcweir // not interested in 127cdf0e10cSrcweir } 128cdf0e10cSrcweir 129cdf0e10cSrcweir //------------------------------------------------------------------------------------------------------------------ actionUndone(const UndoManagerEvent & i_event)130cdf0e10cSrcweir void SAL_CALL UndoManagerContextListener::actionUndone( const UndoManagerEvent& i_event ) throw (RuntimeException) 131cdf0e10cSrcweir { 132cdf0e10cSrcweir (void)i_event; 133cdf0e10cSrcweir // not interested in 134cdf0e10cSrcweir } 135cdf0e10cSrcweir 136cdf0e10cSrcweir //------------------------------------------------------------------------------------------------------------------ actionRedone(const UndoManagerEvent & i_event)137cdf0e10cSrcweir void SAL_CALL UndoManagerContextListener::actionRedone( const UndoManagerEvent& i_event ) throw (RuntimeException) 138cdf0e10cSrcweir { 139cdf0e10cSrcweir (void)i_event; 140cdf0e10cSrcweir // not interested in 141cdf0e10cSrcweir } 142cdf0e10cSrcweir 143cdf0e10cSrcweir //------------------------------------------------------------------------------------------------------------------ allActionsCleared(const EventObject & i_event)144cdf0e10cSrcweir void SAL_CALL UndoManagerContextListener::allActionsCleared( const EventObject& i_event ) throw (RuntimeException) 145cdf0e10cSrcweir { 146cdf0e10cSrcweir (void)i_event; 147cdf0e10cSrcweir // not interested in 148cdf0e10cSrcweir } 149cdf0e10cSrcweir 150cdf0e10cSrcweir //------------------------------------------------------------------------------------------------------------------ redoActionsCleared(const EventObject & i_event)151cdf0e10cSrcweir void SAL_CALL UndoManagerContextListener::redoActionsCleared( const EventObject& i_event ) throw (RuntimeException) 152cdf0e10cSrcweir { 153cdf0e10cSrcweir (void)i_event; 154cdf0e10cSrcweir // not interested in 155cdf0e10cSrcweir } 156cdf0e10cSrcweir 157cdf0e10cSrcweir //------------------------------------------------------------------------------------------------------------------ resetAll(const EventObject & i_event)158cdf0e10cSrcweir void SAL_CALL UndoManagerContextListener::resetAll( const EventObject& i_event ) throw (RuntimeException) 159cdf0e10cSrcweir { 160cdf0e10cSrcweir (void)i_event; 161cdf0e10cSrcweir m_nRelativeContextDepth = 0; 162cdf0e10cSrcweir } 163cdf0e10cSrcweir 164cdf0e10cSrcweir //------------------------------------------------------------------------------------------------------------------ enteredContext(const UndoManagerEvent & i_event)165cdf0e10cSrcweir void SAL_CALL UndoManagerContextListener::enteredContext( const UndoManagerEvent& i_event ) throw (RuntimeException) 166cdf0e10cSrcweir { 167cdf0e10cSrcweir (void)i_event; 168cdf0e10cSrcweir osl_incrementInterlockedCount( &m_nRelativeContextDepth ); 169cdf0e10cSrcweir } 170cdf0e10cSrcweir 171cdf0e10cSrcweir //------------------------------------------------------------------------------------------------------------------ enteredHiddenContext(const UndoManagerEvent & i_event)172cdf0e10cSrcweir void SAL_CALL UndoManagerContextListener::enteredHiddenContext( const UndoManagerEvent& i_event ) throw (RuntimeException) 173cdf0e10cSrcweir { 174cdf0e10cSrcweir (void)i_event; 175cdf0e10cSrcweir osl_incrementInterlockedCount( &m_nRelativeContextDepth ); 176cdf0e10cSrcweir } 177cdf0e10cSrcweir 178cdf0e10cSrcweir //------------------------------------------------------------------------------------------------------------------ leftContext(const UndoManagerEvent & i_event)179cdf0e10cSrcweir void SAL_CALL UndoManagerContextListener::leftContext( const UndoManagerEvent& i_event ) throw (RuntimeException) 180cdf0e10cSrcweir { 181cdf0e10cSrcweir (void)i_event; 182cdf0e10cSrcweir osl_decrementInterlockedCount( &m_nRelativeContextDepth ); 183cdf0e10cSrcweir } 184cdf0e10cSrcweir 185cdf0e10cSrcweir //------------------------------------------------------------------------------------------------------------------ leftHiddenContext(const UndoManagerEvent & i_event)186cdf0e10cSrcweir void SAL_CALL UndoManagerContextListener::leftHiddenContext( const UndoManagerEvent& i_event ) throw (RuntimeException) 187cdf0e10cSrcweir { 188cdf0e10cSrcweir (void)i_event; 189cdf0e10cSrcweir osl_decrementInterlockedCount( &m_nRelativeContextDepth ); 190cdf0e10cSrcweir } 191cdf0e10cSrcweir 192cdf0e10cSrcweir //------------------------------------------------------------------------------------------------------------------ cancelledContext(const UndoManagerEvent & i_event)193cdf0e10cSrcweir void SAL_CALL UndoManagerContextListener::cancelledContext( const UndoManagerEvent& i_event ) throw (RuntimeException) 194cdf0e10cSrcweir { 195cdf0e10cSrcweir (void)i_event; 196cdf0e10cSrcweir osl_decrementInterlockedCount( &m_nRelativeContextDepth ); 197cdf0e10cSrcweir } 198cdf0e10cSrcweir 199cdf0e10cSrcweir //------------------------------------------------------------------------------------------------------------------ disposing(const EventObject & i_event)200cdf0e10cSrcweir void SAL_CALL UndoManagerContextListener::disposing( const EventObject& i_event ) throw (RuntimeException) 201cdf0e10cSrcweir { 202cdf0e10cSrcweir (void)i_event; 203cdf0e10cSrcweir m_documentDisposed = true; 204cdf0e10cSrcweir } 205cdf0e10cSrcweir 206cdf0e10cSrcweir //================================================================================================================== 207cdf0e10cSrcweir //= DocumentUndoGuard_Data 208cdf0e10cSrcweir //================================================================================================================== 209cdf0e10cSrcweir struct DocumentUndoGuard_Data 210cdf0e10cSrcweir { 211cdf0e10cSrcweir Reference< XUndoManager > xUndoManager; 212cdf0e10cSrcweir ::rtl::Reference< UndoManagerContextListener > pContextListener; 213cdf0e10cSrcweir }; 214cdf0e10cSrcweir 215cdf0e10cSrcweir namespace 216cdf0e10cSrcweir { 217cdf0e10cSrcweir //-------------------------------------------------------------------------------------------------------------- lcl_init(DocumentUndoGuard_Data & i_data,const Reference<XInterface> & i_undoSupplierComponent)218cdf0e10cSrcweir void lcl_init( DocumentUndoGuard_Data& i_data, const Reference< XInterface >& i_undoSupplierComponent ) 219cdf0e10cSrcweir { 220cdf0e10cSrcweir try 221cdf0e10cSrcweir { 222cdf0e10cSrcweir Reference< XUndoManagerSupplier > xUndoSupplier( i_undoSupplierComponent, UNO_QUERY ); 223cdf0e10cSrcweir if ( xUndoSupplier.is() ) 224cdf0e10cSrcweir i_data.xUndoManager.set( xUndoSupplier->getUndoManager(), UNO_QUERY_THROW ); 225cdf0e10cSrcweir 226cdf0e10cSrcweir if ( i_data.xUndoManager.is() ) 227cdf0e10cSrcweir i_data.pContextListener.set( new UndoManagerContextListener( i_data.xUndoManager ) ); 228cdf0e10cSrcweir } 229cdf0e10cSrcweir catch( const Exception& ) 230cdf0e10cSrcweir { 231cdf0e10cSrcweir DBG_UNHANDLED_EXCEPTION(); 232cdf0e10cSrcweir } 233cdf0e10cSrcweir } 234cdf0e10cSrcweir 235cdf0e10cSrcweir //-------------------------------------------------------------------------------------------------------------- lcl_restore(DocumentUndoGuard_Data & i_data)236cdf0e10cSrcweir void lcl_restore( DocumentUndoGuard_Data& i_data ) 237cdf0e10cSrcweir { 238cdf0e10cSrcweir try 239cdf0e10cSrcweir { 240cdf0e10cSrcweir if ( i_data.pContextListener.is() ) 241cdf0e10cSrcweir i_data.pContextListener->finish(); 242cdf0e10cSrcweir i_data.pContextListener.clear(); 243cdf0e10cSrcweir } 244cdf0e10cSrcweir catch( const Exception& ) 245cdf0e10cSrcweir { 246cdf0e10cSrcweir DBG_UNHANDLED_EXCEPTION(); 247cdf0e10cSrcweir } 248cdf0e10cSrcweir } 249cdf0e10cSrcweir } 250cdf0e10cSrcweir 251cdf0e10cSrcweir //================================================================================================================== 252cdf0e10cSrcweir //= DocumentUndoGuard 253cdf0e10cSrcweir //================================================================================================================== 254cdf0e10cSrcweir //------------------------------------------------------------------------------------------------------------------ DocumentUndoGuard(const Reference<XInterface> & i_undoSupplierComponent)255cdf0e10cSrcweir DocumentUndoGuard::DocumentUndoGuard( const Reference< XInterface >& i_undoSupplierComponent ) 256cdf0e10cSrcweir :m_pData( new DocumentUndoGuard_Data ) 257cdf0e10cSrcweir { 258cdf0e10cSrcweir lcl_init( *m_pData, i_undoSupplierComponent ); 259cdf0e10cSrcweir } 260cdf0e10cSrcweir ~DocumentUndoGuard()261cdf0e10cSrcweir DocumentUndoGuard::~DocumentUndoGuard() 262cdf0e10cSrcweir { 263cdf0e10cSrcweir lcl_restore( *m_pData ); 264cdf0e10cSrcweir } 265cdf0e10cSrcweir 266cdf0e10cSrcweir //...................................................................................................................... 267cdf0e10cSrcweir } // namespace framework 268cdf0e10cSrcweir //...................................................................................................................... 269