1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: desktopterminationobserver.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_unotools.hxx"
33 #include <unotools/desktopterminationobserver.hxx>
35 /** === begin UNO includes === **/
36 #include <com/sun/star/frame/XTerminateListener.hpp>
37 #include <com/sun/star/frame/XDesktop.hpp>
38 /** === end UNO includes === **/
39 #include <cppuhelper/implbase1.hxx>
40 #include <comphelper/processfactory.hxx>
44 //........................................................................
47 //........................................................................
49 using namespace ::com::sun::star::uno
;
50 using namespace ::com::sun::star::lang
;
51 using namespace ::com::sun::star::frame
;
55 //................................................................
56 typedef ::std::list
< ITerminationListener
* > Listeners
;
58 struct ListenerAdminData
61 bool bAlreadyTerminated
;
64 ListenerAdminData() : bAlreadyTerminated( false ), bCreatedAdapter( false ) { }
67 //................................................................
68 ListenerAdminData
& getListenerAdminData()
70 static ListenerAdminData s_aData
;
74 //================================================================
76 //================================================================
77 class OObserverImpl
: public ::cppu::WeakImplHelper1
< XTerminateListener
>
80 static void ensureObservation();
88 virtual void SAL_CALL
queryTermination( const EventObject
& Event
) throw (TerminationVetoException
, RuntimeException
);
89 virtual void SAL_CALL
notifyTermination( const EventObject
& Event
) throw (RuntimeException
);
92 virtual void SAL_CALL
disposing( const ::com::sun::star::lang::EventObject
& Source
) throw (::com::sun::star::uno::RuntimeException
);
95 //--------------------------------------------------------------------
96 OObserverImpl::OObserverImpl()
100 //--------------------------------------------------------------------
101 OObserverImpl::~OObserverImpl()
105 //--------------------------------------------------------------------
106 void OObserverImpl::ensureObservation()
109 if ( getListenerAdminData().bCreatedAdapter
)
111 ::osl::MutexGuard
aGuard( ::osl::Mutex::getGlobalMutex() );
112 if ( getListenerAdminData().bCreatedAdapter
)
115 getListenerAdminData().bCreatedAdapter
= true;
120 Reference
< XDesktop
> xDesktop
;
121 xDesktop
= xDesktop
.query( ::comphelper::getProcessServiceFactory()->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.frame.Desktop" ) ) ) );
122 OSL_ENSURE( xDesktop
.is(), "OObserverImpl::ensureObservation: could not ensureObservation the desktop!" );
124 xDesktop
->addTerminateListener( new OObserverImpl
);
126 catch( const Exception
& )
128 OSL_ENSURE( sal_False
, "OObserverImpl::ensureObservation: caught an exception!" );
132 //--------------------------------------------------------------------
133 void SAL_CALL
OObserverImpl::queryTermination( const EventObject
& /*Event*/ ) throw (TerminationVetoException
, RuntimeException
)
137 ::osl::MutexGuard
aGuard( ::osl::Mutex::getGlobalMutex() );
138 aToNotify
= getListenerAdminData().aListeners
;
141 for ( Listeners::const_iterator listener
= aToNotify
.begin();
142 listener
!= aToNotify
.end();
146 if ( !(*listener
)->queryTermination() )
147 throw TerminationVetoException();
151 //--------------------------------------------------------------------
152 void SAL_CALL
OObserverImpl::notifyTermination( const EventObject
& /*Event*/ ) throw (RuntimeException
)
157 ::osl::MutexGuard
aGuard( ::osl::Mutex::getGlobalMutex() );
158 OSL_ENSURE( !getListenerAdminData().bAlreadyTerminated
, "OObserverImpl::notifyTermination: terminated twice?" );
159 aToNotify
= getListenerAdminData().aListeners
;
160 getListenerAdminData().bAlreadyTerminated
= true;
163 // notify the listeners
164 for ( Listeners::const_iterator listener
= aToNotify
.begin();
165 listener
!= aToNotify
.end();
169 (*listener
)->notifyTermination();
172 // clear the listener container
174 ::osl::MutexGuard
aGuard( ::osl::Mutex::getGlobalMutex() );
175 getListenerAdminData().aListeners
.clear();
179 //--------------------------------------------------------------------
180 void SAL_CALL
OObserverImpl::disposing( const EventObject
& /*Event*/ ) throw (RuntimeException
)
182 #if OSL_DEBUG_LEVEL > 0
183 ::osl::MutexGuard
aGuard( ::osl::Mutex::getGlobalMutex() );
184 OSL_ENSURE( getListenerAdminData().bAlreadyTerminated
, "OObserverImpl::disposing: disposing without terminated?" );
190 //====================================================================
191 //= DesktopTerminationObserver
192 //====================================================================
193 //--------------------------------------------------------------------
194 void DesktopTerminationObserver::registerTerminationListener( ITerminationListener
* _pListener
)
200 ::osl::MutexGuard
aGuard( ::osl::Mutex::getGlobalMutex() );
201 if ( getListenerAdminData().bAlreadyTerminated
)
203 _pListener
->notifyTermination();
207 getListenerAdminData().aListeners
.push_back( _pListener
);
210 OObserverImpl::ensureObservation();
213 //--------------------------------------------------------------------
214 void DesktopTerminationObserver::revokeTerminationListener( ITerminationListener
* _pListener
)
216 ::osl::MutexGuard
aGuard( ::osl::Mutex::getGlobalMutex() );
217 if ( getListenerAdminData().bAlreadyTerminated
)
219 _pListener
->notifyTermination();
223 Listeners
& rListeners
= getListenerAdminData().aListeners
;
224 for ( Listeners::iterator lookup
= rListeners
.begin();
225 lookup
!= rListeners
.end();
229 if ( *lookup
== _pListener
)
231 rListeners
.erase( lookup
);
237 //........................................................................
239 //........................................................................