xref: /AOO41X/main/unotools/source/misc/eventlisteneradapter.cxx (revision b5088357f810cb81479bbbd0e021cd3c9835ca0d)
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