1 /*************************************************************************
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 * Copyright 2008 by Sun Microsystems, Inc.
6 * OpenOffice.org - a multi-platform office productivity suite
8 * $RCSfile: documenteventnotifier.cxx,v $
10 * $Revision: 1.1.2.4 $
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.
28 ************************************************************************/
30 // MARKER(update_precomp.py): autogen include statement, do not remove
31 #include "precompiled_dbaccess.hxx"
33 #include "documenteventnotifier.hxx"
35 /** === begin UNO includes === **/
36 #include <com/sun/star/frame/DoubleInitializationException.hpp>
37 /** === end UNO includes === **/
39 #include <comphelper/asyncnotification.hxx>
40 #include <cppuhelper/interfacecontainer.hxx>
41 #include <cppuhelper/weak.hxx>
42 #include <tools/diagnose_ex.h>
44 //........................................................................
47 //........................................................................
49 /** === begin UNO using === **/
50 using ::com::sun::star::uno::Reference
;
51 using ::com::sun::star::uno::XInterface
;
52 using ::com::sun::star::uno::UNO_QUERY
;
53 using ::com::sun::star::uno::UNO_QUERY_THROW
;
54 using ::com::sun::star::uno::UNO_SET_THROW
;
55 using ::com::sun::star::uno::Exception
;
56 using ::com::sun::star::uno::RuntimeException
;
57 using ::com::sun::star::uno::Any
;
58 using ::com::sun::star::uno::makeAny
;
59 using ::com::sun::star::uno::Sequence
;
60 using ::com::sun::star::uno::Type
;
61 using ::com::sun::star::frame::DoubleInitializationException
;
62 using ::com::sun::star::document::XDocumentEventListener
;
63 using ::com::sun::star::document::DocumentEvent
;
64 using ::com::sun::star::frame::XController2
;
65 /** === end UNO using === **/
66 using namespace ::com::sun::star
;
68 //==================================================================
69 //= DocumentEventHolder
70 //==================================================================
71 typedef ::comphelper::EventHolder
< DocumentEvent
> DocumentEventHolder
;
73 //====================================================================
74 //= DocumentEventNotifier_Impl
75 //====================================================================
76 class DocumentEventNotifier_Impl
: public ::comphelper::IEventProcessor
78 oslInterlockedCount m_refCount
;
79 ::cppu::OWeakObject
& m_rDocument
;
80 ::osl::Mutex
& m_rMutex
;
83 ::rtl::Reference
< ::comphelper::AsyncEventNotifier
> m_pEventBroadcaster
;
84 ::cppu::OInterfaceContainerHelper m_aLegacyEventListeners
;
85 ::cppu::OInterfaceContainerHelper m_aDocumentEventListeners
;
88 DocumentEventNotifier_Impl( ::cppu::OWeakObject
& _rBroadcasterDocument
, ::osl::Mutex
& _rMutex
)
90 ,m_rDocument( _rBroadcasterDocument
)
92 ,m_bInitialized( false )
94 ,m_aLegacyEventListeners( _rMutex
)
95 ,m_aDocumentEventListeners( _rMutex
)
100 virtual void SAL_CALL
acquire();
101 virtual void SAL_CALL
release();
103 void addLegacyEventListener( const Reference
< document::XEventListener
>& _Listener
)
105 m_aLegacyEventListeners
.addInterface( _Listener
);
108 void removeLegacyEventListener( const Reference
< document::XEventListener
>& _Listener
)
110 m_aLegacyEventListeners
.removeInterface( _Listener
);
113 void addDocumentEventListener( const Reference
< XDocumentEventListener
>& _Listener
)
115 m_aDocumentEventListeners
.addInterface( _Listener
);
118 void removeDocumentEventListener( const Reference
< XDocumentEventListener
>& _Listener
)
120 m_aDocumentEventListeners
.removeInterface( _Listener
);
125 void onDocumentInitialized();
127 void notifyDocumentEvent( const ::rtl::OUString
& _EventName
, const Reference
< XController2
>& _ViewController
,
128 const Any
& _Supplement
)
130 impl_notifyEvent_nothrow( DocumentEvent(
131 m_rDocument
, _EventName
, _ViewController
, _Supplement
) );
134 void notifyDocumentEventAsync( const ::rtl::OUString
& _EventName
, const Reference
< XController2
>& _ViewController
,
135 const Any
& _Supplement
)
137 impl_notifyEventAsync_nothrow( DocumentEvent(
138 m_rDocument
, _EventName
, _ViewController
, _Supplement
) );
142 virtual ~DocumentEventNotifier_Impl()
147 virtual void processEvent( const ::comphelper::AnyEvent
& _rEvent
);
150 void impl_notifyEvent_nothrow( const DocumentEvent
& _rEvent
);
151 void impl_notifyEventAsync_nothrow( const DocumentEvent
& _rEvent
);
154 //--------------------------------------------------------------------
155 void SAL_CALL
DocumentEventNotifier_Impl::acquire()
157 osl_incrementInterlockedCount( &m_refCount
);
160 //--------------------------------------------------------------------
161 void SAL_CALL
DocumentEventNotifier_Impl::release()
163 if ( 0 == osl_decrementInterlockedCount( &m_refCount
) )
167 //--------------------------------------------------------------------
168 void DocumentEventNotifier_Impl::disposing()
171 // cancel any pending asynchronous events
172 ::osl::ResettableMutexGuard
aGuard( m_rMutex
);
173 if ( m_pEventBroadcaster
.is() )
175 m_pEventBroadcaster
->removeEventsForProcessor( this );
176 m_pEventBroadcaster
->terminate();
177 m_pEventBroadcaster
= NULL
;
180 lang::EventObject
aEvent( m_rDocument
);
184 m_aLegacyEventListeners
.disposeAndClear( aEvent
);
185 m_aDocumentEventListeners
.disposeAndClear( aEvent
);
193 //--------------------------------------------------------------------
194 void DocumentEventNotifier_Impl::onDocumentInitialized()
196 if ( m_bInitialized
)
197 throw DoubleInitializationException();
199 m_bInitialized
= true;
200 if ( m_pEventBroadcaster
.is() )
201 // there are already pending asynchronous events
202 m_pEventBroadcaster
->create();
205 //--------------------------------------------------------------------
206 void DocumentEventNotifier_Impl::impl_notifyEvent_nothrow( const DocumentEvent
& _rEvent
)
208 OSL_PRECOND( m_bInitialized
,
209 "DocumentEventNotifier_Impl::impl_notifyEvent_nothrow: only to be called when the document is already initialized!" );
212 document::EventObject
aLegacyEvent( _rEvent
.Source
, _rEvent
.EventName
);
213 m_aLegacyEventListeners
.notifyEach( &document::XEventListener::notifyEvent
, aLegacyEvent
);
215 catch(const Exception
&)
217 DBG_UNHANDLED_EXCEPTION();
221 m_aDocumentEventListeners
.notifyEach( &XDocumentEventListener::documentEventOccured
, _rEvent
);
223 catch( const Exception
& )
225 DBG_UNHANDLED_EXCEPTION();
229 //--------------------------------------------------------------------
230 void DocumentEventNotifier_Impl::impl_notifyEventAsync_nothrow( const DocumentEvent
& _rEvent
)
232 if ( !m_pEventBroadcaster
.is() )
234 m_pEventBroadcaster
.set( new ::comphelper::AsyncEventNotifier
);
235 if ( m_bInitialized
)
236 // start processing the events if and only if we (our document, respectively) are
237 // already initialized
238 m_pEventBroadcaster
->create();
240 m_pEventBroadcaster
->addEvent( new DocumentEventHolder( _rEvent
), this );
243 // -----------------------------------------------------------------------------
244 void DocumentEventNotifier_Impl::processEvent( const ::comphelper::AnyEvent
& _rEvent
)
246 // beware, this is called from the notification thread
248 ::osl::MutexGuard
aGuard( m_rMutex
);
252 const DocumentEventHolder
& rEventHolder
= dynamic_cast< const DocumentEventHolder
& >( _rEvent
);
253 impl_notifyEvent_nothrow( rEventHolder
.getEventObject() );
256 //====================================================================
257 //= DocumentEventNotifier
258 //====================================================================
259 //--------------------------------------------------------------------
260 DocumentEventNotifier::DocumentEventNotifier( ::cppu::OWeakObject
& _rBroadcasterDocument
, ::osl::Mutex
& _rMutex
)
261 :m_pImpl( new DocumentEventNotifier_Impl( _rBroadcasterDocument
, _rMutex
) )
265 //--------------------------------------------------------------------
266 DocumentEventNotifier::~DocumentEventNotifier()
270 //--------------------------------------------------------------------
271 void DocumentEventNotifier::disposing()
273 m_pImpl
->disposing();
276 //--------------------------------------------------------------------
277 void DocumentEventNotifier::onDocumentInitialized()
279 m_pImpl
->onDocumentInitialized();
282 //--------------------------------------------------------------------
283 void DocumentEventNotifier::addLegacyEventListener( const Reference
< document::XEventListener
>& _Listener
)
285 m_pImpl
->addLegacyEventListener( _Listener
);
288 //--------------------------------------------------------------------
289 void DocumentEventNotifier::removeLegacyEventListener( const Reference
< document::XEventListener
>& _Listener
)
291 m_pImpl
->removeLegacyEventListener( _Listener
);
294 //--------------------------------------------------------------------
295 void DocumentEventNotifier::addDocumentEventListener( const Reference
< XDocumentEventListener
>& _Listener
)
297 m_pImpl
->addDocumentEventListener( _Listener
);
300 //--------------------------------------------------------------------
301 void DocumentEventNotifier::removeDocumentEventListener( const Reference
< XDocumentEventListener
>& _Listener
)
303 m_pImpl
->removeDocumentEventListener( _Listener
);
306 //--------------------------------------------------------------------
307 void DocumentEventNotifier::notifyDocumentEvent( const ::rtl::OUString
& _EventName
,
308 const Reference
< XController2
>& _ViewController
, const Any
& _Supplement
)
310 m_pImpl
->notifyDocumentEvent( _EventName
, _ViewController
, _Supplement
);
313 //--------------------------------------------------------------------
314 void DocumentEventNotifier::notifyDocumentEventAsync( const ::rtl::OUString
& _EventName
,
315 const Reference
< XController2
>& _ViewController
, const Any
& _Supplement
)
317 m_pImpl
->notifyDocumentEventAsync( _EventName
, _ViewController
, _Supplement
);
320 //........................................................................
321 } // namespace dbaccess
322 //........................................................................