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 #ifndef CHART2_MODIFYLISTENERHELPER_HXX
24 #define CHART2_MODIFYLISTENERHELPER_HXX
25
26 #include <cppuhelper/interfacecontainer.hxx>
27 #include <com/sun/star/util/XModifyListener.hpp>
28 #include <com/sun/star/util/XModifyBroadcaster.hpp>
29 #include <com/sun/star/util/XModifiable.hpp>
30 #include <com/sun/star/uno/XWeak.hpp>
31 #include <cppuhelper/implbase1.hxx>
32 #include <cppuhelper/compbase2.hxx>
33 #include <cppuhelper/weakref.hxx>
34
35 #include "MutexContainer.hxx"
36 #include "charttoolsdllapi.hxx"
37
38 #include <list>
39 #include <algorithm>
40 #include <functional>
41 #include <utility>
42
43 namespace com { namespace sun { namespace star {
44 namespace chart2
45 {
46 class XChartDocument;
47 }}}}
48
49 namespace chart
50 {
51 namespace ModifyListenerHelper
52 {
53
54 OOO_DLLPUBLIC_CHARTTOOLS ::com::sun::star::uno::Reference< ::com::sun::star::util::XModifyListener > createModifyEventForwarder();
55
56 // ================================================================================
57
58 /** This helper class serves as forwarder of modify events. It can be used
59 whenever an object has to send modify events after it gets a modify event of
60 one of its children.
61
62 <p>The listeners are held as WeakReferences if they support XWeak. Thus the
63 life time of the listeners is independent of the broadcaster's lifetime in
64 this case.</p>
65 */
66 class ModifyEventForwarder :
67 public MutexContainer,
68 public ::cppu::WeakComponentImplHelper2<
69 ::com::sun::star::util::XModifyBroadcaster,
70 ::com::sun::star::util::XModifyListener >
71 {
72 public:
73 ModifyEventForwarder();
74
75 void FireEvent( const ::com::sun::star::lang::EventObject & rEvent );
76
77 void AddListener(
78 const ::com::sun::star::uno::Reference< ::com::sun::star::util::XModifyListener >& aListener );
79 void RemoveListener(
80 const ::com::sun::star::uno::Reference< ::com::sun::star::util::XModifyListener >& aListener );
81
82 protected:
83 // ____ XModifyBroadcaster ____
84 virtual void SAL_CALL addModifyListener(
85 const ::com::sun::star::uno::Reference< ::com::sun::star::util::XModifyListener >& aListener )
86 throw (::com::sun::star::uno::RuntimeException);
87 virtual void SAL_CALL removeModifyListener(
88 const ::com::sun::star::uno::Reference< ::com::sun::star::util::XModifyListener >& aListener )
89 throw (::com::sun::star::uno::RuntimeException);
90
91 // ____ XModifyListener ____
92 virtual void SAL_CALL modified(
93 const ::com::sun::star::lang::EventObject& aEvent )
94 throw (::com::sun::star::uno::RuntimeException);
95
96 // ____ XEventListener (base of XModifyListener) ____
97 virtual void SAL_CALL disposing(
98 const ::com::sun::star::lang::EventObject& Source )
99 throw (::com::sun::star::uno::RuntimeException);
100
101 // ____ WeakComponentImplHelperBase ____
102 virtual void SAL_CALL disposing();
103
104 private:
105 /// call disposing() at all listeners and remove all listeners
106 void DisposeAndClear( const ::com::sun::star::uno::Reference<
107 ::com::sun::star::uno::XWeak > & xSource );
108
109 // ::osl::Mutex & m_rMutex;
110 ::cppu::OBroadcastHelper m_aModifyListeners;
111
112 typedef ::std::list<
113 ::std::pair<
114 ::com::sun::star::uno::WeakReference< ::com::sun::star::util::XModifyListener >,
115 ::com::sun::star::uno::Reference< ::com::sun::star::util::XModifyListener > > >
116 tListenerMap;
117
118 tListenerMap m_aListenerMap;
119 };
120
121 // ================================================================================
122
123 namespace impl
124 {
125
126 template< class InterfaceRef >
127 struct addListenerFunctor : public ::std::unary_function< InterfaceRef, void >
128 {
addListenerFunctorchart::ModifyListenerHelper::impl::addListenerFunctor129 explicit addListenerFunctor( const ::com::sun::star::uno::Reference<
130 ::com::sun::star::util::XModifyListener > & xListener ) :
131 m_xListener( xListener )
132 {}
133
operator ()chart::ModifyListenerHelper::impl::addListenerFunctor134 void operator() ( const InterfaceRef & xObject )
135 {
136 ::com::sun::star::uno::Reference< ::com::sun::star::util::XModifyBroadcaster >
137 xBroadcaster( xObject, ::com::sun::star::uno::UNO_QUERY );
138 if( xBroadcaster.is() && m_xListener.is())
139 xBroadcaster->addModifyListener( m_xListener );
140 }
141 private:
142 ::com::sun::star::uno::Reference< ::com::sun::star::util::XModifyListener > m_xListener;
143 };
144
145 template< class InterfaceRef >
146 struct removeListenerFunctor : public ::std::unary_function< InterfaceRef, void >
147 {
removeListenerFunctorchart::ModifyListenerHelper::impl::removeListenerFunctor148 explicit removeListenerFunctor( const ::com::sun::star::uno::Reference<
149 ::com::sun::star::util::XModifyListener > & xListener ) :
150 m_xListener( xListener )
151 {}
152
operator ()chart::ModifyListenerHelper::impl::removeListenerFunctor153 void operator() ( const InterfaceRef & xObject )
154 {
155 ::com::sun::star::uno::Reference< ::com::sun::star::util::XModifyBroadcaster >
156 xBroadcaster( xObject, ::com::sun::star::uno::UNO_QUERY );
157 if( xBroadcaster.is() && m_xListener.is())
158 xBroadcaster->removeModifyListener( m_xListener );
159 }
160 private:
161 ::com::sun::star::uno::Reference< ::com::sun::star::util::XModifyListener > m_xListener;
162 };
163
164 template< class Pair >
165 struct addListenerToMappedElementFunctor : public ::std::unary_function< Pair, void >
166 {
addListenerToMappedElementFunctorchart::ModifyListenerHelper::impl::addListenerToMappedElementFunctor167 explicit addListenerToMappedElementFunctor( const ::com::sun::star::uno::Reference<
168 ::com::sun::star::util::XModifyListener > & xListener ) :
169 m_xListener( xListener )
170 {}
171
operator ()chart::ModifyListenerHelper::impl::addListenerToMappedElementFunctor172 void operator() ( const Pair & aPair )
173 {
174 ::com::sun::star::uno::Reference< ::com::sun::star::util::XModifyBroadcaster >
175 xBroadcaster( aPair.second, ::com::sun::star::uno::UNO_QUERY );
176 if( xBroadcaster.is() && m_xListener.is())
177 xBroadcaster->addModifyListener( m_xListener );
178 }
179 private:
180 ::com::sun::star::uno::Reference< ::com::sun::star::util::XModifyListener > m_xListener;
181 };
182
183 template< class Pair >
184 struct removeListenerFromMappedElementFunctor : public ::std::unary_function< Pair, void >
185 {
removeListenerFromMappedElementFunctorchart::ModifyListenerHelper::impl::removeListenerFromMappedElementFunctor186 explicit removeListenerFromMappedElementFunctor( const ::com::sun::star::uno::Reference<
187 ::com::sun::star::util::XModifyListener > & xListener ) :
188 m_xListener( xListener )
189 {}
190
operator ()chart::ModifyListenerHelper::impl::removeListenerFromMappedElementFunctor191 void operator() ( const Pair & aPair )
192 {
193 ::com::sun::star::uno::Reference< ::com::sun::star::util::XModifyBroadcaster >
194 xBroadcaster( aPair.second, ::com::sun::star::uno::UNO_QUERY );
195 if( xBroadcaster.is() && m_xListener.is())
196 xBroadcaster->removeModifyListener( m_xListener );
197 }
198 private:
199 ::com::sun::star::uno::Reference< ::com::sun::star::util::XModifyListener > m_xListener;
200 };
201
202 } // namespace impl
203
204 // --------------------------------------------------------------------------------
205
206
207 template< class InterfaceRef >
addListener(const InterfaceRef & xObject,const::com::sun::star::uno::Reference<::com::sun::star::util::XModifyListener> & xListener)208 void addListener(
209 const InterfaceRef & xObject,
210 const ::com::sun::star::uno::Reference<
211 ::com::sun::star::util::XModifyListener > & xListener )
212 {
213 if( xListener.is())
214 {
215 impl::addListenerFunctor< InterfaceRef > aFunctor( xListener );
216 aFunctor( xObject );
217 }
218 }
219
220 template< class Container >
addListenerToAllElements(const Container & rContainer,const::com::sun::star::uno::Reference<::com::sun::star::util::XModifyListener> & xListener)221 void addListenerToAllElements(
222 const Container & rContainer,
223 const ::com::sun::star::uno::Reference<
224 ::com::sun::star::util::XModifyListener > & xListener )
225 {
226 if( xListener.is())
227 ::std::for_each( rContainer.begin(), rContainer.end(),
228 impl::addListenerFunctor< typename Container::value_type >( xListener ));
229 }
230
231 template< class Container >
addListenerToAllMapElements(const Container & rContainer,const::com::sun::star::uno::Reference<::com::sun::star::util::XModifyListener> & xListener)232 void addListenerToAllMapElements(
233 const Container & rContainer,
234 const ::com::sun::star::uno::Reference<
235 ::com::sun::star::util::XModifyListener > & xListener )
236 {
237 if( xListener.is())
238 ::std::for_each( rContainer.begin(), rContainer.end(),
239 impl::addListenerToMappedElementFunctor< typename Container::value_type >( xListener ));
240 }
241
242 template< typename T >
addListenerToAllSequenceElements(const::com::sun::star::uno::Sequence<T> & rSequence,const::com::sun::star::uno::Reference<::com::sun::star::util::XModifyListener> & xListener)243 void addListenerToAllSequenceElements(
244 const ::com::sun::star::uno::Sequence< T > & rSequence,
245 const ::com::sun::star::uno::Reference<
246 ::com::sun::star::util::XModifyListener > & xListener )
247 {
248 if( xListener.is())
249 ::std::for_each( rSequence.getConstArray(), rSequence.getConstArray() + rSequence.getLength(),
250 impl::addListenerFunctor< T >( xListener ));
251 }
252
253 template< class InterfaceRef >
removeListener(const InterfaceRef & xObject,const::com::sun::star::uno::Reference<::com::sun::star::util::XModifyListener> & xListener)254 void removeListener(
255 const InterfaceRef & xObject,
256 const ::com::sun::star::uno::Reference<
257 ::com::sun::star::util::XModifyListener > & xListener )
258 {
259 if( xListener.is())
260 {
261 impl::removeListenerFunctor< InterfaceRef > aFunctor( xListener );
262 aFunctor( xObject );
263 }
264 }
265
266 template< class Container >
removeListenerFromAllElements(const Container & rContainer,const::com::sun::star::uno::Reference<::com::sun::star::util::XModifyListener> & xListener)267 void removeListenerFromAllElements(
268 const Container & rContainer,
269 const ::com::sun::star::uno::Reference<
270 ::com::sun::star::util::XModifyListener > & xListener )
271 {
272 if( xListener.is())
273 ::std::for_each( rContainer.begin(), rContainer.end(),
274 impl::removeListenerFunctor< typename Container::value_type >( xListener ));
275 }
276
277 template< class Container >
removeListenerFromAllMapElements(const Container & rContainer,const::com::sun::star::uno::Reference<::com::sun::star::util::XModifyListener> & xListener)278 void removeListenerFromAllMapElements(
279 const Container & rContainer,
280 const ::com::sun::star::uno::Reference<
281 ::com::sun::star::util::XModifyListener > & xListener )
282 {
283 if( xListener.is())
284 ::std::for_each( rContainer.begin(), rContainer.end(),
285 impl::removeListenerFromMappedElementFunctor< typename Container::value_type >( xListener ));
286 }
287
288 template< typename T >
removeListenerFromAllSequenceElements(const::com::sun::star::uno::Sequence<T> & rSequence,const::com::sun::star::uno::Reference<::com::sun::star::util::XModifyListener> & xListener)289 void removeListenerFromAllSequenceElements(
290 const ::com::sun::star::uno::Sequence< T > & rSequence,
291 const ::com::sun::star::uno::Reference<
292 ::com::sun::star::util::XModifyListener > & xListener )
293 {
294 if( xListener.is())
295 ::std::for_each( rSequence.getConstArray(), rSequence.getConstArray() + rSequence.getLength(),
296 impl::removeListenerFunctor< T >( xListener ));
297 }
298
299 } // namespace ModifyListenerHelper
300 } // namespace chart
301
302 // CHART2_MODIFYLISTENERHELPER_HXX
303 #endif
304