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