1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <com/sun/star/accessibility/XAccessible.hpp>
21 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
22 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
23 #include <com/sun/star/accessibility/AccessibleRole.hpp>
24 #include <com/sun/star/accessibility/XAccessibleEventBroadcaster.hpp>
26 #include <vcl/svapp.hxx>
28 #include <AccComponentEventListener.hxx>
29 #include <AccObjectManagerAgent.hxx>
30 #include <unomsaaevent.hxx>
32 using namespace com::sun::star::uno
;
33 using namespace com::sun::star::accessibility
;
35 AccComponentEventListener::AccComponentEventListener(css::accessibility::XAccessible
* pAcc
, AccObjectManagerAgent
* Agent
)
36 :AccEventListener(pAcc
, Agent
)
40 AccComponentEventListener::~AccComponentEventListener()
45 * Uno's event notifier when event is captured
47 * @param AccessibleEventObject the event object which contains information about event
49 void AccComponentEventListener::notifyEvent( const css::accessibility::AccessibleEventObject
& aEvent
)
53 switch (aEvent
.EventId
)
55 case AccessibleEventId::VALUE_CHANGED
:
56 HandleValueChangedEvent(aEvent
.OldValue
, aEvent
.NewValue
);
58 case AccessibleEventId::ACTION_CHANGED
:
59 HandleActionChangedEvent();
61 case AccessibleEventId::TEXT_CHANGED
:
62 HandleTextChangedEvent(aEvent
.OldValue
, aEvent
.NewValue
);
64 case AccessibleEventId::CARET_CHANGED
:
65 HandleCaretChangedEvent(aEvent
.OldValue
, aEvent
.NewValue
);
67 case AccessibleEventId::VISIBLE_DATA_CHANGED
:
68 HandleVisibleDataChangedEvent();
70 case AccessibleEventId::BOUNDRECT_CHANGED
:
71 HandleBoundrectChangedEvent();
73 case AccessibleEventId::SELECTION_CHANGED
:
74 HandleSelectionChangedEventNoArgs();
76 //to add TEXT_SELECTION_CHANGED event
77 case AccessibleEventId::TEXT_SELECTION_CHANGED
:
78 HandleTextSelectionChangedEvent();
82 AccEventListener::notifyEvent(aEvent
);
88 * handle the VALUE_CHANGED event
90 * @param oldValue the old value of the source of event
91 * @param newValue the new value of the source of event
93 void AccComponentEventListener::HandleValueChangedEvent(Any
, Any
)
95 pAgent
->UpdateValue(m_xAccessible
.get());
96 pAgent
->NotifyAccEvent(UM_EVENT_OBJECT_VALUECHANGE
, m_xAccessible
.get());
100 * handle the NAME_CHANGED event
102 void AccComponentEventListener::HandleActionChangedEvent()
104 pAgent
->UpdateAction(m_xAccessible
.get());
105 pAgent
->NotifyAccEvent(UM_EVENT_OBJECT_DEFACTIONCHANGE
, m_xAccessible
.get());
109 * handle the TEXT_CHANGED event
111 * @param oldValue the old value of the source of event
112 * @param newValue the new value of the source of event
114 void AccComponentEventListener::HandleTextChangedEvent(Any
, Any newValue
)
116 pAgent
->UpdateValue(m_xAccessible
.get(), newValue
);
117 pAgent
->NotifyAccEvent(UM_EVENT_OBJECT_VALUECHANGE
, m_xAccessible
.get());
121 * handle the CARET_CHANGED event
123 * @param oldValue the old value of the source of event
124 * @param newValue the new value of the source of event
126 void AccComponentEventListener::HandleCaretChangedEvent(Any
, Any
)
128 pAgent
->NotifyAccEvent(UM_EVENT_OBJECT_CARETCHANGE
, m_xAccessible
.get());
132 * set the new state and fire the MSAA event
134 * @param state new state id
135 * @param enable true if state is set, false if state is unset
137 void AccComponentEventListener::SetComponentState(short state
, bool enable
)
139 // only the following state can be fired state event.
142 case AccessibleStateType::CHECKED
:
143 case AccessibleStateType::PRESSED
:
144 case AccessibleStateType::SELECTED
:
145 case AccessibleStateType::ARMED
:
146 case AccessibleStateType::INDETERMINATE
:
147 case AccessibleStateType::SHOWING
:
148 FireStatePropertyChange(state
, enable
);
150 case AccessibleStateType::VISIBLE
:
151 if (GetRole() == AccessibleRole::MENU_ITEM
)
155 pAgent
->IncreaseState(m_xAccessible
.get(), AccessibleStateType::VISIBLE
);
156 pAgent
->IncreaseState(m_xAccessible
.get(), AccessibleStateType::FOCUSABLE
);
160 pAgent
->DecreaseState(m_xAccessible
.get(), AccessibleStateType::VISIBLE
);
161 pAgent
->DecreaseState(m_xAccessible
.get(), AccessibleStateType::FOCUSABLE
);
166 FireStatePropertyChange(state
, enable
);
169 case AccessibleStateType::FOCUSED
:
170 FireStateFocusedChange(enable
);
172 case AccessibleStateType::ENABLED
:
175 pAgent
->UpdateState(m_xAccessible
.get());
176 pAgent
->DecreaseState(m_xAccessible
.get(), AccessibleStateType::DEFUNC
);
177 // 8. label should have no FOCUSABLE state, Firefox has READONLY state, we can also have.
178 if ( GetRole() != AccessibleRole::LABEL
179 && GetRole() != AccessibleRole::STATIC
180 && GetRole() != AccessibleRole::SCROLL_BAR
)
182 pAgent
->IncreaseState(m_xAccessible
.get(), AccessibleStateType::FOCUSABLE
);
187 pAgent
->UpdateState(m_xAccessible
.get());
188 pAgent
->IncreaseState(m_xAccessible
.get(), AccessibleStateType::DEFUNC
);
189 pAgent
->DecreaseState(m_xAccessible
.get(), AccessibleStateType::FOCUSABLE
);
192 case AccessibleStateType::ACTIVE
:
193 // Only frames should be active
194 // no msaa state mapping
202 * fire the MSAA state changed event
204 * @param state the state id
205 * @param set true if state is set, false if state is unset
207 void AccComponentEventListener::FireStatePropertyChange(short state
, bool set
)
214 case AccessibleStateType::CHECKED
:
215 case AccessibleStateType::INDETERMINATE
:
216 pAgent
->IncreaseState(m_xAccessible
.get(), state
);
217 pAgent
->UpdateAction(m_xAccessible
.get());
219 if(!pAgent
->IsSpecialToolboItem(m_xAccessible
.get()))
221 pAgent
->NotifyAccEvent(UM_EVENT_STATE_CHECKED
, m_xAccessible
.get());
224 case AccessibleStateType::PRESSED
:
225 pAgent
->IncreaseState(m_xAccessible
.get(), state
);
226 pAgent
->NotifyAccEvent(UM_EVENT_STATE_PRESSED
, m_xAccessible
.get());
228 case AccessibleStateType::SELECTED
:
229 pAgent
->IncreaseState(m_xAccessible
.get(), state
);
231 case AccessibleStateType::ARMED
:
232 pAgent
->IncreaseState(m_xAccessible
.get(), state
);
233 pAgent
->NotifyAccEvent(UM_EVENT_STATE_ARMED
, m_xAccessible
.get());
235 case AccessibleStateType::SHOWING
:
236 pAgent
->DecreaseState(m_xAccessible
.get(), AccessibleStateType::DEFUNC
);
237 // UNO !SHOWING == MSAA OFFSCREEN
238 pAgent
->IncreaseState(m_xAccessible
.get(), AccessibleStateType::SHOWING
);
240 case AccessibleStateType::VISIBLE
:
241 // UNO !VISIBLE == MSAA INVISIBLE
242 pAgent
->IncreaseState(m_xAccessible
.get(), AccessibleStateType::VISIBLE
);
253 case AccessibleStateType::CHECKED
:
254 case AccessibleStateType::INDETERMINATE
:
255 pAgent
->DecreaseState(m_xAccessible
.get(), state
);
256 pAgent
->UpdateAction(m_xAccessible
.get());
258 if(!pAgent
->IsSpecialToolboItem(m_xAccessible
.get()))
260 pAgent
->NotifyAccEvent(UM_EVENT_STATE_CHECKED
, m_xAccessible
.get());
263 case AccessibleStateType::PRESSED
:
264 pAgent
->DecreaseState(m_xAccessible
.get(), state
);
265 pAgent
->NotifyAccEvent(UM_EVENT_STATE_PRESSED
, m_xAccessible
.get());
267 case AccessibleStateType::SELECTED
:
268 pAgent
->DecreaseState(m_xAccessible
.get(), state
);
269 //if the state is unset, no need to send MSAA SELECTION event
270 //pAgent->NotifyAccEvent(UM_EVENT_STATE_SELECTED, m_xAccessible.get());
272 case AccessibleStateType::ARMED
:
274 pAgent
->DecreaseState(m_xAccessible
.get(), state
);
275 //if the state is unset, no need to send MSAA MENU event
276 //pAgent->NotifyAccEvent(UM_EVENT_STATE_ARMED, m_xAccessible.get());
279 case AccessibleStateType::SHOWING
:
280 pAgent
->DecreaseState(m_xAccessible
.get(), AccessibleStateType::DEFUNC
);
281 // UNO !SHOWING == MSAA OFFSCREEN
282 pAgent
->DecreaseState(m_xAccessible
.get(), AccessibleStateType::SHOWING
);
284 case AccessibleStateType::VISIBLE
:
285 // UNO !VISIBLE == MSAA INVISIBLE
286 pAgent
->DecreaseState(m_xAccessible
.get(), AccessibleStateType::VISIBLE
);
296 * handle the focused event
298 * @param enable true if get focus, false if lose focus
300 void AccComponentEventListener::FireStateFocusedChange(bool enable
)
304 if (GetParentRole() != AccessibleRole::COMBO_BOX
)
305 pAgent
->NotifyAccEvent(UM_EVENT_STATE_FOCUSED
, m_xAccessible
.get());
309 //if lose focus, no need to send MSAA FOCUS event
310 pAgent
->DecreaseState(m_xAccessible
.get(), AccessibleStateType::FOCUSED
);
314 void AccComponentEventListener::HandleSelectionChangedEventNoArgs()
316 pAgent
->NotifyAccEvent(UM_EVENT_SELECTION_CHANGED
, m_xAccessible
.get());
319 //add TEXT_SELECTION_CHANGED event
320 void AccComponentEventListener::HandleTextSelectionChangedEvent()
322 pAgent
->NotifyAccEvent(UM_EVENT_TEXT_SELECTION_CHANGED
, m_xAccessible
.get());
325 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */