22#include <com/sun/star/task/theJobExecutor.hpp>
23#include <com/sun/star/container/XNameReplace.hpp>
24#include <com/sun/star/container/XSet.hpp>
25#include <com/sun/star/document/XEventListener.hpp>
26#include <com/sun/star/document/XEventBroadcaster.hpp>
27#include <com/sun/star/document/XDocumentEventListener.hpp>
28#include <com/sun/star/frame/XGlobalEventBroadcaster.hpp>
29#include <com/sun/star/lang/DisposedException.hpp>
30#include <com/sun/star/lang/NoSupportException.hpp>
31#include <com/sun/star/lang/XServiceInfo.hpp>
32#include <com/sun/star/uno/Type.hxx>
52typedef ::std::vector< css::uno::Reference< css::frame::XModel > > TModelList;
56class SfxGlobalEvents_Impl :
public ::cppu::WeakImplHelper< css::lang::XServiceInfo
57 , css::frame::XGlobalEventBroadcaster
58 , css::document::XEventBroadcaster
59 , css::document::XEventListener
60 , css::lang::XComponent
65 css::uno::Reference< css::document::XEventListener > m_xJobExecutorListener;
68 std::multiset<css::uno::Reference<css::lang::XEventListener>> m_disposeListeners;
73 explicit SfxGlobalEvents_Impl(
const css::uno::Reference < css::uno::XComponentContext >& rxContext);
77 return "com.sun.star.comp.sfx2.GlobalEventBroadcaster";
87 css::uno::Sequence< OUString >
aSeq {
"com.sun.star.frame.GlobalEventBroadcaster" };
92 virtual css::uno::Reference< css::container::XNameReplace > SAL_CALL getEvents()
override;
94 virtual void SAL_CALL addEventListener(
const css::uno::Reference< css::document::XEventListener >& xListener)
override;
96 virtual void SAL_CALL removeEventListener(
const css::uno::Reference< css::document::XEventListener >& xListener)
override;
99 virtual void SAL_CALL addDocumentEventListener(
const css::uno::Reference< css::document::XDocumentEventListener >& Listener )
override;
100 virtual void SAL_CALL removeDocumentEventListener(
const css::uno::Reference< css::document::XDocumentEventListener >& Listener )
override;
101 virtual void SAL_CALL notifyDocumentEvent(
const OUString& EventName,
const css::uno::Reference< css::frame::XController2 >& ViewController,
const css::uno::Any& Supplement )
override;
104 virtual void SAL_CALL notifyEvent(
const css::document::EventObject& aEvent)
override;
107 virtual void SAL_CALL documentEventOccured(
const css::document::DocumentEvent& Event )
override;
110 virtual sal_Bool SAL_CALL has(
const css::uno::Any& aElement)
override;
112 virtual void SAL_CALL insert(
const css::uno::Any& aElement)
override;
114 virtual void SAL_CALL
remove(
const css::uno::Any& aElement)
override;
117 virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration()
override;
120 virtual css::uno::Type SAL_CALL getElementType()
override;
122 virtual sal_Bool SAL_CALL hasElements()
override;
125 virtual void SAL_CALL disposing(
const css::lang::EventObject& aEvent)
override;
128 void SAL_CALL
dispose()
override;
130 void SAL_CALL addEventListener(css::uno::Reference<css::lang::XEventListener>
const & xListener)
133 void SAL_CALL removeEventListener(
134 css::uno::Reference<css::lang::XEventListener>
const & aListener)
override;
139 void implts_notifyJobExecution(
const css::document::EventObject& aEvent);
140 void implts_checkAndExecuteEventBindings(
const css::document::DocumentEvent& aEvent);
141 void implts_notifyListener(
const css::document::DocumentEvent& aEvent);
144 TModelList::iterator impl_searchDoc(
const css::uno::Reference< css::frame::XModel >& xModel);
147SfxGlobalEvents_Impl::SfxGlobalEvents_Impl(
const uno::Reference < uno::XComponentContext >& rxContext)
148 : m_xJobExecutorListener( task::theJobExecutor::
get( rxContext ),
uno::UNO_QUERY_THROW )
151 osl_atomic_increment(&m_refCount);
154 osl_atomic_decrement(&m_refCount);
157uno::Reference< container::XNameReplace > SAL_CALL SfxGlobalEvents_Impl::getEvents()
160 std::scoped_lock aLock(m_aLock);
162 throw css::lang::DisposedException();
169void SAL_CALL SfxGlobalEvents_Impl::addEventListener(
const uno::Reference< document::XEventListener >& xListener)
171 std::unique_lock g(m_aLock);
173 throw css::lang::DisposedException();
174 m_aLegacyListeners.addInterface(g, xListener);
178void SAL_CALL SfxGlobalEvents_Impl::removeEventListener(
const uno::Reference< document::XEventListener >& xListener)
180 std::unique_lock g(m_aLock);
182 m_aLegacyListeners.removeInterface(g, xListener);
186void SAL_CALL SfxGlobalEvents_Impl::addDocumentEventListener(
const uno::Reference< document::XDocumentEventListener >& Listener )
188 std::unique_lock g(m_aLock);
190 throw css::lang::DisposedException();
191 m_aDocumentListeners.addInterface( g, Listener );
195void SAL_CALL SfxGlobalEvents_Impl::removeDocumentEventListener(
const uno::Reference< document::XDocumentEventListener >& Listener )
197 std::unique_lock g(m_aLock);
199 m_aDocumentListeners.removeInterface( g, Listener );
203void SAL_CALL SfxGlobalEvents_Impl::notifyDocumentEvent(
const OUString& ,
204 const uno::Reference< frame::XController2 >& ,
const uno::Any& )
207 throw lang::NoSupportException(OUString(), *
this);
211void SAL_CALL SfxGlobalEvents_Impl::notifyEvent(
const document::EventObject& aEvent)
215 implts_notifyJobExecution(aEvent);
216 implts_checkAndExecuteEventBindings(aDocEvent);
217 implts_notifyListener(aDocEvent);
221void SAL_CALL SfxGlobalEvents_Impl::documentEventOccured(
const document::DocumentEvent& Event )
224 implts_notifyJobExecution(document::EventObject(Event.Source, Event.EventName));
225 implts_checkAndExecuteEventBindings(Event);
226 implts_notifyListener(Event);
230void SAL_CALL SfxGlobalEvents_Impl::disposing(
const lang::EventObject& aEvent)
232 uno::Reference< frame::XModel > xDoc(
aEvent.Source, uno::UNO_QUERY);
235 std::scoped_lock g(m_aLock);
236 TModelList::iterator pIt = impl_searchDoc(xDoc);
237 if (pIt != m_lModels.end())
238 m_lModels.erase(pIt);
242void SfxGlobalEvents_Impl::dispose() {
243 std::multiset<css::uno::Reference<css::lang::XEventListener>> listeners;
245 std::unique_lock g(m_aLock);
249 auto tmpEvents = std::move(m_xEvents);
250 auto tmpModels = std::move(m_lModels);
251 m_xJobExecutorListener.clear();
252 m_disposeListeners.swap(listeners);
259 m_aLegacyListeners.disposeAndClear(g, {getXWeak()});
260 m_aDocumentListeners.disposeAndClear(g, {getXWeak()});
262 for (
auto const & i: listeners) {
264 i->disposing({getXWeak()});
265 }
catch (css::lang::DisposedException &) {}
269void SfxGlobalEvents_Impl::addEventListener(
270 css::uno::Reference<css::lang::XEventListener>
const & xListener)
272 if (!xListener.is()) {
273 throw css::uno::RuntimeException(
"null listener");
276 std::scoped_lock g(m_aLock);
278 m_disposeListeners.insert(xListener);
283 xListener->disposing({getXWeak()});
284 }
catch (css::lang::DisposedException &) {}
287void SfxGlobalEvents_Impl::removeEventListener(
288 css::uno::Reference<css::lang::XEventListener>
const & aListener)
290 std::scoped_lock g(m_aLock);
291 auto const i = m_disposeListeners.find(aListener);
292 if (i != m_disposeListeners.end()) {
293 m_disposeListeners.erase(i);
299 uno::Reference< frame::XModel > xDoc;
305 std::scoped_lock g(m_aLock);
307 throw css::lang::DisposedException();
309 TModelList::iterator pIt = impl_searchDoc(xDoc);
310 if (pIt != m_lModels.end())
318void SAL_CALL SfxGlobalEvents_Impl::insert(
const uno::Any& aElement )
320 uno::Reference< frame::XModel > xDoc;
323 throw lang::IllegalArgumentException(
324 "Can not locate at least the model parameter.",
325 static_cast< container::XSet*
>(
this),
330 std::scoped_lock g(m_aLock);
332 throw css::lang::DisposedException();
334 TModelList::iterator pIt = impl_searchDoc(xDoc);
335 if (pIt != m_lModels.end())
336 throw container::ElementExistException(
338 static_cast<container::XSet*
>(
this));
339 m_lModels.push_back(xDoc);
343 uno::Reference< document::XDocumentEventBroadcaster > xDocBroadcaster(xDoc, uno::UNO_QUERY );
344 if (xDocBroadcaster.is())
345 xDocBroadcaster->addDocumentEventListener(
this);
349 uno::Reference< document::XEventBroadcaster > xBroadcaster(xDoc, uno::UNO_QUERY);
350 if (xBroadcaster.is())
351 xBroadcaster->addEventListener(
static_cast< document::XEventListener*
>(
this));
356void SAL_CALL SfxGlobalEvents_Impl::remove(
const uno::Any& aElement )
358 uno::Reference< frame::XModel > xDoc;
361 throw lang::IllegalArgumentException(
362 "Can not locate at least the model parameter.",
363 static_cast< container::XSet*
>(
this),
368 std::scoped_lock g(m_aLock);
369 TModelList::iterator pIt = impl_searchDoc(xDoc);
370 if (pIt == m_lModels.end())
371 throw container::NoSuchElementException(
373 static_cast<container::XSet*
>(
this));
374 m_lModels.erase(pIt);
378 uno::Reference< document::XDocumentEventBroadcaster > xDocBroadcaster(xDoc, uno::UNO_QUERY );
379 if (xDocBroadcaster.is())
380 xDocBroadcaster->removeDocumentEventListener(
this);
384 uno::Reference< document::XEventBroadcaster > xBroadcaster(xDoc, uno::UNO_QUERY);
385 if (xBroadcaster.is())
386 xBroadcaster->removeEventListener(
static_cast< document::XEventListener*
>(
this));
391uno::Reference< container::XEnumeration > SAL_CALL SfxGlobalEvents_Impl::createEnumeration()
394 std::scoped_lock g(m_aLock);
396 throw css::lang::DisposedException();
398 uno::Sequence<uno::Any> models(m_lModels.size());
399 auto modelsRange = asNonConstRange(models);
400 for (
size_t i = 0;
i < m_lModels.size(); ++
i)
402 modelsRange[
i] <<= m_lModels[
i];
404 uno::Reference<container::XEnumeration> xEnum(new ::comphelper::OAnyEnumeration(models));
411uno::Type SAL_CALL SfxGlobalEvents_Impl::getElementType()
417sal_Bool SAL_CALL SfxGlobalEvents_Impl::hasElements()
420 std::scoped_lock g(m_aLock);
422 throw css::lang::DisposedException();
424 return (!m_lModels.empty());
429void SfxGlobalEvents_Impl::implts_notifyJobExecution(
const document::EventObject& aEvent)
431 css::uno::Reference<css::document::XEventListener> listener;
433 std::scoped_lock g(m_aLock);
434 listener = m_xJobExecutorListener;
436 if (!listener.is()) {
441 listener->notifyEvent(aEvent);
443 catch(
const uno::RuntimeException&)
445 catch(
const uno::Exception&)
450void SfxGlobalEvents_Impl::implts_checkAndExecuteEventBindings(
const document::DocumentEvent& aEvent)
454 std::scoped_lock g(m_aLock);
462 if ( events->hasByName(
aEvent.EventName ) )
464 uno::Sequence < beans::PropertyValue > aAny = events->getByName2(
aEvent.EventName);
468 catch ( uno::RuntimeException
const & )
472 catch ( uno::Exception
const & )
479void SfxGlobalEvents_Impl::implts_notifyListener(
const document::DocumentEvent& aEvent)
481 std::unique_lock g(m_aLock);
483 document::EventObject aLegacyEvent(
aEvent.Source,
aEvent.EventName);
484 m_aLegacyListeners.forEach(g,
485 [&aLegacyEvent](
const css::uno::Reference<document::XEventListener>& xListener)
487 xListener->notifyEvent(aLegacyEvent);
490 m_aDocumentListeners.forEach(g,
491 [&aEvent](
const css::uno::Reference<document::XDocumentEventListener>& xListener)
493 xListener->documentEventOccured(aEvent);
500TModelList::iterator SfxGlobalEvents_Impl::impl_searchDoc(
const uno::Reference< frame::XModel >& xModel)
503 return m_lModels.end();
505 return std::find_if(m_lModels.begin(), m_lModels.end(),
506 [&xModel](
const uno::Reference< frame::XModel >& rxModel) {
507 return rxModel == xModel;
513extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
515 css::uno::XComponentContext *context,
516 css::uno::Sequence<css::uno::Any>
const &)
518 return cppu::acquire(
new SfxGlobalEvents_Impl(context));
static SfxApplication * GetOrCreate()
static void Execute(css::uno::Sequence< css::beans::PropertyValue > const &aEventData, const css::document::DocumentEvent &aTrigger, SfxObjectShell *pDoc)
css::uno::Type const & get()
#define DBG_UNHANDLED_EXCEPTION(...)
SAL_DLLPUBLIC_EXPORT css::uno::XInterface * com_sun_star_comp_sfx2_GlobalEventBroadcaster_get_implementation(css::uno::XComponentContext *context, css::uno::Sequence< css::uno::Any > const &)
Sequence< sal_Int8 > aSeq
OUStringBuffer & remove(OUStringBuffer &rIn, sal_Unicode c)
css::uno::Sequence< OUString > getSupportedServiceNames()
OUString getImplementationName()
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
css::uno::Reference< css::linguistic2::XProofreadingIterator > get(css::uno::Reference< css::uno::XComponentContext > const &context)
Reference< XModel > xModel