1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_unotools.hxx"
26 #include <unotools/eventlisteneradapter.hxx>
27 #include <osl/diagnose.h>
28 #include <cppuhelper/implbase1.hxx>
29 #include <comphelper/stl_types.hxx>
30 
31 //.........................................................................
32 namespace utl
33 {
34 //.........................................................................
35 
36 	using namespace ::com::sun::star::uno;
37 	using namespace ::com::sun::star::lang;
38 
39 	//=====================================================================
40 	//= OEventListenerImpl
41 	//=====================================================================
42 	class OEventListenerImpl : public ::cppu::WeakImplHelper1< XEventListener >
43 	{
44 	protected:
45 		OEventListenerAdapter*			m_pAdapter;
46 		Reference< XEventListener >		m_xKeepMeAlive;
47 			// imagine an implementation of XComponent which holds it's listeners with a weak reference ...
48 			// would be very bad if we don't hold ourself
49 		Reference< XComponent >			m_xComponent;
50 
51 	public:
52 		OEventListenerImpl( OEventListenerAdapter* _pAdapter, const Reference< XComponent >& _rxComp );
53 
54 		void							dispose();
getComponent() const55 		const Reference< XComponent >&	getComponent() const { return m_xComponent; }
56 
57 	protected:
58 		virtual void SAL_CALL disposing( const EventObject& _rSource ) throw (RuntimeException);
59 	};
60 
61 	//---------------------------------------------------------------------
OEventListenerImpl(OEventListenerAdapter * _pAdapter,const Reference<XComponent> & _rxComp)62 	OEventListenerImpl::OEventListenerImpl( OEventListenerAdapter* _pAdapter, const Reference< XComponent >& _rxComp )
63 		:m_pAdapter(_pAdapter)
64 	{
65 		OSL_ENSURE(m_pAdapter, "OEventListenerImpl::OEventListenerImpl: invalid adapter!");
66 		// no checks of _rxComp !!
67 		// (OEventListenerAdapter is responsible for this)
68 
69 		// just in case addEventListener throws an exception ... don't initialize m_xKeepMeAlive before this
70 		// is done
71 		Reference< XEventListener > xMeMyselfAndI = this;
72 		_rxComp->addEventListener(xMeMyselfAndI);
73 
74 		m_xComponent = _rxComp;
75 		m_xKeepMeAlive = xMeMyselfAndI;
76 	}
77 
78 	//---------------------------------------------------------------------
dispose()79 	void OEventListenerImpl::dispose()
80 	{
81 		if (m_xComponent.is())
82 		{
83 			m_xComponent->removeEventListener(m_xKeepMeAlive);
84 			m_xComponent.clear();
85 			m_xKeepMeAlive.clear();
86 		}
87 	}
88 
89 	//---------------------------------------------------------------------
disposing(const EventObject & _rSource)90 	void SAL_CALL OEventListenerImpl::disposing( const EventObject& _rSource ) throw (RuntimeException)
91 	{
92 		Reference< XEventListener > xDeleteUponLeaving = m_xKeepMeAlive;
93 		m_xKeepMeAlive.clear();
94 		m_xComponent.clear();
95 
96 		m_pAdapter->_disposing(_rSource);
97 	}
98 
99 	//=====================================================================
100 	//= OEventListenerAdapterImpl
101 	//=====================================================================
102 	struct OEventListenerAdapterImpl
103 	{
104 	public:
105 		::std::vector< void* >	aListeners;
106 	};
107 
108 	//=====================================================================
109 	//= OEventListenerAdapter
110 	//=====================================================================
111 	//---------------------------------------------------------------------
OEventListenerAdapter()112 	OEventListenerAdapter::OEventListenerAdapter()
113 		:m_pImpl(new OEventListenerAdapterImpl)
114 	{
115 	}
116 
117 	//---------------------------------------------------------------------
~OEventListenerAdapter()118 	OEventListenerAdapter::~OEventListenerAdapter()
119 	{
120 		stopAllComponentListening( );
121 		delete m_pImpl;
122 		m_pImpl = NULL;
123 	}
124 
125 	//---------------------------------------------------------------------
stopComponentListening(const::com::sun::star::uno::Reference<::com::sun::star::lang::XComponent> & _rxComp)126 	void OEventListenerAdapter::stopComponentListening( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent >& _rxComp )
127 	{
128         if ( m_pImpl->aListeners.empty() )
129             return;
130 
131         ::std::vector< void* >::iterator dispose = m_pImpl->aListeners.begin();
132         do
133         {
134             OEventListenerImpl* pListenerImpl = static_cast< OEventListenerImpl* >( *dispose );
135             if ( pListenerImpl->getComponent().get() == _rxComp.get() )
136             {
137                 pListenerImpl->dispose();
138                 pListenerImpl->release();
139                 dispose = m_pImpl->aListeners.erase( dispose );
140             }
141             else
142                 ++dispose;
143         }
144         while ( dispose != m_pImpl->aListeners.end() );
145 	}
146 
147 	//---------------------------------------------------------------------
stopAllComponentListening()148 	void OEventListenerAdapter::stopAllComponentListening(  )
149 	{
150 		for (	::std::vector< void* >::const_iterator aDisposeLoop = m_pImpl->aListeners.begin();
151 				aDisposeLoop != m_pImpl->aListeners.end();
152 				++aDisposeLoop
153 			)
154 		{
155 			OEventListenerImpl* pListenerImpl = static_cast< OEventListenerImpl* >(*aDisposeLoop);
156 			pListenerImpl->dispose();
157 			pListenerImpl->release();
158 		}
159 		m_pImpl->aListeners.clear();
160 	}
161 
162 	//---------------------------------------------------------------------
startComponentListening(const Reference<XComponent> & _rxComp)163 	void OEventListenerAdapter::startComponentListening( const Reference< XComponent >& _rxComp )
164 	{
165 		if (!_rxComp.is())
166 		{
167 			OSL_ENSURE(sal_False, "OEventListenerAdapter::startComponentListening: invalid component!");
168 			return;
169 		}
170 
171 		OEventListenerImpl* pListenerImpl = new OEventListenerImpl(this, _rxComp);
172 		pListenerImpl->acquire();
173 		m_pImpl->aListeners.push_back(pListenerImpl);
174 	}
175 
176 //.........................................................................
177 }	// namespace utl
178 //.........................................................................
179