xref: /trunk/main/winaccessibility/source/service/AccEventListener.cxx (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 #include <cppuhelper/bootstrap.hxx>
23 #include <com/sun/star/bridge/XUnoUrlResolver.hpp>
24 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
25 #include <toolkit/awt/Vclxwindow.hxx>
26 
27 #ifndef _SV_SYSDATA_HXX
28 #if defined( WIN ) || defined( WNT ) || defined( OS2 )
29 typedef void* HWND;
30 #endif
31 #endif
32 #include "AccEventListener.hxx"
33 #include "AccObjectManagerAgent.hxx"
34 #include "unomsaaevent.hxx"
35 
36 #include <com/sun/star/accessibility/XAccessible.hpp>
37 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
38 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
39 #include <com/sun/star/accessibility/AccessibleRole.hpp>
40 #include <com/sun/star/accessibility/XAccessibleEventBroadcaster.hpp>
41 #include <com/sun/star/accessibility/XAccessibleComponent.hpp>
42 
43 #include <stdio.h>
44 
45 using namespace com::sun::star::uno;
46 using namespace com::sun::star::accessibility;
47 using namespace rtl;
48 using namespace cppu;
49 
AccEventListener(com::sun::star::accessibility::XAccessible * pAcc,AccObjectManagerAgent * Agent)50 AccEventListener::AccEventListener(com::sun::star::accessibility::XAccessible* pAcc,
51                                    AccObjectManagerAgent* Agent)
52         :pAccessible(pAcc),
53         pAgent(Agent),
54         m_isDisposed(false),
55         m_refcount(0)
56 {}
57 
~AccEventListener()58 AccEventListener::~AccEventListener()
59 {
60 }
61 
62 /**
63  *  Uno's event notifier when event is captured
64  *  @param AccessibleEventObject    the event object which contains information about event
65  */
notifyEvent(const::com::sun::star::accessibility::AccessibleEventObject & aEvent)66 void  AccEventListener::notifyEvent( const ::com::sun::star::accessibility::AccessibleEventObject& aEvent )
67 {
68 
69     switch (aEvent.EventId)
70     {
71     case AccessibleEventId::NAME_CHANGED:
72         handleNameChangedEvent(aEvent.NewValue);
73         break;
74     case AccessibleEventId::DESCRIPTION_CHANGED:
75         handleDescriptionChangedEvent(aEvent.NewValue);
76         break;
77     case AccessibleEventId::STATE_CHANGED:
78         handleStateChangedEvent(aEvent.OldValue, aEvent.NewValue);
79         break;
80     default:
81         break;
82     }
83 }
84 
85 /**
86  *  handle the NAME_CHANGED event
87  *  @param  name        the new name with changed.
88  */
handleNameChangedEvent(Any name)89 void AccEventListener::handleNameChangedEvent(Any name)
90 {
91     if ( pAgent->IsTopWinAcc( pAccessible ) )
92     {
93         XAccessible* pAccDoc = pAgent->GetAccDocByAccTopWin( pAccessible );
94         if ( pAccDoc )
95         {
96             pAgent->UpdateAccName(pAccDoc);
97             pAgent->NotifyAccEvent(UM_EVENT_OBJECT_NAMECHANGE, pAccDoc);
98         }
99     }
100 
101     pAgent->UpdateAccName(pAccessible, name);
102     pAgent->NotifyAccEvent(UM_EVENT_OBJECT_NAMECHANGE, pAccessible);
103 }
104 
105 /**
106  *  handle the DESCRIPTION_CHANGED event
107  *  @param  desc        the new description
108  */
handleDescriptionChangedEvent(Any desc)109 void AccEventListener::handleDescriptionChangedEvent(Any desc)
110 {
111     pAgent->UpdateDescription(pAccessible, desc);
112     pAgent->NotifyAccEvent(UM_EVENT_OBJECT_DESCRIPTIONCHANGE, pAccessible);
113 }
114 
115 /**
116  *  handle the BOUNDRECT_CHANGED event
117  */
handleBoundrectChangedEvent()118 void AccEventListener::handleBoundrectChangedEvent()
119 {
120     pAgent->UpdateLocation(pAccessible);
121     pAgent->NotifyAccEvent(UM_EVENT_BOUNDRECT_CHANGED, pAccessible);
122 }
123 
124 /**
125  *  handle the VISIBLE_DATA_CHANGED event
126  */
handleVisibleDataChangedEvent()127 void AccEventListener::handleVisibleDataChangedEvent()
128 {
129     pAgent->UpdateValue(pAccessible);
130     pAgent->NotifyAccEvent(UM_EVENT_VISIBLE_DATA_CHANGED, pAccessible);
131 }
132 
133 /**
134  *  handle the STATE_CHANGED event
135  *  @param  oldValue    the old state of the source of event
136  *  @param  newValue    the new state of the source of event
137  */
handleStateChangedEvent(Any oldValue,Any newValue)138 void AccEventListener::handleStateChangedEvent(Any oldValue, Any newValue)
139 {
140     short newV, oldV;
141     if( newValue >>= newV)
142     {
143         setComponentState(newV, true);
144     }
145     else if (oldValue >>= oldV)
146     {
147         setComponentState(oldV, false);
148     }
149 }
150 
151 /**
152  *  set the new state and fire the MSAA event
153  *  @param  state       new state id
154  *  @param  enable      true if state is set, false if state is unset
155  */
setComponentState(short state,bool enable)156 void AccEventListener::setComponentState(short state, bool enable )
157 {
158     switch (state)
159     {
160     case AccessibleStateType::FOCUSED:
161         fireStateFocusdChange(enable);
162         break;
163     default:
164         fireStatePropertyChange(state, enable);
165         break;
166     }
167 }
168 
169 /**
170  *  handle the focused event
171  *  @param enable   true if get focus, false if lose focus
172  */
fireStateFocusdChange(bool enable)173 void AccEventListener::fireStateFocusdChange(bool enable)
174 {
175     if(enable)
176     {
177         pAgent->IncreaseState( pAccessible, AccessibleStateType::FOCUSED);
178         pAgent->NotifyAccEvent(UM_EVENT_STATE_FOCUSED, pAccessible);
179     }
180     else
181     {
182         // no focus lost event in MSAA
183     }
184 }
185 
186 
187 /**
188  *  fire the MSAA state changed event
189  *  @param state    the state id
190  *  @param set      true if state is set, false if state is unset
191  */
fireStatePropertyChange(short state,bool set)192 void AccEventListener::fireStatePropertyChange(short state, bool set )
193 {
194     if( set )
195     {
196         //get new state
197     }
198     else
199     {
200         //lose old state
201     }
202 }
203 
204 /**
205  *  get the role of accessible object which is observed
206  */
getRole()207 short AccEventListener::getRole()
208 {
209     Reference<com::sun::star::accessibility::XAccessibleContext> xContext(pAccessible->getAccessibleContext(),UNO_QUERY);
210     if(xContext.is())
211     {
212         return xContext->getAccessibleRole();
213     }
214     return -1;
215 }
216 
217 /**
218  *  get the role of accessible parent object which is observed
219  */
getParentRole()220 short AccEventListener::getParentRole()
221 {
222     if(pAccessible)
223     {
224         return pAgent->GetParentRole(pAccessible);
225     }
226     return -1;
227 }
228 /**
229  *  remove the listener from accessible object
230  */
removeMeFromBroadcaster()231 void AccEventListener::removeMeFromBroadcaster()
232 {
233     try
234     {
235         vos::OGuard aGuard(aRemoveMutex);
236         if(m_isDisposed)
237             return;
238         //get accessible context
239         Reference< XAccessibleContext > pRContext;
240         XAccessibleContext* pContext =NULL;
241 
242         if( pAccessible == NULL)
243         {
244             return;
245         }
246         pRContext = pAccessible->getAccessibleContext();
247         if( !pRContext.is() )
248         {
249             return;
250         }
251 
252         //get broadcaster from accessible component
253         Reference<XAccessibleComponent> xComponent(pRContext,UNO_QUERY);
254         if(!xComponent.is())
255         {
256             return;
257         }
258         Reference<XAccessibleEventBroadcaster> broadcaster(xComponent,UNO_QUERY);
259         XAccessibleEventBroadcaster* pBroadcaster = broadcaster.get();
260         if (pBroadcaster != NULL)
261         {
262             //remove the lister from accessible object
263             pBroadcaster->removeEventListener(this);
264             m_isDisposed = true;
265             pAgent->NotifyDestroy(pAccessible);
266         }
267     }
268     catch(...)
269     {
270         return;
271     }
272 
273 }
274 
275 /**
276  *  this method is invoked before listener is disposed
277  */
disposing(const::com::sun::star::lang::EventObject & Source)278 void AccEventListener::disposing( const ::com::sun::star::lang::EventObject& Source )
279 {
280     removeMeFromBroadcaster();
281 }
282 
283 //need to investigate further
queryInterface(const::com::sun::star::uno::Type & aType)284 ::com::sun::star::uno::Any SAL_CALL AccEventListener::queryInterface( const ::com::sun::star::uno::Type& aType )
285 {
286     if(aType.equals(::getCppuType( (Reference< com::sun::star::accessibility::XAccessibleEventListener> const *)0 ) ))
287     {
288         Reference< com::sun::star::accessibility::XAccessibleEventListener> xEventListener( static_cast< com::sun::star::accessibility::XAccessibleEventListener* >(this));
289         return makeAny(xEventListener);
290     }
291 
292     return Any();
293 }
294 
acquire()295 void AccEventListener::acquire(  ) throw ()
296 {
297     ::osl_incrementInterlockedCount( &m_refcount );
298 }
299 
release()300 void AccEventListener::release() throw ()
301 {
302     // thread-safe decrementation of reference count
303     if (0 == ::osl_decrementInterlockedCount( &m_refcount ))
304     {
305         delete this; // shutdown this object
306     }
307 }
308