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 <com/sun/star/accessibility/XAccessible.hpp>
23 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
24 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
25 #include <com/sun/star/accessibility/AccessibleRole.hpp>
26 #include <com/sun/star/accessibility/XAccessibleEventBroadcaster.hpp>
27
28 #include "AccComponentEventListener.hxx"
29 #include "AccObjectManagerAgent.hxx"
30 #include "unomsaaevent.hxx"
31
32 using namespace com::sun::star::uno;
33 using namespace com::sun::star::accessibility;
34
AccComponentEventListener(com::sun::star::accessibility::XAccessible * pAcc,AccObjectManagerAgent * Agent)35 AccComponentEventListener::AccComponentEventListener(com::sun::star::accessibility::XAccessible* pAcc, AccObjectManagerAgent* Agent)
36 :AccEventListener(pAcc, Agent)
37 {
38 }
39
~AccComponentEventListener()40 AccComponentEventListener::~AccComponentEventListener()
41 {
42 }
43
44 /**
45 * Uno's event notifier when event is captured
46 *
47 * @param AccessibleEventObject the event object which contains information about event
48 */
notifyEvent(const::com::sun::star::accessibility::AccessibleEventObject & aEvent)49 void AccComponentEventListener::notifyEvent( const ::com::sun::star::accessibility::AccessibleEventObject& aEvent )
50 throw (::com::sun::star::uno::RuntimeException)
51 {
52 switch (aEvent.EventId)
53 {
54 case AccessibleEventId::VALUE_CHANGED:
55 handleValueChangedEvent(aEvent.OldValue, aEvent.NewValue);
56 break;
57 case AccessibleEventId::ACTION_CHANGED:
58 handleActionChangedEvent();
59 break;
60 case AccessibleEventId::TEXT_CHANGED:
61 handleTextChangedEvent(aEvent.OldValue, aEvent.NewValue);
62 break;
63 case AccessibleEventId::CARET_CHANGED:
64 handleCaretChangedEvent(aEvent.OldValue, aEvent.NewValue);
65 break;
66 case AccessibleEventId::VISIBLE_DATA_CHANGED:
67 handleVisibleDataChangedEvent();
68 break;
69 case AccessibleEventId::BOUNDRECT_CHANGED:
70 handleBoundrectChangedEvent();
71 break;
72 case AccessibleEventId::SELECTION_CHANGED:
73 handleSelectionChangedEvent();
74 break;
75 //to add TEXT_SELECTION_CHANGED event
76 case AccessibleEventId::TEXT_SELECTION_CHANGED:
77 handleTextSelectionChangedEvent();
78 break;
79 //End
80 default:
81 AccEventListener::notifyEvent(aEvent);
82 break;
83 }
84 }
85
86 /**
87 * handle the VALUE_CHANGED event
88 *
89 * @param oldValue the old value of the source of event
90 * @param newValue the new value of the source of event
91 */
handleValueChangedEvent(Any oldValue,Any newValue)92 void AccComponentEventListener::handleValueChangedEvent(Any oldValue, Any newValue)
93 {
94 pAgent->UpdateValue(pAccessible);
95 pAgent->NotifyAccEvent(UM_EVENT_OBJECT_VALUECHANGE, pAccessible);
96 }
97
98 /**
99 * handle the NAME_CHANGED event
100 */
handleActionChangedEvent()101 void AccComponentEventListener::handleActionChangedEvent()
102 {
103 pAgent->UpdateAction(pAccessible);
104 pAgent->NotifyAccEvent(UM_EVENT_OBJECT_DEFACTIONCHANGE, pAccessible);
105 }
106
107 /**
108 * handle the TEXT_CHANGED event
109 *
110 * @param oldValue the old value of the source of event
111 * @param newValue the new value of the source of event
112 */
handleTextChangedEvent(Any oldValue,Any newValue)113 void AccComponentEventListener::handleTextChangedEvent(Any oldValue, Any newValue)
114 {
115 pAgent->UpdateValue(pAccessible, newValue);
116 pAgent->NotifyAccEvent(UM_EVENT_OBJECT_VALUECHANGE, pAccessible);
117 }
118
119 /**
120 * handle the CARET_CHANGED event
121 *
122 * @param oldValue the old value of the source of event
123 * @param newValue the new value of the source of event
124 */
handleCaretChangedEvent(Any oldValue,Any newValue)125 void AccComponentEventListener::handleCaretChangedEvent(Any oldValue, Any newValue)
126 {
127 pAgent->NotifyAccEvent(UM_EVENT_OBJECT_CARETCHANGE, pAccessible);
128 }
129
130 /**
131 * handle the VISIBLE_DATA_CHANGED event
132 */
handleVisibleDataChangedEvent()133 void AccComponentEventListener::handleVisibleDataChangedEvent()
134 {
135 AccEventListener::handleVisibleDataChangedEvent();
136 }
137
138 /**
139 * handle the BOUNDRECT_CHANGED event
140 */
handleBoundrectChangedEvent()141 void AccComponentEventListener::handleBoundrectChangedEvent()
142 {
143 AccEventListener::handleBoundrectChangedEvent();
144 }
145
146 /**
147 * set the new state and fire the MSAA event
148 *
149 * @param state new state id
150 * @param enable true if state is set, false if state is unset
151 */
setComponentState(short state,bool enable)152 void AccComponentEventListener::setComponentState(short state, bool enable )
153 {
154 // only the following state can be fired state event.
155 switch (state)
156 {
157 case AccessibleStateType::CHECKED:
158 case AccessibleStateType::PRESSED:
159 case AccessibleStateType::SELECTED:
160 case AccessibleStateType::ARMED:
161 case AccessibleStateType::INDETERMINATE:
162 case AccessibleStateType::SHOWING:
163 fireStatePropertyChange(state, enable);
164 break;
165 case AccessibleStateType::VISIBLE:
166 if (getRole() == AccessibleRole::MENU_ITEM)
167 {
168 if(enable)
169 {
170 pAgent->IncreaseState( pAccessible, AccessibleStateType::VISIBLE);
171 pAgent->IncreaseState( pAccessible, AccessibleStateType::FOCUSABLE);
172 }
173 else
174 {
175 pAgent->DecreaseState( pAccessible, AccessibleStateType::VISIBLE);
176 pAgent->DecreaseState( pAccessible, AccessibleStateType::FOCUSABLE);
177 }
178 }
179 else
180 {
181 fireStatePropertyChange(state, enable);
182 }
183 break;
184 break;
185 case AccessibleStateType::FOCUSED:
186 fireStateFocusdChange(enable);
187 break;
188 case AccessibleStateType::ENABLED:
189 if(enable)
190 {
191 pAgent->UpdateState(pAccessible);
192 pAgent->DecreaseState( pAccessible, AccessibleStateType::DEFUNC);
193 // 8. label should have no FOCUSABLE state state, Firefox has READONLY state, we can also have.
194 if( getRole() != AccessibleRole::LABEL
195 && getRole() != AccessibleRole::SCROLL_BAR)
196 pAgent->IncreaseState( pAccessible, AccessibleStateType::FOCUSABLE);
197 }
198 else
199 {
200 pAgent->UpdateState(pAccessible);
201 pAgent->IncreaseState( pAccessible, AccessibleStateType::DEFUNC);
202 pAgent->DecreaseState( pAccessible, AccessibleStateType::FOCUSABLE);
203 }
204 break;
205 case AccessibleStateType::ACTIVE:
206 // Only frames should be active
207 // no msaa state mapping
208 break;
209 default:
210 break;
211 }
212 }
213
214 /**
215 * fire the MSAA state changed event
216 *
217 * @param state the state id
218 * @param set true if state is set, false if state is unset
219 */
fireStatePropertyChange(short state,bool set)220 void AccComponentEventListener::fireStatePropertyChange(short state, bool set)
221 {
222 if( set)
223 {
224 // new value
225 switch(state)
226 {
227 case AccessibleStateType::CHECKED:
228 case AccessibleStateType::INDETERMINATE:
229 pAgent->IncreaseState( pAccessible, state);
230 pAgent->UpdateAction( pAccessible );
231
232 if(!pAgent->IsSpecialToolboItem(pAccessible))
233 {
234 pAgent->NotifyAccEvent(UM_EVENT_STATE_CHECKED, pAccessible);
235 }
236 break;
237 case AccessibleStateType::PRESSED:
238 pAgent->IncreaseState( pAccessible, state);
239 pAgent->NotifyAccEvent(UM_EVENT_STATE_PRESSED, pAccessible);
240 break;
241 case AccessibleStateType::SELECTED:
242 pAgent->IncreaseState( pAccessible, state);
243 break;
244 case AccessibleStateType::ARMED:
245 pAgent->IncreaseState( pAccessible, state);
246 pAgent->NotifyAccEvent(UM_EVENT_STATE_ARMED, pAccessible);
247 break;
248 case AccessibleStateType::SHOWING:
249 pAgent->DecreaseState( pAccessible, AccessibleStateType::DEFUNC);
250 // UNO !SHOWING == MSAA OFFSCREEN
251 pAgent->IncreaseState( pAccessible, AccessibleStateType::SHOWING );
252 break;
253 case AccessibleStateType::VISIBLE:
254 // UNO !VISIBLE == MSAA INVISIBLE
255 pAgent->IncreaseState( pAccessible, AccessibleStateType::VISIBLE );
256 break;
257 default:
258 break;
259 }
260 }
261 else
262 {
263 // old value
264 switch(state)
265 {
266 case AccessibleStateType::CHECKED:
267 case AccessibleStateType::INDETERMINATE:
268 pAgent->DecreaseState( pAccessible, state );
269 pAgent->UpdateAction( pAccessible );
270
271 if(!pAgent->IsSpecialToolboItem(pAccessible))
272 {
273 pAgent->NotifyAccEvent(UM_EVENT_STATE_CHECKED, pAccessible);
274 }
275 break;
276 case AccessibleStateType::PRESSED:
277 pAgent->DecreaseState( pAccessible, state );
278 pAgent->NotifyAccEvent(UM_EVENT_STATE_PRESSED, pAccessible);
279 break;
280 case AccessibleStateType::SELECTED:
281 pAgent->DecreaseState( pAccessible, state );
282 //if the state is unset, no need to send MSAA SELECTION event
283 //pAgent->NotifyAccEvent(UM_EVENT_STATE_SELECTED, pAccessible);
284 break;
285 case AccessibleStateType::ARMED:
286 {
287 pAgent->DecreaseState( pAccessible, state);
288 //if the state is unset, no need to send MSAA MENU event
289 //pAgent->NotifyAccEvent(UM_EVENT_STATE_ARMED, pAccessible);
290 }
291 break;
292 case AccessibleStateType::SHOWING:
293 pAgent->DecreaseState( pAccessible, AccessibleStateType::DEFUNC);
294 // UNO !SHOWING == MSAA OFFSCREEN
295 pAgent->DecreaseState( pAccessible, AccessibleStateType::SHOWING );
296 break;
297 case AccessibleStateType::VISIBLE:
298 // UNO !VISIBLE == MSAA INVISIBLE
299 pAgent->DecreaseState( pAccessible, AccessibleStateType::VISIBLE );
300 break;
301
302 default:
303 break;
304 }
305 }
306 }
307
308 /**
309 * handle the focused event
310 *
311 * @param enable true if get focus, false if lose focus
312 */
fireStateFocusdChange(bool enable)313 void AccComponentEventListener::fireStateFocusdChange(bool enable)
314 {
315 if(enable)
316 {
317 if(getParentRole() != AccessibleRole::COMBO_BOX )
318 pAgent->NotifyAccEvent(UM_EVENT_STATE_FOCUSED, pAccessible);
319 }
320 else
321 {
322 //if lose focus, no need to send MSAA FOCUS event
323 pAgent->DecreaseState( pAccessible, AccessibleStateType::FOCUSED);
324 }
325 }
326
handleSelectionChangedEvent()327 void AccComponentEventListener::handleSelectionChangedEvent()
328 {
329 pAgent->NotifyAccEvent(UM_EVENT_SELECTION_CHANGED, pAccessible);
330 }
331
332 //add TEXT_SELECTION_CHANGED event
handleTextSelectionChangedEvent()333 void AccComponentEventListener::handleTextSelectionChangedEvent()
334 {
335 pAgent->NotifyAccEvent(UM_EVENT_TEXT_SELECTION_CHANGED, pAccessible);
336 }
337