1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include "doceventnotifier.hxx"
22 #include "scriptdocument.hxx"
24 #include <com/sun/star/frame/GlobalEventBroadcaster.hpp>
25 #include <com/sun/star/document/XEventBroadcaster.hpp>
27 #include <vcl/svapp.hxx>
29 #include <tools/diagnose_ex.h>
31 #include <comphelper/processfactory.hxx>
33 #include <osl/mutex.hxx>
34 #include <sal/macros.h>
36 #include <cppuhelper/compbase1.hxx>
37 #include <cppuhelper/basemutex.hxx>
39 //........................................................................
42 //........................................................................
44 using ::com::sun::star::document::XEventBroadcaster
;
45 using ::com::sun::star::document::XEventListener
;
46 using ::com::sun::star::document::EventObject
;
47 using ::com::sun::star::uno::XComponentContext
;
48 using ::com::sun::star::uno::RuntimeException
;
49 using ::com::sun::star::uno::Reference
;
50 using ::com::sun::star::uno::UNO_QUERY_THROW
;
51 using ::com::sun::star::uno::Exception
;
52 using ::com::sun::star::frame::XModel
;
53 using ::com::sun::star::frame::GlobalEventBroadcaster
;
54 using ::com::sun::star::uno::UNO_QUERY
;
56 namespace csslang
= ::com::sun::star::lang
;
58 //====================================================================
59 //= DocumentEventNotifier::Impl
60 //====================================================================
61 typedef ::cppu::WeakComponentImplHelper1
< XEventListener
62 > DocumentEventNotifier_Impl_Base
;
70 /** impl class for DocumentEventNotifier
72 class DocumentEventNotifier::Impl
:public ::boost::noncopyable
73 ,public ::cppu::BaseMutex
74 ,public DocumentEventNotifier_Impl_Base
77 Impl (DocumentEventListener
&, Reference
<XModel
> const& rxDocument
);
80 // document::XEventListener
81 virtual void SAL_CALL
notifyEvent( const EventObject
& Event
) throw (RuntimeException
);
83 // lang::XEventListener
84 virtual void SAL_CALL
disposing( const csslang::EventObject
& Event
) throw (RuntimeException
);
87 virtual void SAL_CALL
disposing();
90 /// determines whether the instance is already disposed
91 bool impl_isDisposed_nothrow() const { return m_pListener
== NULL
; }
93 /// disposes the instance
94 void impl_dispose_nothrow();
96 /// registers or revokes the instance as listener at the global event broadcaster
97 void impl_listenerAction_nothrow( ListenerAction _eAction
);
100 DocumentEventListener
* m_pListener
;
101 Reference
< XModel
> m_xModel
;
104 //--------------------------------------------------------------------
105 DocumentEventNotifier::Impl::Impl (DocumentEventListener
& rListener
, Reference
<XModel
> const& rxDocument
) :
106 DocumentEventNotifier_Impl_Base(m_aMutex
),
107 m_pListener(&rListener
),
110 osl_atomic_increment( &m_refCount
);
111 impl_listenerAction_nothrow( RegisterListener
);
112 osl_atomic_decrement( &m_refCount
);
115 //--------------------------------------------------------------------
116 DocumentEventNotifier::Impl::~Impl ()
118 if ( !impl_isDisposed_nothrow() )
125 //--------------------------------------------------------------------
126 void SAL_CALL
DocumentEventNotifier::Impl::notifyEvent( const EventObject
& _rEvent
) throw (RuntimeException
)
128 ::osl::ClearableMutexGuard
aGuard( m_aMutex
);
130 OSL_PRECOND( !impl_isDisposed_nothrow(), "DocumentEventNotifier::Impl::notifyEvent: disposed, but still getting events?" );
131 if ( impl_isDisposed_nothrow() )
134 Reference
< XModel
> xDocument( _rEvent
.Source
, UNO_QUERY
);
135 OSL_ENSURE( xDocument
.is(), "DocumentEventNotifier::Impl::notifyEvent: illegal source document!" );
136 if ( !xDocument
.is() )
141 const sal_Char
* pEventName
;
142 void (DocumentEventListener::*listenerMethod
)( const ScriptDocument
& _rDocument
);
144 EventEntry aEvents
[] = {
145 { "OnNew", &DocumentEventListener::onDocumentCreated
},
146 { "OnLoad", &DocumentEventListener::onDocumentOpened
},
147 { "OnSave", &DocumentEventListener::onDocumentSave
},
148 { "OnSaveDone", &DocumentEventListener::onDocumentSaveDone
},
149 { "OnSaveAs", &DocumentEventListener::onDocumentSaveAs
},
150 { "OnSaveAsDone", &DocumentEventListener::onDocumentSaveAsDone
},
151 { "OnUnload", &DocumentEventListener::onDocumentClosed
},
152 { "OnTitleChanged", &DocumentEventListener::onDocumentTitleChanged
},
153 { "OnModeChanged", &DocumentEventListener::onDocumentModeChanged
}
156 for ( size_t i
=0; i
< SAL_N_ELEMENTS( aEvents
); ++i
)
158 if ( !_rEvent
.EventName
.equalsAscii( aEvents
[i
].pEventName
) )
161 ScriptDocument
aDocument( xDocument
);
163 // the listener implementations usually require the SolarMutex, so lock it here.
164 // But ensure the proper order of locking the solar and the own mutex
166 SolarMutexGuard aSolarGuard
;
167 ::osl::MutexGuard
aGuard2( m_aMutex
);
169 if ( impl_isDisposed_nothrow() )
170 // somebody took the chance to dispose us -> bail out
173 (m_pListener
->*aEvents
[i
].listenerMethod
)( aDocument
);
179 //--------------------------------------------------------------------
180 void SAL_CALL
DocumentEventNotifier::Impl::disposing( const csslang::EventObject
& /*Event*/ ) throw (RuntimeException
)
182 SolarMutexGuard aSolarGuard
;
183 ::osl::MutexGuard
aGuard( m_aMutex
);
185 if ( !impl_isDisposed_nothrow() )
186 impl_dispose_nothrow();
189 //--------------------------------------------------------------------
190 void SAL_CALL
DocumentEventNotifier::Impl::disposing()
192 impl_listenerAction_nothrow( RemoveListener
);
193 impl_dispose_nothrow();
196 //--------------------------------------------------------------------
197 void DocumentEventNotifier::Impl::impl_dispose_nothrow()
203 //--------------------------------------------------------------------
204 void DocumentEventNotifier::Impl::impl_listenerAction_nothrow( ListenerAction _eAction
)
208 Reference
< XEventBroadcaster
> xBroadcaster
;
210 xBroadcaster
.set( m_xModel
, UNO_QUERY_THROW
);
213 Reference
< com::sun::star::uno::XComponentContext
> aContext(
214 comphelper::getProcessComponentContext() );
215 xBroadcaster
.set( GlobalEventBroadcaster::create(aContext
), UNO_QUERY_THROW
);
218 void ( SAL_CALL
XEventBroadcaster::*listenerAction
)( const Reference
< XEventListener
>& ) =
219 ( _eAction
== RegisterListener
) ? &XEventBroadcaster::addEventListener
: &XEventBroadcaster::removeEventListener
;
220 (xBroadcaster
.get()->*listenerAction
)( this );
222 catch( const Exception
& )
224 DBG_UNHANDLED_EXCEPTION();
228 //====================================================================
229 //= DocumentEventNotifier
230 //====================================================================
231 //--------------------------------------------------------------------
232 DocumentEventNotifier::DocumentEventNotifier (DocumentEventListener
& rListener
, Reference
<XModel
> const& rxDocument
) :
233 m_pImpl(new Impl(rListener
, rxDocument
))
236 //--------------------------------------------------------------------
237 DocumentEventNotifier::DocumentEventNotifier (DocumentEventListener
& rListener
) :
238 m_pImpl(new Impl(rListener
, Reference
<XModel
>()))
241 //--------------------------------------------------------------------
242 DocumentEventNotifier::~DocumentEventNotifier()
246 //--------------------------------------------------------------------
247 void DocumentEventNotifier::dispose()
252 //====================================================================
253 //= DocumentEventListener
254 //====================================================================
255 DocumentEventListener::~DocumentEventListener()
259 //........................................................................
260 } // namespace basctl
261 //........................................................................
263 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */