xref: /trunk/main/chart2/source/inc/ModifyListenerHelper.hxx (revision 91144cd0085a7583d2099b982122deb2184ab956)
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     virtual void SAL_CALL removeModifyListener(
87         const ::com::sun::star::uno::Reference< ::com::sun::star::util::XModifyListener >& aListener );
88 
89     // ____ XModifyListener ____
90     virtual void SAL_CALL modified(
91         const ::com::sun::star::lang::EventObject& aEvent );
92 
93     // ____ XEventListener (base of XModifyListener) ____
94     virtual void SAL_CALL disposing(
95         const ::com::sun::star::lang::EventObject& Source );
96 
97     // ____ WeakComponentImplHelperBase ____
98     virtual void SAL_CALL disposing();
99 
100 private:
101     /// call disposing() at all listeners and remove all listeners
102     void DisposeAndClear( const ::com::sun::star::uno::Reference<
103                               ::com::sun::star::uno::XWeak > & xSource );
104 
105 //     ::osl::Mutex & m_rMutex;
106     ::cppu::OBroadcastHelper  m_aModifyListeners;
107 
108     typedef ::std::list<
109             ::std::pair<
110             ::com::sun::star::uno::WeakReference< ::com::sun::star::util::XModifyListener >,
111             ::com::sun::star::uno::Reference< ::com::sun::star::util::XModifyListener > > >
112         tListenerMap;
113 
114     tListenerMap m_aListenerMap;
115 };
116 
117 // ================================================================================
118 
119 namespace impl
120 {
121 
122 template< class InterfaceRef >
123 struct addListenerFunctor : public ::std::unary_function< InterfaceRef, void >
124 {
addListenerFunctorchart::ModifyListenerHelper::impl::addListenerFunctor125     explicit addListenerFunctor( const ::com::sun::star::uno::Reference<
126                                      ::com::sun::star::util::XModifyListener > & xListener ) :
127             m_xListener( xListener )
128     {}
129 
operator ()chart::ModifyListenerHelper::impl::addListenerFunctor130     void operator() ( const InterfaceRef & xObject )
131     {
132         ::com::sun::star::uno::Reference< ::com::sun::star::util::XModifyBroadcaster >
133               xBroadcaster( xObject, ::com::sun::star::uno::UNO_QUERY );
134         if( xBroadcaster.is() && m_xListener.is())
135             xBroadcaster->addModifyListener( m_xListener );
136     }
137 private:
138     ::com::sun::star::uno::Reference< ::com::sun::star::util::XModifyListener > m_xListener;
139 };
140 
141 template< class InterfaceRef >
142 struct removeListenerFunctor : public ::std::unary_function< InterfaceRef, void >
143 {
removeListenerFunctorchart::ModifyListenerHelper::impl::removeListenerFunctor144     explicit removeListenerFunctor( const ::com::sun::star::uno::Reference<
145                                         ::com::sun::star::util::XModifyListener > & xListener ) :
146             m_xListener( xListener )
147     {}
148 
operator ()chart::ModifyListenerHelper::impl::removeListenerFunctor149     void operator() ( const InterfaceRef & xObject )
150     {
151         ::com::sun::star::uno::Reference< ::com::sun::star::util::XModifyBroadcaster >
152               xBroadcaster( xObject, ::com::sun::star::uno::UNO_QUERY );
153         if( xBroadcaster.is() && m_xListener.is())
154             xBroadcaster->removeModifyListener( m_xListener );
155     }
156 private:
157     ::com::sun::star::uno::Reference< ::com::sun::star::util::XModifyListener > m_xListener;
158 };
159 
160 template< class Pair >
161 struct addListenerToMappedElementFunctor : public ::std::unary_function< Pair, void >
162 {
addListenerToMappedElementFunctorchart::ModifyListenerHelper::impl::addListenerToMappedElementFunctor163     explicit addListenerToMappedElementFunctor( const ::com::sun::star::uno::Reference<
164                                                     ::com::sun::star::util::XModifyListener > & xListener ) :
165             m_xListener( xListener )
166     {}
167 
operator ()chart::ModifyListenerHelper::impl::addListenerToMappedElementFunctor168     void operator() ( const Pair & aPair )
169     {
170         ::com::sun::star::uno::Reference< ::com::sun::star::util::XModifyBroadcaster >
171               xBroadcaster( aPair.second, ::com::sun::star::uno::UNO_QUERY );
172         if( xBroadcaster.is() && m_xListener.is())
173             xBroadcaster->addModifyListener( m_xListener );
174     }
175 private:
176     ::com::sun::star::uno::Reference< ::com::sun::star::util::XModifyListener > m_xListener;
177 };
178 
179 template< class Pair >
180 struct removeListenerFromMappedElementFunctor : public ::std::unary_function< Pair, void >
181 {
removeListenerFromMappedElementFunctorchart::ModifyListenerHelper::impl::removeListenerFromMappedElementFunctor182     explicit removeListenerFromMappedElementFunctor( const ::com::sun::star::uno::Reference<
183                                                          ::com::sun::star::util::XModifyListener > & xListener ) :
184             m_xListener( xListener )
185     {}
186 
operator ()chart::ModifyListenerHelper::impl::removeListenerFromMappedElementFunctor187     void operator() ( const Pair & aPair )
188     {
189         ::com::sun::star::uno::Reference< ::com::sun::star::util::XModifyBroadcaster >
190               xBroadcaster( aPair.second, ::com::sun::star::uno::UNO_QUERY );
191         if( xBroadcaster.is() && m_xListener.is())
192             xBroadcaster->removeModifyListener( m_xListener );
193     }
194 private:
195     ::com::sun::star::uno::Reference< ::com::sun::star::util::XModifyListener > m_xListener;
196 };
197 
198 } //  namespace impl
199 
200 // --------------------------------------------------------------------------------
201 
202 
203 template< class InterfaceRef >
addListener(const InterfaceRef & xObject,const::com::sun::star::uno::Reference<::com::sun::star::util::XModifyListener> & xListener)204 void addListener(
205     const InterfaceRef & xObject,
206     const ::com::sun::star::uno::Reference<
207         ::com::sun::star::util::XModifyListener > & xListener )
208 {
209     if( xListener.is())
210     {
211         impl::addListenerFunctor< InterfaceRef > aFunctor( xListener );
212         aFunctor( xObject );
213     }
214 }
215 
216 template< class Container >
addListenerToAllElements(const Container & rContainer,const::com::sun::star::uno::Reference<::com::sun::star::util::XModifyListener> & xListener)217 void addListenerToAllElements(
218     const Container & rContainer,
219     const ::com::sun::star::uno::Reference<
220         ::com::sun::star::util::XModifyListener > & xListener )
221 {
222     if( xListener.is())
223         ::std::for_each( rContainer.begin(), rContainer.end(),
224                          impl::addListenerFunctor< typename Container::value_type >( xListener ));
225 }
226 
227 template< class Container >
addListenerToAllMapElements(const Container & rContainer,const::com::sun::star::uno::Reference<::com::sun::star::util::XModifyListener> & xListener)228 void addListenerToAllMapElements(
229     const Container & rContainer,
230     const ::com::sun::star::uno::Reference<
231         ::com::sun::star::util::XModifyListener > & xListener )
232 {
233     if( xListener.is())
234         ::std::for_each( rContainer.begin(), rContainer.end(),
235                          impl::addListenerToMappedElementFunctor< typename Container::value_type >( xListener ));
236 }
237 
238 template< typename T >
addListenerToAllSequenceElements(const::com::sun::star::uno::Sequence<T> & rSequence,const::com::sun::star::uno::Reference<::com::sun::star::util::XModifyListener> & xListener)239 void addListenerToAllSequenceElements(
240     const ::com::sun::star::uno::Sequence< T > & rSequence,
241     const ::com::sun::star::uno::Reference<
242         ::com::sun::star::util::XModifyListener > & xListener )
243 {
244     if( xListener.is())
245         ::std::for_each( rSequence.getConstArray(), rSequence.getConstArray() + rSequence.getLength(),
246                          impl::addListenerFunctor< T >( xListener ));
247 }
248 
249 template< class InterfaceRef >
removeListener(const InterfaceRef & xObject,const::com::sun::star::uno::Reference<::com::sun::star::util::XModifyListener> & xListener)250 void removeListener(
251     const InterfaceRef & xObject,
252     const ::com::sun::star::uno::Reference<
253         ::com::sun::star::util::XModifyListener > & xListener )
254 {
255     if( xListener.is())
256     {
257         impl::removeListenerFunctor< InterfaceRef > aFunctor( xListener );
258         aFunctor( xObject );
259     }
260 }
261 
262 template< class Container >
removeListenerFromAllElements(const Container & rContainer,const::com::sun::star::uno::Reference<::com::sun::star::util::XModifyListener> & xListener)263 void removeListenerFromAllElements(
264     const Container & rContainer,
265     const ::com::sun::star::uno::Reference<
266         ::com::sun::star::util::XModifyListener > & xListener )
267 {
268     if( xListener.is())
269         ::std::for_each( rContainer.begin(), rContainer.end(),
270                          impl::removeListenerFunctor< typename Container::value_type >( xListener ));
271 }
272 
273 template< class Container >
removeListenerFromAllMapElements(const Container & rContainer,const::com::sun::star::uno::Reference<::com::sun::star::util::XModifyListener> & xListener)274 void removeListenerFromAllMapElements(
275     const Container & rContainer,
276     const ::com::sun::star::uno::Reference<
277         ::com::sun::star::util::XModifyListener > & xListener )
278 {
279     if( xListener.is())
280         ::std::for_each( rContainer.begin(), rContainer.end(),
281                          impl::removeListenerFromMappedElementFunctor< typename Container::value_type >( xListener ));
282 }
283 
284 template< typename T >
removeListenerFromAllSequenceElements(const::com::sun::star::uno::Sequence<T> & rSequence,const::com::sun::star::uno::Reference<::com::sun::star::util::XModifyListener> & xListener)285 void removeListenerFromAllSequenceElements(
286     const ::com::sun::star::uno::Sequence< T > & rSequence,
287     const ::com::sun::star::uno::Reference<
288         ::com::sun::star::util::XModifyListener > & xListener )
289 {
290     if( xListener.is())
291         ::std::for_each( rSequence.getConstArray(), rSequence.getConstArray() + rSequence.getLength(),
292                          impl::removeListenerFunctor< T >( xListener ));
293 }
294 
295 } //  namespace ModifyListenerHelper
296 } //  namespace chart
297 
298 // CHART2_MODIFYLISTENERHELPER_HXX
299 #endif
300