merge the formfield patch from ooo-build
[ooovba.git] / unotools / source / misc / desktopterminationobserver.cxx
blobcd1fad984769ffacda43d429ddde50248ef58300
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: desktopterminationobserver.cxx,v $
10 * $Revision: 1.6 $
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>
42 #include <list>
44 //........................................................................
45 namespace utl
47 //........................................................................
49 using namespace ::com::sun::star::uno;
50 using namespace ::com::sun::star::lang;
51 using namespace ::com::sun::star::frame;
53 namespace
55 //................................................................
56 typedef ::std::list< ITerminationListener* > Listeners;
58 struct ListenerAdminData
60 Listeners aListeners;
61 bool bAlreadyTerminated;
62 bool bCreatedAdapter;
64 ListenerAdminData() : bAlreadyTerminated( false ), bCreatedAdapter( false ) { }
67 //................................................................
68 ListenerAdminData& getListenerAdminData()
70 static ListenerAdminData s_aData;
71 return s_aData;
74 //================================================================
75 //= OObserverImpl
76 //================================================================
77 class OObserverImpl : public ::cppu::WeakImplHelper1< XTerminateListener >
79 public:
80 static void ensureObservation();
82 protected:
83 OObserverImpl();
84 ~OObserverImpl();
86 private:
87 // XTerminateListener
88 virtual void SAL_CALL queryTermination( const EventObject& Event ) throw (TerminationVetoException, RuntimeException);
89 virtual void SAL_CALL notifyTermination( const EventObject& Event ) throw (RuntimeException);
91 // XEventListener
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 )
110 return;
111 ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
112 if ( getListenerAdminData().bCreatedAdapter )
113 return;
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!" );
123 if ( xDesktop.is() )
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)
135 Listeners aToNotify;
137 ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
138 aToNotify = getListenerAdminData().aListeners;
141 for ( Listeners::const_iterator listener = aToNotify.begin();
142 listener != aToNotify.end();
143 ++listener
146 if ( !(*listener)->queryTermination() )
147 throw TerminationVetoException();
151 //--------------------------------------------------------------------
152 void SAL_CALL OObserverImpl::notifyTermination( const EventObject& /*Event*/ ) throw (RuntimeException)
154 // get the listeners
155 Listeners aToNotify;
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();
166 ++listener
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?" );
185 #endif
186 // not interested in
190 //====================================================================
191 //= DesktopTerminationObserver
192 //====================================================================
193 //--------------------------------------------------------------------
194 void DesktopTerminationObserver::registerTerminationListener( ITerminationListener* _pListener )
196 if ( !_pListener )
197 return;
200 ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
201 if ( getListenerAdminData().bAlreadyTerminated )
203 _pListener->notifyTermination();
204 return;
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();
220 return;
223 Listeners& rListeners = getListenerAdminData().aListeners;
224 for ( Listeners::iterator lookup = rListeners.begin();
225 lookup != rListeners.end();
226 ++lookup
229 if ( *lookup == _pListener )
231 rListeners.erase( lookup );
232 break;
237 //........................................................................
238 } // namespace utl
239 //........................................................................