1*b5088357SAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3*b5088357SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4*b5088357SAndrew Rist * or more contributor license agreements. See the NOTICE file 5*b5088357SAndrew Rist * distributed with this work for additional information 6*b5088357SAndrew Rist * regarding copyright ownership. The ASF licenses this file 7*b5088357SAndrew Rist * to you under the Apache License, Version 2.0 (the 8*b5088357SAndrew Rist * "License"); you may not use this file except in compliance 9*b5088357SAndrew Rist * with the License. You may obtain a copy of the License at 10*b5088357SAndrew Rist * 11*b5088357SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12*b5088357SAndrew Rist * 13*b5088357SAndrew Rist * Unless required by applicable law or agreed to in writing, 14*b5088357SAndrew Rist * software distributed under the License is distributed on an 15*b5088357SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*b5088357SAndrew Rist * KIND, either express or implied. See the License for the 17*b5088357SAndrew Rist * specific language governing permissions and limitations 18*b5088357SAndrew Rist * under the License. 19*b5088357SAndrew Rist * 20*b5088357SAndrew Rist *************************************************************/ 21*b5088357SAndrew Rist 22*b5088357SAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 25cdf0e10cSrcweir #include "precompiled_unotools.hxx" 26cdf0e10cSrcweir #include <unotools/desktopterminationobserver.hxx> 27cdf0e10cSrcweir 28cdf0e10cSrcweir /** === begin UNO includes === **/ 29cdf0e10cSrcweir #include <com/sun/star/frame/XTerminateListener.hpp> 30cdf0e10cSrcweir #include <com/sun/star/frame/XDesktop.hpp> 31cdf0e10cSrcweir /** === end UNO includes === **/ 32cdf0e10cSrcweir #include <cppuhelper/implbase1.hxx> 33cdf0e10cSrcweir #include <comphelper/processfactory.hxx> 34cdf0e10cSrcweir 35cdf0e10cSrcweir #include <list> 36cdf0e10cSrcweir 37cdf0e10cSrcweir //........................................................................ 38cdf0e10cSrcweir namespace utl 39cdf0e10cSrcweir { 40cdf0e10cSrcweir //........................................................................ 41cdf0e10cSrcweir 42cdf0e10cSrcweir using namespace ::com::sun::star::uno; 43cdf0e10cSrcweir using namespace ::com::sun::star::lang; 44cdf0e10cSrcweir using namespace ::com::sun::star::frame; 45cdf0e10cSrcweir 46cdf0e10cSrcweir namespace 47cdf0e10cSrcweir { 48cdf0e10cSrcweir //................................................................ 49cdf0e10cSrcweir typedef ::std::list< ITerminationListener* > Listeners; 50cdf0e10cSrcweir 51cdf0e10cSrcweir struct ListenerAdminData 52cdf0e10cSrcweir { 53cdf0e10cSrcweir Listeners aListeners; 54cdf0e10cSrcweir bool bAlreadyTerminated; 55cdf0e10cSrcweir bool bCreatedAdapter; 56cdf0e10cSrcweir ListenerAdminDatautl::__anond378dcb00111::ListenerAdminData57cdf0e10cSrcweir ListenerAdminData() : bAlreadyTerminated( false ), bCreatedAdapter( false ) { } 58cdf0e10cSrcweir }; 59cdf0e10cSrcweir 60cdf0e10cSrcweir //................................................................ getListenerAdminData()61cdf0e10cSrcweir ListenerAdminData& getListenerAdminData() 62cdf0e10cSrcweir { 63cdf0e10cSrcweir static ListenerAdminData s_aData; 64cdf0e10cSrcweir return s_aData; 65cdf0e10cSrcweir } 66cdf0e10cSrcweir 67cdf0e10cSrcweir //================================================================ 68cdf0e10cSrcweir //= OObserverImpl 69cdf0e10cSrcweir //================================================================ 70cdf0e10cSrcweir class OObserverImpl : public ::cppu::WeakImplHelper1< XTerminateListener > 71cdf0e10cSrcweir { 72cdf0e10cSrcweir public: 73cdf0e10cSrcweir static void ensureObservation(); 74cdf0e10cSrcweir 75cdf0e10cSrcweir protected: 76cdf0e10cSrcweir OObserverImpl(); 77cdf0e10cSrcweir ~OObserverImpl(); 78cdf0e10cSrcweir 79cdf0e10cSrcweir private: 80cdf0e10cSrcweir // XTerminateListener 81cdf0e10cSrcweir virtual void SAL_CALL queryTermination( const EventObject& Event ) throw (TerminationVetoException, RuntimeException); 82cdf0e10cSrcweir virtual void SAL_CALL notifyTermination( const EventObject& Event ) throw (RuntimeException); 83cdf0e10cSrcweir 84cdf0e10cSrcweir // XEventListener 85cdf0e10cSrcweir virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw (::com::sun::star::uno::RuntimeException); 86cdf0e10cSrcweir }; 87cdf0e10cSrcweir 88cdf0e10cSrcweir //-------------------------------------------------------------------- OObserverImpl()89cdf0e10cSrcweir OObserverImpl::OObserverImpl() 90cdf0e10cSrcweir { 91cdf0e10cSrcweir } 92cdf0e10cSrcweir 93cdf0e10cSrcweir //-------------------------------------------------------------------- ~OObserverImpl()94cdf0e10cSrcweir OObserverImpl::~OObserverImpl() 95cdf0e10cSrcweir { 96cdf0e10cSrcweir } 97cdf0e10cSrcweir 98cdf0e10cSrcweir //-------------------------------------------------------------------- ensureObservation()99cdf0e10cSrcweir void OObserverImpl::ensureObservation() 100cdf0e10cSrcweir { 101cdf0e10cSrcweir { 102cdf0e10cSrcweir if ( getListenerAdminData().bCreatedAdapter ) 103cdf0e10cSrcweir return; 104cdf0e10cSrcweir ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ); 105cdf0e10cSrcweir if ( getListenerAdminData().bCreatedAdapter ) 106cdf0e10cSrcweir return; 107cdf0e10cSrcweir 108cdf0e10cSrcweir getListenerAdminData().bCreatedAdapter = true; 109cdf0e10cSrcweir } 110cdf0e10cSrcweir 111cdf0e10cSrcweir try 112cdf0e10cSrcweir { 113cdf0e10cSrcweir Reference< XDesktop > xDesktop; 114cdf0e10cSrcweir xDesktop = xDesktop.query( ::comphelper::getProcessServiceFactory()->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.frame.Desktop" ) ) ) ); 115cdf0e10cSrcweir OSL_ENSURE( xDesktop.is(), "OObserverImpl::ensureObservation: could not ensureObservation the desktop!" ); 116cdf0e10cSrcweir if ( xDesktop.is() ) 117cdf0e10cSrcweir xDesktop->addTerminateListener( new OObserverImpl ); 118cdf0e10cSrcweir } 119cdf0e10cSrcweir catch( const Exception& ) 120cdf0e10cSrcweir { 121cdf0e10cSrcweir OSL_ENSURE( sal_False, "OObserverImpl::ensureObservation: caught an exception!" ); 122cdf0e10cSrcweir } 123cdf0e10cSrcweir } 124cdf0e10cSrcweir 125cdf0e10cSrcweir //-------------------------------------------------------------------- queryTermination(const EventObject &)126cdf0e10cSrcweir void SAL_CALL OObserverImpl::queryTermination( const EventObject& /*Event*/ ) throw (TerminationVetoException, RuntimeException) 127cdf0e10cSrcweir { 128cdf0e10cSrcweir Listeners aToNotify; 129cdf0e10cSrcweir { 130cdf0e10cSrcweir ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ); 131cdf0e10cSrcweir aToNotify = getListenerAdminData().aListeners; 132cdf0e10cSrcweir } 133cdf0e10cSrcweir 134cdf0e10cSrcweir for ( Listeners::const_iterator listener = aToNotify.begin(); 135cdf0e10cSrcweir listener != aToNotify.end(); 136cdf0e10cSrcweir ++listener 137cdf0e10cSrcweir ) 138cdf0e10cSrcweir { 139cdf0e10cSrcweir if ( !(*listener)->queryTermination() ) 140cdf0e10cSrcweir throw TerminationVetoException(); 141cdf0e10cSrcweir } 142cdf0e10cSrcweir } 143cdf0e10cSrcweir 144cdf0e10cSrcweir //-------------------------------------------------------------------- notifyTermination(const EventObject &)145cdf0e10cSrcweir void SAL_CALL OObserverImpl::notifyTermination( const EventObject& /*Event*/ ) throw (RuntimeException) 146cdf0e10cSrcweir { 147cdf0e10cSrcweir // get the listeners 148cdf0e10cSrcweir Listeners aToNotify; 149cdf0e10cSrcweir { 150cdf0e10cSrcweir ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ); 151cdf0e10cSrcweir OSL_ENSURE( !getListenerAdminData().bAlreadyTerminated, "OObserverImpl::notifyTermination: terminated twice?" ); 152cdf0e10cSrcweir aToNotify = getListenerAdminData().aListeners; 153cdf0e10cSrcweir getListenerAdminData().bAlreadyTerminated = true; 154cdf0e10cSrcweir } 155cdf0e10cSrcweir 156cdf0e10cSrcweir // notify the listeners 157cdf0e10cSrcweir for ( Listeners::const_iterator listener = aToNotify.begin(); 158cdf0e10cSrcweir listener != aToNotify.end(); 159cdf0e10cSrcweir ++listener 160cdf0e10cSrcweir ) 161cdf0e10cSrcweir { 162cdf0e10cSrcweir (*listener)->notifyTermination(); 163cdf0e10cSrcweir } 164cdf0e10cSrcweir 165cdf0e10cSrcweir // clear the listener container 166cdf0e10cSrcweir { 167cdf0e10cSrcweir ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ); 168cdf0e10cSrcweir getListenerAdminData().aListeners.clear(); 169cdf0e10cSrcweir } 170cdf0e10cSrcweir } 171cdf0e10cSrcweir 172cdf0e10cSrcweir //-------------------------------------------------------------------- disposing(const EventObject &)173cdf0e10cSrcweir void SAL_CALL OObserverImpl::disposing( const EventObject& /*Event*/ ) throw (RuntimeException) 174cdf0e10cSrcweir { 175cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 0 176cdf0e10cSrcweir ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ); 177cdf0e10cSrcweir OSL_ENSURE( getListenerAdminData().bAlreadyTerminated, "OObserverImpl::disposing: disposing without terminated?" ); 178cdf0e10cSrcweir #endif 179cdf0e10cSrcweir // not interested in 180cdf0e10cSrcweir } 181cdf0e10cSrcweir } 182cdf0e10cSrcweir 183cdf0e10cSrcweir //==================================================================== 184cdf0e10cSrcweir //= DesktopTerminationObserver 185cdf0e10cSrcweir //==================================================================== 186cdf0e10cSrcweir //-------------------------------------------------------------------- registerTerminationListener(ITerminationListener * _pListener)187cdf0e10cSrcweir void DesktopTerminationObserver::registerTerminationListener( ITerminationListener* _pListener ) 188cdf0e10cSrcweir { 189cdf0e10cSrcweir if ( !_pListener ) 190cdf0e10cSrcweir return; 191cdf0e10cSrcweir 192cdf0e10cSrcweir { 193cdf0e10cSrcweir ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ); 194cdf0e10cSrcweir if ( getListenerAdminData().bAlreadyTerminated ) 195cdf0e10cSrcweir { 196cdf0e10cSrcweir _pListener->notifyTermination(); 197cdf0e10cSrcweir return; 198cdf0e10cSrcweir } 199cdf0e10cSrcweir 200cdf0e10cSrcweir getListenerAdminData().aListeners.push_back( _pListener ); 201cdf0e10cSrcweir } 202cdf0e10cSrcweir 203cdf0e10cSrcweir OObserverImpl::ensureObservation(); 204cdf0e10cSrcweir } 205cdf0e10cSrcweir 206cdf0e10cSrcweir //-------------------------------------------------------------------- revokeTerminationListener(ITerminationListener * _pListener)207cdf0e10cSrcweir void DesktopTerminationObserver::revokeTerminationListener( ITerminationListener* _pListener ) 208cdf0e10cSrcweir { 209cdf0e10cSrcweir ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ); 210cdf0e10cSrcweir Listeners& rListeners = getListenerAdminData().aListeners; 211cdf0e10cSrcweir for ( Listeners::iterator lookup = rListeners.begin(); 212cdf0e10cSrcweir lookup != rListeners.end(); 213cdf0e10cSrcweir ++lookup 214cdf0e10cSrcweir ) 215cdf0e10cSrcweir { 216cdf0e10cSrcweir if ( *lookup == _pListener ) 217cdf0e10cSrcweir { 218cdf0e10cSrcweir rListeners.erase( lookup ); 219cdf0e10cSrcweir break; 220cdf0e10cSrcweir } 221cdf0e10cSrcweir } 222cdf0e10cSrcweir } 223cdf0e10cSrcweir 224cdf0e10cSrcweir //........................................................................ 225cdf0e10cSrcweir } // namespace utl 226cdf0e10cSrcweir //........................................................................ 227cdf0e10cSrcweir 228