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_chart2.hxx"
26
27 #include "ModifyListenerHelper.hxx"
28 #include "WeakListenerAdapter.hxx"
29 #include "macros.hxx"
30
31 #include <cppuhelper/interfacecontainer.hxx>
32
33 #include <com/sun/star/frame/XModel.hpp>
34
35 using namespace ::com::sun::star;
36
37 using ::com::sun::star::uno::Reference;
38 using ::com::sun::star::uno::Sequence;
39 using ::rtl::OUString;
40
41 namespace
42 {
43
lcl_fireModifyEvent(::cppu::OBroadcastHelper & rBroadcastHelper,const Reference<uno::XWeak> & xEventSource,const lang::EventObject * pEvent)44 void lcl_fireModifyEvent(
45 ::cppu::OBroadcastHelper & rBroadcastHelper,
46 const Reference< uno::XWeak > & xEventSource,
47 const lang::EventObject * pEvent )
48 {
49 ::cppu::OInterfaceContainerHelper * pCntHlp = rBroadcastHelper.getContainer(
50 ::getCppuType( reinterpret_cast< Reference< util::XModifyListener > * >(0)));
51 if( pCntHlp )
52 {
53 lang::EventObject aEventToSend;
54 if( pEvent )
55 aEventToSend = *pEvent;
56 else
57 aEventToSend.Source.set( xEventSource );
58 OSL_ENSURE( aEventToSend.Source.is(), "Sending event without source" );
59
60 ::cppu::OInterfaceIteratorHelper aIt( *pCntHlp );
61
62 while( aIt.hasMoreElements())
63 {
64 Reference< util::XModifyListener > xModListener( aIt.next(), uno::UNO_QUERY );
65 if( xModListener.is())
66 xModListener->modified( aEventToSend );
67 }
68 }
69 }
70
71 struct lcl_weakReferenceToSame : public ::std::unary_function<
72 ::std::pair<
73 ::com::sun::star::uno::WeakReference< ::com::sun::star::util::XModifyListener >,
74 ::com::sun::star::uno::Reference< ::com::sun::star::util::XModifyListener > >,
75 bool >
76 {
lcl_weakReferenceToSame__anon8f820fb00111::lcl_weakReferenceToSame77 lcl_weakReferenceToSame( const Reference< util::XModifyListener > & xModListener ) :
78 m_xHardRef( xModListener )
79 {}
80
operator ()__anon8f820fb00111::lcl_weakReferenceToSame81 bool operator() ( const argument_type & xElem )
82 {
83 Reference< util::XModifyListener > xWeakAsHard( xElem.first );
84 if( xWeakAsHard.is())
85 return (xWeakAsHard == m_xHardRef);
86 return false;
87 }
88
89 private:
90 Reference< util::XModifyListener > m_xHardRef;
91 };
92
93 } // anonymous namespace
94
95 // ================================================================================
96
97 namespace chart
98 {
99 namespace ModifyListenerHelper
100 {
101
createModifyEventForwarder()102 uno::Reference< util::XModifyListener > createModifyEventForwarder()
103 {
104 return new ModifyEventForwarder();
105 }
106
ModifyEventForwarder()107 ModifyEventForwarder::ModifyEventForwarder() :
108 ::cppu::WeakComponentImplHelper2<
109 ::com::sun::star::util::XModifyBroadcaster,
110 ::com::sun::star::util::XModifyListener >( m_aMutex ),
111 m_aModifyListeners( m_aMutex )
112 {
113 }
114
FireEvent(const lang::EventObject & rEvent)115 void ModifyEventForwarder::FireEvent( const lang::EventObject & rEvent )
116 {
117 lcl_fireModifyEvent( m_aModifyListeners, Reference< uno::XWeak >(), & rEvent );
118 }
119
AddListener(const Reference<util::XModifyListener> & aListener)120 void ModifyEventForwarder::AddListener( const Reference< util::XModifyListener >& aListener )
121 {
122 try
123 {
124 Reference< util::XModifyListener > xListenerToAdd( aListener );
125
126 Reference< uno::XWeak > xWeak( aListener, uno::UNO_QUERY );
127 if( xWeak.is())
128 {
129 // remember the helper class for later remove
130 uno::WeakReference< util::XModifyListener > xWeakRef( aListener );
131 xListenerToAdd.set( new WeakModifyListenerAdapter( xWeakRef ));
132 m_aListenerMap.push_back( tListenerMap::value_type( xWeakRef, xListenerToAdd ));
133 }
134
135 m_aModifyListeners.addListener( ::getCppuType( &xListenerToAdd ), xListenerToAdd );
136 }
137 catch( const uno::Exception & ex )
138 {
139 ASSERT_EXCEPTION( ex );
140 }
141 }
142
RemoveListener(const Reference<util::XModifyListener> & aListener)143 void ModifyEventForwarder::RemoveListener( const Reference< util::XModifyListener >& aListener )
144 {
145 try
146 {
147 // look up fitting helper class that has been added
148 Reference< util::XModifyListener > xListenerToRemove( aListener );
149 tListenerMap::iterator aIt(
150 ::std::find_if( m_aListenerMap.begin(), m_aListenerMap.end(), lcl_weakReferenceToSame( aListener )));
151 if( aIt != m_aListenerMap.end())
152 {
153 xListenerToRemove.set( (*aIt).second );
154 // map entry is no longer needed
155 m_aListenerMap.erase( aIt );
156 }
157
158 m_aModifyListeners.removeListener( ::getCppuType( &aListener ), xListenerToRemove );
159 }
160 catch( const uno::Exception & ex )
161 {
162 ASSERT_EXCEPTION( ex );
163 }
164 }
165
DisposeAndClear(const Reference<uno::XWeak> & xSource)166 void ModifyEventForwarder::DisposeAndClear( const Reference< uno::XWeak > & xSource )
167 {
168 ::cppu::OInterfaceContainerHelper * pCntHlp = m_aModifyListeners.getContainer(
169 ::getCppuType( reinterpret_cast< Reference< util::XModifyListener > * >(0)));
170 if( pCntHlp )
171 pCntHlp->disposeAndClear( lang::EventObject( xSource ) );
172 }
173
174 // ____ XModifyBroadcaster ____
addModifyListener(const Reference<util::XModifyListener> & aListener)175 void SAL_CALL ModifyEventForwarder::addModifyListener( const Reference< util::XModifyListener >& aListener )
176 throw (uno::RuntimeException)
177 {
178 AddListener( aListener );
179 }
180
removeModifyListener(const Reference<util::XModifyListener> & aListener)181 void SAL_CALL ModifyEventForwarder::removeModifyListener( const Reference< util::XModifyListener >& aListener )
182 throw (uno::RuntimeException)
183 {
184 RemoveListener( aListener );
185 }
186
187 // ____ XModifyListener ____
modified(const lang::EventObject & aEvent)188 void SAL_CALL ModifyEventForwarder::modified( const lang::EventObject& aEvent )
189 throw (uno::RuntimeException)
190 {
191 FireEvent( aEvent );
192 }
193
194 // ____ XEventListener (base of XModifyListener) ____
disposing(const lang::EventObject &)195 void SAL_CALL ModifyEventForwarder::disposing( const lang::EventObject& /* Source */ )
196 throw (uno::RuntimeException)
197 {
198 // nothing
199 }
200
201 // ____ WeakComponentImplHelperBase ____
disposing()202 void SAL_CALL ModifyEventForwarder::disposing()
203 {
204 // dispose was called at this
205 DisposeAndClear( this );
206 }
207
208 } // namespace ModifyListenerHelper
209 } // namespace chart
210