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 "AccDescendantManagerEventListener.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
AccDescendantManagerEventListener(com::sun::star::accessibility::XAccessible * pAcc,AccObjectManagerAgent * Agent)35 AccDescendantManagerEventListener::AccDescendantManagerEventListener(com::sun::star::accessibility::XAccessible* pAcc, AccObjectManagerAgent* Agent)
36 :AccComponentEventListener(pAcc, Agent),
37 pActiveDescendant(NULL)
38 {
39 }
40
~AccDescendantManagerEventListener()41 AccDescendantManagerEventListener::~AccDescendantManagerEventListener()
42 {
43 }
44
45 /**
46 * Uno's event notifier when event is captured
47 * @param AccessibleEventObject the event object which contains information about event
48 */
notifyEvent(const::com::sun::star::accessibility::AccessibleEventObject & aEvent)49 void AccDescendantManagerEventListener::notifyEvent( const ::com::sun::star::accessibility::AccessibleEventObject& aEvent )
50 throw (::com::sun::star::uno::RuntimeException)
51 {
52 switch (aEvent.EventId)
53 {
54 case AccessibleEventId::SELECTION_CHANGED:
55 handleSelectionChangedEvent(aEvent.OldValue, aEvent.NewValue);
56 break;
57 case AccessibleEventId::CHILD:
58 handleChildChangedEvent(aEvent.OldValue, aEvent.NewValue);
59 break;
60 case AccessibleEventId::ACTIVE_DESCENDANT_CHANGED_NOFOCUS:
61 handleChildChangedNoFocusEvent(aEvent.OldValue, aEvent.NewValue);
62 break;
63 case AccessibleEventId::SELECTION_CHANGED_ADD:
64 handleSelectionChangedAddEvent(aEvent.OldValue, aEvent.NewValue);
65 break;
66 case AccessibleEventId::SELECTION_CHANGED_REMOVE:
67 handleSelectionChangedRemoveEvent(aEvent.OldValue, aEvent.NewValue);
68 break;
69 case AccessibleEventId::SELECTION_CHANGED_WITHIN:
70 handleSelectionChangedWithinEvent(aEvent.OldValue, aEvent.NewValue);
71 break;
72 default:
73 AccComponentEventListener::notifyEvent(aEvent);
74 break;
75 }
76 }
77
78 /**
79 * handle the CHILD event
80 * @param oldValue the child to be deleted
81 * @param newValue the child to be added
82 */
handleChildChangedEvent(Any oldValue,Any newValue)83 void AccDescendantManagerEventListener::handleChildChangedEvent(Any oldValue, Any newValue)
84 {
85
86 Reference< XAccessible > xChild;
87 if( newValue >>= xChild)
88 {
89 //create a new child
90 if(xChild.is())
91 {
92 XAccessible* pAcc = xChild.get();
93 pAgent->InsertAccObj( pAcc,pAccessible);
94 pAgent->InsertChildrenAccObj(pAcc);
95
96 pAgent->NotifyAccEvent(UM_EVENT_CHILD_ADDED, pAcc);
97
98 }
99 else
100 {}
101 }
102
103 if (oldValue >>= xChild)
104 {
105 if(xChild.is())
106 {
107 XAccessible* pAcc = xChild.get();
108
109 pAgent->NotifyAccEvent(UM_EVENT_CHILD_REMOVED, pAcc);
110 pAgent->DeleteChildrenAccObj( pAcc );
111 pAgent->DeleteAccObj( pAcc );
112 }
113 else
114 {}
115 }
116
117 }
118
119 /**
120 * handle the SELECTION_CHANGED event
121 */
handleSelectionChangedEvent(Any oldValue,Any newValue)122 void AccDescendantManagerEventListener::handleSelectionChangedEvent(Any oldValue, Any newValue)
123 {
124 bool bSend =false;
125 Reference< XAccessible > xChild;
126 if(newValue >>= xChild )
127 {
128 if(xChild.is())
129 {
130 XAccessible* pAcc = xChild.get();
131 //if the Role is the SC cell ,don't add the selected state.
132 if (pAgent->GetRole(pAcc) != AccessibleRole::TABLE_CELL)
133 {
134 pAgent->IncreaseState( pAcc, AccessibleStateType::SELECTED);
135 }
136
137 pAgent->NotifyAccEvent(UM_EVENT_SELECTION_CHANGED, pAcc);
138 bSend=true;
139 }
140 }
141 if(oldValue >>= xChild )
142 {
143 if(xChild.is())
144 {
145 XAccessible* pAcc = xChild.get();
146 pAgent->DecreaseState( pAcc, AccessibleStateType::SELECTED);
147 }
148 }
149 if (!bSend)
150 {
151 pAgent->NotifyAccEvent(UM_EVENT_SELECTION_CHANGED, pAccessible);
152 }
153 }
154
155
handleChildChangedNoFocusEvent(Any oldValue,Any newValue)156 void AccDescendantManagerEventListener::handleChildChangedNoFocusEvent(Any oldValue, Any newValue)
157 {
158 Reference< XAccessible > xChild;
159 if(newValue >>= xChild )
160 {
161 if(xChild.is())
162 {
163 XAccessible* pAcc = xChild.get();
164
165 pAgent->InsertAccObj(pAcc,pAccessible);
166 pAgent->InsertChildrenAccObj(pAcc);
167
168 pActiveDescendant= pAcc;
169 }
170 }
171 if (oldValue >>= xChild)
172 {
173 if(xChild.is())
174 {
175 XAccessible* pAcc = xChild.get();
176 pAgent->DeleteChildrenAccObj( pAcc );
177 pAgent->DeleteAccObj( pAcc );
178 }
179 }
180 }
181
NotifyChildEvent(short nWinEvent,const Any & Value)182 bool AccDescendantManagerEventListener::NotifyChildEvent(short nWinEvent,const Any &Value)
183 {
184 Reference< XAccessible > xChild;
185 if(Value >>= xChild )
186 {
187 if(xChild.is())
188 {
189 XAccessible* pAcc = xChild.get();
190 pAgent->NotifyAccEvent(nWinEvent, pAcc);
191
192 if (pAgent && pAgent->IsStateManageDescendant(pAccessible) && ( nWinEvent == UM_EVENT_SELECTION_CHANGED_REMOVE) )
193 {
194 pAgent->DeleteAccObj( pAcc );
195 }
196 return true;
197 }
198 }
199 return false;
200 }
handleSelectionChangedAddEvent(const Any &,const Any & newValue)201 void AccDescendantManagerEventListener::handleSelectionChangedAddEvent(const Any& /*oldValue*/, const Any &newValue)
202 {
203 if(NotifyChildEvent(UM_EVENT_SELECTION_CHANGED_ADD,newValue))
204 {
205 return ;
206 }
207 pAgent->NotifyAccEvent(UM_EVENT_SELECTION_CHANGED_ADD,pAccessible);
208 }
handleSelectionChangedRemoveEvent(const Any &,const Any & newValue)209 void AccDescendantManagerEventListener::handleSelectionChangedRemoveEvent(const Any& /*oldValue*/, const Any &newValue)
210 {
211 if(NotifyChildEvent(UM_EVENT_SELECTION_CHANGED_REMOVE,newValue))
212 {
213 return ;
214 }
215 pAgent->NotifyAccEvent(UM_EVENT_SELECTION_CHANGED_REMOVE,pAccessible);
216 }
217
handleSelectionChangedWithinEvent(const Any &,const Any & newValue)218 void AccDescendantManagerEventListener::handleSelectionChangedWithinEvent(const Any& /*oldValue*/, const Any &newValue)
219 {
220 if(NotifyChildEvent(UM_EVENT_SELECTION_CHANGED_WITHIN,newValue))
221 {
222 return ;
223 }
224 pAgent->NotifyAccEvent(UM_EVENT_SELECTION_CHANGED_WITHIN,pAccessible);
225 }
226
227