bump product version to 4.1.6.2
[LibreOffice.git] / basctl / source / basicide / doceventnotifier.cxx
blob957ae1b8ea1b758dda954b2ed868636f246a6fea
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 //........................................................................
40 namespace basctl
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;
64 enum ListenerAction
66 RegisterListener,
67 RemoveListener
70 /** impl class for DocumentEventNotifier
72 class DocumentEventNotifier::Impl :public ::boost::noncopyable
73 ,public ::cppu::BaseMutex
74 ,public DocumentEventNotifier_Impl_Base
76 public:
77 Impl (DocumentEventListener&, Reference<XModel> const& rxDocument);
78 ~Impl ();
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);
86 // ComponentHelper
87 virtual void SAL_CALL disposing();
89 private:
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 );
99 private:
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),
108 m_xModel(rxDocument)
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() )
120 acquire();
121 dispose();
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() )
132 return;
134 Reference< XModel > xDocument( _rEvent.Source, UNO_QUERY );
135 OSL_ENSURE( xDocument.is(), "DocumentEventNotifier::Impl::notifyEvent: illegal source document!" );
136 if ( !xDocument.is() )
137 return;
139 struct EventEntry
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 ) )
159 continue;
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
165 aGuard.clear();
166 SolarMutexGuard aSolarGuard;
167 ::osl::MutexGuard aGuard2( m_aMutex );
169 if ( impl_isDisposed_nothrow() )
170 // somebody took the chance to dispose us -> bail out
171 return;
173 (m_pListener->*aEvents[i].listenerMethod)( aDocument );
175 break;
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()
199 m_pListener = NULL;
200 m_xModel.clear();
203 //--------------------------------------------------------------------
204 void DocumentEventNotifier::Impl::impl_listenerAction_nothrow( ListenerAction _eAction )
208 Reference< XEventBroadcaster > xBroadcaster;
209 if ( m_xModel.is() )
210 xBroadcaster.set( m_xModel, UNO_QUERY_THROW );
211 else
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()
249 m_pImpl->dispose();
252 //====================================================================
253 //= DocumentEventListener
254 //====================================================================
255 DocumentEventListener::~DocumentEventListener()
259 //........................................................................
260 } // namespace basctl
261 //........................................................................
263 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */