22#include <com/sun/star/frame/TerminationVetoException.hpp>
23#include <com/sun/star/frame/XTerminateListener.hpp>
24#include <com/sun/star/frame/Desktop.hpp>
27#include <osl/diagnose.h>
42 typedef ::std::vector< ITerminationListener* > Listeners;
44 struct ListenerAdminData
53 ListenerAdminData& getListenerAdminData()
55 static ListenerAdminData s_aData;
61 class OObserverImpl :
public ::cppu::WeakImplHelper< XTerminateListener >
64 static void ensureObservation();
68 virtual ~OObserverImpl()
override;
71 virtual void SAL_CALL queryTermination(
const EventObject& Event )
override;
72 virtual void SAL_CALL notifyTermination(
const EventObject& Event )
override;
75 virtual void SAL_CALL disposing(
const css::lang::EventObject& Source )
override;
78 OObserverImpl::OObserverImpl()
82 OObserverImpl::~OObserverImpl()
86 void OObserverImpl::ensureObservation()
91 ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
95 getListenerAdminData().bCreatedAdapter =
true;
100 Reference< XDesktop2 > xDesktop = Desktop::create( ::comphelper::getProcessComponentContext() );
101 xDesktop->addTerminateListener(
new OObserverImpl );
103 catch(
const Exception& )
109 void SAL_CALL OObserverImpl::queryTermination(
const EventObject& )
113 ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
114 aToNotify = getListenerAdminData().aListeners;
117 for (
auto const& listener : aToNotify)
119 if ( !listener->queryTermination() )
120 throw TerminationVetoException();
124 void SAL_CALL OObserverImpl::notifyTermination(
const EventObject& )
129 ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
130 OSL_ENSURE( !getListenerAdminData().
bAlreadyTerminated,
"OObserverImpl::notifyTermination: terminated twice?" );
131 aToNotify = getListenerAdminData().aListeners;
132 getListenerAdminData().bAlreadyTerminated =
true;
136 for (
auto const& listener : aToNotify)
138 listener->notifyTermination();
143 ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
144 getListenerAdminData().aListeners.clear();
148 void SAL_CALL OObserverImpl::disposing(
const EventObject& )
150#if OSL_DEBUG_LEVEL > 0
151 ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
152 OSL_ENSURE( getListenerAdminData().
bAlreadyTerminated,
"OObserverImpl::disposing: disposing without terminated?" );
160 void DesktopTerminationObserver::registerTerminationListener( ITerminationListener* _pListener )
166 ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
169 _pListener->notifyTermination();
173 getListenerAdminData().aListeners.push_back( _pListener );
176 OObserverImpl::ensureObservation();
179 void DesktopTerminationObserver::revokeTerminationListener( ITerminationListener
const * _pListener )
181 ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
182 Listeners& rListeners = getListenerAdminData().aListeners;
183 rListeners.erase(std::remove(rListeners.begin(), rListeners.end(), _pListener), rListeners.end());
#define TOOLS_WARN_EXCEPTION(area, stream)