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