1*3a700b0aSSteve Yin /**************************************************************
2*3a700b0aSSteve Yin  *
3*3a700b0aSSteve Yin  * Licensed to the Apache Software Foundation (ASF) under one
4*3a700b0aSSteve Yin  * or more contributor license agreements.  See the NOTICE file
5*3a700b0aSSteve Yin  * distributed with this work for additional information
6*3a700b0aSSteve Yin  * regarding copyright ownership.  The ASF licenses this file
7*3a700b0aSSteve Yin  * to you under the Apache License, Version 2.0 (the
8*3a700b0aSSteve Yin  * "License"); you may not use this file except in compliance
9*3a700b0aSSteve Yin  * with the License.  You may obtain a copy of the License at
10*3a700b0aSSteve Yin  *
11*3a700b0aSSteve Yin  *   http://www.apache.org/licenses/LICENSE-2.0
12*3a700b0aSSteve Yin  *
13*3a700b0aSSteve Yin  * Unless required by applicable law or agreed to in writing,
14*3a700b0aSSteve Yin  * software distributed under the License is distributed on an
15*3a700b0aSSteve Yin  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*3a700b0aSSteve Yin  * KIND, either express or implied.  See the License for the
17*3a700b0aSSteve Yin  * specific language governing permissions and limitations
18*3a700b0aSSteve Yin  * under the License.
19*3a700b0aSSteve Yin  *
20*3a700b0aSSteve Yin  *************************************************************/
215fdc4257SSteve Yin 
225fdc4257SSteve Yin #include <com/sun/star/accessibility/XAccessible.hpp>
235fdc4257SSteve Yin #include <com/sun/star/accessibility/AccessibleStateType.hpp>
245fdc4257SSteve Yin #include <com/sun/star/accessibility/AccessibleEventId.hpp>
255fdc4257SSteve Yin #include <com/sun/star/accessibility/AccessibleRole.hpp>
265fdc4257SSteve Yin #include <com/sun/star/accessibility/XAccessibleEventBroadcaster.hpp>
275fdc4257SSteve Yin 
285fdc4257SSteve Yin #include "AccContainerEventListener.hxx"
295fdc4257SSteve Yin #include "AccObjectManagerAgent.hxx"
305fdc4257SSteve Yin #include "unomsaaevent.hxx"
315fdc4257SSteve Yin 
325fdc4257SSteve Yin using namespace com::sun::star::uno;
335fdc4257SSteve Yin using namespace com::sun::star::accessibility;
345fdc4257SSteve Yin 
AccContainerEventListener(com::sun::star::accessibility::XAccessible * pAcc,AccObjectManagerAgent * Agent)355fdc4257SSteve Yin AccContainerEventListener::AccContainerEventListener(com::sun::star::accessibility::XAccessible* pAcc, AccObjectManagerAgent* Agent)
365fdc4257SSteve Yin         :AccEventListener(pAcc, Agent)
375fdc4257SSteve Yin {
385fdc4257SSteve Yin }
395fdc4257SSteve Yin 
~AccContainerEventListener()405fdc4257SSteve Yin AccContainerEventListener::~AccContainerEventListener()
415fdc4257SSteve Yin {
425fdc4257SSteve Yin }
435fdc4257SSteve Yin 
445fdc4257SSteve Yin /**
455fdc4257SSteve Yin  *	Uno's event notifier when event is captured
465fdc4257SSteve Yin  *
475fdc4257SSteve Yin  *	@param AccessibleEventObject	the event object which contains information about event
485fdc4257SSteve Yin  */
notifyEvent(const::com::sun::star::accessibility::AccessibleEventObject & aEvent)495fdc4257SSteve Yin void  AccContainerEventListener::notifyEvent( const ::com::sun::star::accessibility::AccessibleEventObject& aEvent )
505fdc4257SSteve Yin throw (::com::sun::star::uno::RuntimeException)
515fdc4257SSteve Yin {
525fdc4257SSteve Yin     short role = getRole();
535fdc4257SSteve Yin     switch (aEvent.EventId)
545fdc4257SSteve Yin     {
555fdc4257SSteve Yin     case AccessibleEventId::CHILD:
565fdc4257SSteve Yin         handleChildChangedEvent(aEvent.OldValue, aEvent.NewValue);
575fdc4257SSteve Yin         break;
585fdc4257SSteve Yin     case AccessibleEventId::SELECTION_CHANGED:
595fdc4257SSteve Yin         handleSelectionChangedEvent(aEvent.OldValue, aEvent.NewValue);
605fdc4257SSteve Yin         break;
615fdc4257SSteve Yin     case AccessibleEventId::INVALIDATE_ALL_CHILDREN:
625fdc4257SSteve Yin         handleAllChildrenChangedEvent();
635fdc4257SSteve Yin         break;
645fdc4257SSteve Yin     case AccessibleEventId::TEXT_CHANGED:
655fdc4257SSteve Yin         handleTextChangedEvent(aEvent.OldValue, aEvent.NewValue);
665fdc4257SSteve Yin     case AccessibleEventId::VISIBLE_DATA_CHANGED:
675fdc4257SSteve Yin         handleVisibleDataChangedEvent();
685fdc4257SSteve Yin         break;
695fdc4257SSteve Yin     case AccessibleEventId::BOUNDRECT_CHANGED:
705fdc4257SSteve Yin         handleBoundrectChangedEvent();
715fdc4257SSteve Yin         break;
725fdc4257SSteve Yin     case AccessibleEventId::STATE_CHANGED:
735fdc4257SSteve Yin         handleStateChangedEvent(aEvent.OldValue, aEvent.NewValue);
745fdc4257SSteve Yin         break;
755fdc4257SSteve Yin     case AccessibleEventId::VALUE_CHANGED:
765fdc4257SSteve Yin         handleValueChangedEvent(aEvent.OldValue, aEvent.NewValue);
775fdc4257SSteve Yin         break;
785fdc4257SSteve Yin     case AccessibleEventId::SELECTION_CHANGED_ADD:
795fdc4257SSteve Yin        	handleSelectionChangedAddEvent(aEvent.OldValue, aEvent.NewValue);
805fdc4257SSteve Yin        	break;
815fdc4257SSteve Yin     case AccessibleEventId::SELECTION_CHANGED_REMOVE:
825fdc4257SSteve Yin         handleSelectionChangedRemoveEvent(aEvent.OldValue, aEvent.NewValue);
835fdc4257SSteve Yin         break;
845fdc4257SSteve Yin     case AccessibleEventId::SELECTION_CHANGED_WITHIN:
855fdc4257SSteve Yin         handleSelectionChangedWithinEvent(aEvent.OldValue, aEvent.NewValue);
865fdc4257SSteve Yin         break;
875fdc4257SSteve Yin     case AccessibleEventId::PAGE_CHANGED:
885fdc4257SSteve Yin         handlePageChangedEvent(aEvent.OldValue, aEvent.NewValue);
895fdc4257SSteve Yin         break;
905fdc4257SSteve Yin     case AccessibleEventId::SECTION_CHANGED:
915fdc4257SSteve Yin         handleSectionChangedEvent(aEvent.OldValue, aEvent.NewValue);
925fdc4257SSteve Yin         break;
935fdc4257SSteve Yin     case AccessibleEventId::COLUMN_CHANGED:
945fdc4257SSteve Yin         handleColumnChangedEvent(aEvent.OldValue, aEvent.NewValue);
955fdc4257SSteve Yin         break;
965fdc4257SSteve Yin     default:
975fdc4257SSteve Yin         AccEventListener::notifyEvent(aEvent);
985fdc4257SSteve Yin         break;
995fdc4257SSteve Yin     }
1005fdc4257SSteve Yin }
1015fdc4257SSteve Yin 
1025fdc4257SSteve Yin /**
1035fdc4257SSteve Yin  *	handle the VISIBLE_DATA_CHANGED event
1045fdc4257SSteve Yin  */
handleVisibleDataChangedEvent()1055fdc4257SSteve Yin void AccContainerEventListener::handleVisibleDataChangedEvent()
1065fdc4257SSteve Yin {
1075fdc4257SSteve Yin     AccEventListener::handleVisibleDataChangedEvent();
1085fdc4257SSteve Yin }
1095fdc4257SSteve Yin 
1105fdc4257SSteve Yin /**
1115fdc4257SSteve Yin  *	handle the BOUNDRECT_CHANGED event
1125fdc4257SSteve Yin  */
handleBoundrectChangedEvent()1135fdc4257SSteve Yin void AccContainerEventListener::handleBoundrectChangedEvent()
1145fdc4257SSteve Yin {
1155fdc4257SSteve Yin     AccEventListener::handleBoundrectChangedEvent();
1165fdc4257SSteve Yin }
1175fdc4257SSteve Yin 
handleStateChangedEvent(Any oldValue,Any newValue)1185fdc4257SSteve Yin void AccContainerEventListener::handleStateChangedEvent(Any oldValue, Any newValue)
1195fdc4257SSteve Yin {
1205fdc4257SSteve Yin     short State;
1215fdc4257SSteve Yin     if( newValue >>= State)
1225fdc4257SSteve Yin     {
1235fdc4257SSteve Yin         setComponentState( State,true);
1245fdc4257SSteve Yin     }
1255fdc4257SSteve Yin     else if (oldValue >>= State)
1265fdc4257SSteve Yin     {
1275fdc4257SSteve Yin         setComponentState( State,false);
1285fdc4257SSteve Yin     }
1295fdc4257SSteve Yin 
1305fdc4257SSteve Yin }
1315fdc4257SSteve Yin 
1325fdc4257SSteve Yin /**
1335fdc4257SSteve Yin  * handle the CHILD event
1345fdc4257SSteve Yin  * @param	oldValue	the child to be deleted
1355fdc4257SSteve Yin  * @param	newValue	the child to be added
1365fdc4257SSteve Yin  */
handleChildChangedEvent(Any oldValue,Any newValue)1375fdc4257SSteve Yin void AccContainerEventListener::handleChildChangedEvent(Any oldValue, Any newValue)
1385fdc4257SSteve Yin {
1395fdc4257SSteve Yin     Reference< XAccessible > xChild;
1405fdc4257SSteve Yin     if( newValue >>= xChild)
1415fdc4257SSteve Yin     {
1425fdc4257SSteve Yin         //create a new child
1435fdc4257SSteve Yin         if(xChild.is())
1445fdc4257SSteve Yin         {
1455fdc4257SSteve Yin             XAccessible* pAcc = xChild.get();
1465fdc4257SSteve Yin             //add this child
1475fdc4257SSteve Yin 
1485fdc4257SSteve Yin             if(pAgent->InsertAccObj( pAcc,pAccessible))
1495fdc4257SSteve Yin             {
1505fdc4257SSteve Yin                 //add all oldValue's existing children
1515fdc4257SSteve Yin                 pAgent->InsertChildrenAccObj(pAcc);
1525fdc4257SSteve Yin                 pAgent->NotifyAccEvent(UM_EVENT_CHILD_ADDED, pAcc);
1535fdc4257SSteve Yin             }
1545fdc4257SSteve Yin         }
1555fdc4257SSteve Yin         else
1565fdc4257SSteve Yin         {}
1575fdc4257SSteve Yin     }
1585fdc4257SSteve Yin     else if (oldValue >>= xChild)
1595fdc4257SSteve Yin     {
1605fdc4257SSteve Yin         //delete a existing child
1615fdc4257SSteve Yin         if(xChild.is())
1625fdc4257SSteve Yin         {
1635fdc4257SSteve Yin             XAccessible* pAcc = xChild.get();
1645fdc4257SSteve Yin             pAgent->NotifyAccEvent(UM_EVENT_CHILD_REMOVED, pAcc);
1655fdc4257SSteve Yin             //delete all oldValue's existing children
1665fdc4257SSteve Yin             pAgent->DeleteChildrenAccObj( pAcc );
1675fdc4257SSteve Yin             //delete this child
1685fdc4257SSteve Yin             pAgent->DeleteAccObj( pAcc );
1695fdc4257SSteve Yin 
1705fdc4257SSteve Yin         }
1715fdc4257SSteve Yin         else
1725fdc4257SSteve Yin         {}
1735fdc4257SSteve Yin     }
1745fdc4257SSteve Yin 
1755fdc4257SSteve Yin }
1765fdc4257SSteve Yin 
1775fdc4257SSteve Yin /**
1785fdc4257SSteve Yin  * handle the SELECTION_CHANGED event
1795fdc4257SSteve Yin  * @param	oldValue	the old value of the source of event
1805fdc4257SSteve Yin  * @param	newValue	the new value of the source of event
1815fdc4257SSteve Yin  */
handleSelectionChangedEvent(const Any &,const Any & newValue)1825fdc4257SSteve Yin void AccContainerEventListener::handleSelectionChangedEvent(const Any& /*oldValue*/, const Any& newValue)
1835fdc4257SSteve Yin {
1845fdc4257SSteve Yin     if(NotifyChildEvent(UM_EVENT_SELECTION_CHANGED,newValue))
1855fdc4257SSteve Yin     {
1865fdc4257SSteve Yin         return ;
1875fdc4257SSteve Yin     }
1885fdc4257SSteve Yin 
1895fdc4257SSteve Yin     //menu bar does not process selection change event,just same as word behavior
1905fdc4257SSteve Yin     if(getRole()!=AccessibleRole::MENU_BAR)
1915fdc4257SSteve Yin         pAgent->NotifyAccEvent(UM_EVENT_SELECTION_CHANGED, pAccessible);
1925fdc4257SSteve Yin }
1935fdc4257SSteve Yin 
1945fdc4257SSteve Yin /**
1955fdc4257SSteve Yin  *	handle the INVALIDATE_ALL_CHILDREN event
1965fdc4257SSteve Yin  */
handleAllChildrenChangedEvent()1975fdc4257SSteve Yin void AccContainerEventListener::handleAllChildrenChangedEvent()
1985fdc4257SSteve Yin {
1995fdc4257SSteve Yin     //TODO: update all the children
2005fdc4257SSteve Yin     if( pAccessible )
2015fdc4257SSteve Yin     {
2025fdc4257SSteve Yin         //delete all oldValue's existing children
2035fdc4257SSteve Yin         pAgent->DeleteChildrenAccObj( pAccessible );
2045fdc4257SSteve Yin         //add all oldValue's existing children
2055fdc4257SSteve Yin         pAgent->InsertChildrenAccObj( pAccessible );
2065fdc4257SSteve Yin         pAgent->NotifyAccEvent(UM_EVENT_OBJECT_REORDER , pAccessible);
2075fdc4257SSteve Yin     }
2085fdc4257SSteve Yin }
2095fdc4257SSteve Yin 
2105fdc4257SSteve Yin /**
2115fdc4257SSteve Yin  *	handle the TEXT_CHANGED event
2125fdc4257SSteve Yin  */
handleTextChangedEvent(Any oldValue,Any newValue)2135fdc4257SSteve Yin void AccContainerEventListener::handleTextChangedEvent(Any oldValue, Any newValue)
2145fdc4257SSteve Yin {
2155fdc4257SSteve Yin     pAgent->UpdateValue(pAccessible, newValue);
2165fdc4257SSteve Yin     pAgent->NotifyAccEvent(UM_EVENT_OBJECT_TEXTCHANGE, pAccessible);
2175fdc4257SSteve Yin }
2185fdc4257SSteve Yin 
2195fdc4257SSteve Yin /**
2205fdc4257SSteve Yin  * set the new state and fire the MSAA event
2215fdc4257SSteve Yin  * @param	state	new state id
2225fdc4257SSteve Yin  * @param	enable	true if state is set, false if state is unset
2235fdc4257SSteve Yin  */
setComponentState(short state,bool enable)2245fdc4257SSteve Yin void AccContainerEventListener::setComponentState(short state, bool enable )
2255fdc4257SSteve Yin {
2265fdc4257SSteve Yin     // only the following state can be fired state event.
2275fdc4257SSteve Yin 
2285fdc4257SSteve Yin     switch (state)
2295fdc4257SSteve Yin     {
2305fdc4257SSteve Yin     case AccessibleStateType::SELECTED:
2315fdc4257SSteve Yin     case AccessibleStateType::BUSY:
2325fdc4257SSteve Yin     case AccessibleStateType::INDETERMINATE:
2335fdc4257SSteve Yin     case AccessibleStateType::OFFSCREEN:
2345fdc4257SSteve Yin     case AccessibleStateType::FOCUSABLE:
2355fdc4257SSteve Yin     case AccessibleStateType::SHOWING:
2365fdc4257SSteve Yin     case AccessibleStateType::VISIBLE:
2375fdc4257SSteve Yin         fireStatePropertyChange(state, enable);
2385fdc4257SSteve Yin         break;
2395fdc4257SSteve Yin     case AccessibleStateType::FOCUSED:
2405fdc4257SSteve Yin         fireStateFocusdChange(enable);
2415fdc4257SSteve Yin         break;
2425fdc4257SSteve Yin     case AccessibleStateType::ENABLED:
2435fdc4257SSteve Yin         if(enable)
2445fdc4257SSteve Yin         {
2455fdc4257SSteve Yin             pAgent->DecreaseState( pAccessible, AccessibleStateType::DEFUNC);
2465fdc4257SSteve Yin             pAgent->IncreaseState( pAccessible, AccessibleStateType::FOCUSABLE);
2475fdc4257SSteve Yin             pAgent->UpdateState(pAccessible);
2485fdc4257SSteve Yin 
2495fdc4257SSteve Yin             UpdateAllChildrenState(pAccessible);
2505fdc4257SSteve Yin         }
2515fdc4257SSteve Yin         else
2525fdc4257SSteve Yin         {
2535fdc4257SSteve Yin             pAgent->IncreaseState( pAccessible, AccessibleStateType::DEFUNC);
2545fdc4257SSteve Yin             pAgent->DecreaseState( pAccessible, AccessibleStateType::FOCUSABLE);
2555fdc4257SSteve Yin             pAgent->UpdateState(pAccessible);
2565fdc4257SSteve Yin 
2575fdc4257SSteve Yin             UpdateAllChildrenState(pAccessible);
2585fdc4257SSteve Yin         }
2595fdc4257SSteve Yin         break;
2605fdc4257SSteve Yin     case AccessibleStateType::ACTIVE:
2615fdc4257SSteve Yin         // Only frames should be active
2625fdc4257SSteve Yin         // no msaa state mapping
2635fdc4257SSteve Yin         //for PAGE_TAB_LIST, there will be ACTIVE state, then it should be converted to FOCUSED event.
2645fdc4257SSteve Yin         if(getRole() == AccessibleRole::PAGE_TAB_LIST)
2655fdc4257SSteve Yin         {
2665fdc4257SSteve Yin             if (!enable) /* get the active state */
2675fdc4257SSteve Yin             {
2685fdc4257SSteve Yin                 pAgent->IncreaseState( pAccessible, AccessibleStateType::FOCUSED);
2695fdc4257SSteve Yin             }
2705fdc4257SSteve Yin 
2715fdc4257SSteve Yin             else	/* lose the active state */
2725fdc4257SSteve Yin             {
2735fdc4257SSteve Yin                 pAgent->DecreaseState( pAccessible, AccessibleStateType::FOCUSED);
2745fdc4257SSteve Yin             }
2755fdc4257SSteve Yin         }
2765fdc4257SSteve Yin         break;
2775fdc4257SSteve Yin 
2785fdc4257SSteve Yin     case AccessibleStateType::EXPANDED:
2795fdc4257SSteve Yin     case AccessibleStateType::COLLAPSE:
2805fdc4257SSteve Yin     case AccessibleStateType::CHECKED:
2815fdc4257SSteve Yin         {
2825fdc4257SSteve Yin             pAgent->UpdateState(pAccessible);
2835fdc4257SSteve Yin             pAgent->NotifyAccEvent(UM_EVENT_STATE_BUSY, pAccessible);
2845fdc4257SSteve Yin             break;
2855fdc4257SSteve Yin         }
2865fdc4257SSteve Yin 
2875fdc4257SSteve Yin     default:
2885fdc4257SSteve Yin         break;
2895fdc4257SSteve Yin     }
2905fdc4257SSteve Yin }
2915fdc4257SSteve Yin 
2925fdc4257SSteve Yin /**
2935fdc4257SSteve Yin  * fire the MSAA state changed event
2945fdc4257SSteve Yin  * @param	state	the state id
2955fdc4257SSteve Yin  * @param	set		true if state is set, false if state is unset
2965fdc4257SSteve Yin  */
fireStatePropertyChange(short state,bool set)2975fdc4257SSteve Yin void AccContainerEventListener::fireStatePropertyChange(short state, bool set)
2985fdc4257SSteve Yin {
2995fdc4257SSteve Yin     if( set )
3005fdc4257SSteve Yin 	{
3015fdc4257SSteve Yin 		// new value
3025fdc4257SSteve Yin 		switch(state)
3035fdc4257SSteve Yin 		{
3045fdc4257SSteve Yin 		case AccessibleStateType::SELECTED:
3055fdc4257SSteve Yin 			pAgent->IncreaseState( pAccessible, state);
3065fdc4257SSteve Yin 			break;
3075fdc4257SSteve Yin 		case AccessibleStateType::INDETERMINATE:
3085fdc4257SSteve Yin 		case AccessibleStateType::BUSY:
3095fdc4257SSteve Yin 		case AccessibleStateType::FOCUSABLE:
3105fdc4257SSteve Yin 		case AccessibleStateType::OFFSCREEN:
3115fdc4257SSteve Yin 			pAgent->IncreaseState( pAccessible, state);
3125fdc4257SSteve Yin 			pAgent->NotifyAccEvent(UM_EVENT_STATE_BUSY, pAccessible);
3135fdc4257SSteve Yin 			break;
3145fdc4257SSteve Yin 		case AccessibleStateType::SHOWING:
3155fdc4257SSteve Yin 			// UNO !SHOWING == MSAA OFFSCREEN
3165fdc4257SSteve Yin 			pAgent->IncreaseState( pAccessible, AccessibleStateType::SHOWING );
3175fdc4257SSteve Yin 			break;
3185fdc4257SSteve Yin 		case AccessibleStateType::VISIBLE:
3195fdc4257SSteve Yin 			// UNO !VISIBLE == MSAA INVISIBLE
3205fdc4257SSteve Yin 			pAgent->IncreaseState( pAccessible, AccessibleStateType::VISIBLE );
3215fdc4257SSteve Yin 			break;
3225fdc4257SSteve Yin 		default:
3235fdc4257SSteve Yin 			break;
3245fdc4257SSteve Yin 		}
3255fdc4257SSteve Yin 	}
3265fdc4257SSteve Yin     else
3275fdc4257SSteve Yin     {
3285fdc4257SSteve Yin         // old value
3295fdc4257SSteve Yin         switch(state)
3305fdc4257SSteve Yin         {
3315fdc4257SSteve Yin         case AccessibleStateType::SELECTED:
3325fdc4257SSteve Yin             pAgent->DecreaseState( pAccessible, state );
3335fdc4257SSteve Yin             break;
3345fdc4257SSteve Yin         case AccessibleStateType::BUSY:
3355fdc4257SSteve Yin         case AccessibleStateType::INDETERMINATE:
3365fdc4257SSteve Yin         case AccessibleStateType::FOCUSABLE:
3375fdc4257SSteve Yin         case AccessibleStateType::OFFSCREEN:
3385fdc4257SSteve Yin             pAgent->DecreaseState( pAccessible, state);
3395fdc4257SSteve Yin             pAgent->NotifyAccEvent(UM_EVENT_STATE_BUSY, pAccessible);
3405fdc4257SSteve Yin             break;
3415fdc4257SSteve Yin         case AccessibleStateType::SHOWING:
3425fdc4257SSteve Yin             // UNO !SHOWING == MSAA OFFSCREEN
3435fdc4257SSteve Yin             pAgent->DecreaseState( pAccessible, AccessibleStateType::SHOWING );
3445fdc4257SSteve Yin             break;
3455fdc4257SSteve Yin         case AccessibleStateType::VISIBLE:
3465fdc4257SSteve Yin             // UNO !VISIBLE == MSAA INVISIBLE
3475fdc4257SSteve Yin             pAgent->DecreaseState( pAccessible, AccessibleStateType::VISIBLE );
3485fdc4257SSteve Yin             break;
3495fdc4257SSteve Yin         default:
3505fdc4257SSteve Yin             break;
3515fdc4257SSteve Yin         }
3525fdc4257SSteve Yin     }
3535fdc4257SSteve Yin }
3545fdc4257SSteve Yin 
3555fdc4257SSteve Yin /**
3565fdc4257SSteve Yin  * handle the focused event
3575fdc4257SSteve Yin  * @param	enable	true if get focus, false if lose focus
3585fdc4257SSteve Yin  */
fireStateFocusdChange(bool enable)3595fdc4257SSteve Yin void AccContainerEventListener::fireStateFocusdChange(bool enable)
3605fdc4257SSteve Yin {
3615fdc4257SSteve Yin     if(enable)
3625fdc4257SSteve Yin     {
3635fdc4257SSteve Yin         pAgent->IncreaseState( pAccessible, AccessibleStateType::FOCUSED);
3645fdc4257SSteve Yin         //if the acc role is MENU_BAR, MSAA UM_EVENT_MENU_START event should be sent
3655fdc4257SSteve Yin         //if the acc role is POPUP_MENU, MSAA UM_EVENT_MENUPOPUPSTART event should be sent
3665fdc4257SSteve Yin         short role = getRole();
3675fdc4257SSteve Yin         if(role == AccessibleRole::MENU_BAR)
3685fdc4257SSteve Yin         {
3695fdc4257SSteve Yin             pAgent->NotifyAccEvent(UM_EVENT_MENU_START, pAccessible);
3705fdc4257SSteve Yin         }
3715fdc4257SSteve Yin         else if (role == AccessibleRole::POPUP_MENU)
3725fdc4257SSteve Yin             pAgent->NotifyAccEvent(UM_EVENT_MENUPOPUPSTART, pAccessible);
3735fdc4257SSteve Yin         //Disable the focused event on option_pane and Panel.
3745fdc4257SSteve Yin         //only disable option_pane for toolbar has panel to get focus
3755fdc4257SSteve Yin         else if (role == AccessibleRole::PANEL || role == AccessibleRole::OPTION_PANE )
3765fdc4257SSteve Yin         {
3775fdc4257SSteve Yin             //don't send focused event on PANEL & OPTION_PANE if the parent is not toolbar
3785fdc4257SSteve Yin             short parentRole = getParentRole();
379d886bbf3SSteve Yin             if (parentRole == AccessibleRole::TOOL_BAR
380d886bbf3SSteve Yin 				|| parentRole == AccessibleRole::SCROLL_PANE // sidebar
381d886bbf3SSteve Yin 				|| parentRole == AccessibleRole::PANEL)	// sidebar
3825fdc4257SSteve Yin                 pAgent->NotifyAccEvent(UM_EVENT_STATE_FOCUSED, pAccessible);
3835fdc4257SSteve Yin         }
3845fdc4257SSteve Yin         //to update ComboBox's description
3855fdc4257SSteve Yin         else if (role == AccessibleRole::COMBO_BOX )
3865fdc4257SSteve Yin         {
3875fdc4257SSteve Yin             pAgent->UpdateDescription(pAccessible);
3885fdc4257SSteve Yin             //for editable combobox, send focus event on only edit control,
3895fdc4257SSteve Yin             bool bSendFocusOnCombobox = true;
3905fdc4257SSteve Yin             //send focused event to the first text child
3915fdc4257SSteve Yin             Reference<XAccessibleContext> mxContext(pAccessible->getAccessibleContext(),UNO_QUERY);
3925fdc4257SSteve Yin             if(mxContext.is())
3935fdc4257SSteve Yin             {
3945fdc4257SSteve Yin                 Reference<XAccessible> mxChild = mxContext->getAccessibleChild(0);
3955fdc4257SSteve Yin                 if(mxChild.is())
3965fdc4257SSteve Yin                 {
3975fdc4257SSteve Yin                     Reference<XAccessibleContext> mxChildContext(mxChild->getAccessibleContext(),UNO_QUERY);
3985fdc4257SSteve Yin                     short childrole = mxChildContext->getAccessibleRole();
3995fdc4257SSteve Yin                     if (childrole == AccessibleRole::TEXT)
4005fdc4257SSteve Yin                     {
4015fdc4257SSteve Yin                         if (IsEditable(mxChildContext))
4025fdc4257SSteve Yin                         {
4035fdc4257SSteve Yin                             pAgent->DecreaseState( pAccessible, AccessibleStateType::FOCUSED);
4045fdc4257SSteve Yin                             pAgent->IncreaseState( mxChild.get(), AccessibleStateType::FOCUSED);
4055fdc4257SSteve Yin                             pAgent->NotifyAccEvent(UM_EVENT_STATE_FOCUSED, mxChild.get());
4065fdc4257SSteve Yin                             bSendFocusOnCombobox = false;
4075fdc4257SSteve Yin                         }
4085fdc4257SSteve Yin                     }
4095fdc4257SSteve Yin                 }
4105fdc4257SSteve Yin             }
4115fdc4257SSteve Yin             if (bSendFocusOnCombobox)
4125fdc4257SSteve Yin                 pAgent->NotifyAccEvent(UM_EVENT_STATE_FOCUSED, pAccessible);
4135fdc4257SSteve Yin         }
4145fdc4257SSteve Yin         else
4155fdc4257SSteve Yin             pAgent->NotifyAccEvent(UM_EVENT_STATE_FOCUSED, pAccessible);
4165fdc4257SSteve Yin     }
4175fdc4257SSteve Yin     else
4185fdc4257SSteve Yin     {
4195fdc4257SSteve Yin         pAgent->DecreaseState( pAccessible, AccessibleStateType::FOCUSED);
4205fdc4257SSteve Yin         //if the acc role is MENU_BAR, MSAA UM_EVENT_MENU_END event should be sent
4215fdc4257SSteve Yin         //if the acc role is POPUP_MENU, MSAA UM_EVENT_MENUPOPUPEND event should be sent
4225fdc4257SSteve Yin         if(getRole() == AccessibleRole::MENU_BAR)
4235fdc4257SSteve Yin         {
4245fdc4257SSteve Yin             pAgent->NotifyAccEvent(UM_EVENT_MENU_END, pAccessible);
4255fdc4257SSteve Yin         }
4265fdc4257SSteve Yin         else if (getRole() == AccessibleRole::POPUP_MENU)
4275fdc4257SSteve Yin         {
4285fdc4257SSteve Yin             pAgent->NotifyAccEvent(UM_EVENT_MENUPOPUPEND, pAccessible);
4295fdc4257SSteve Yin         }
4305fdc4257SSteve Yin     }
4315fdc4257SSteve Yin }
4325fdc4257SSteve Yin 
4335fdc4257SSteve Yin /**
4345fdc4257SSteve Yin  * handle the VALUE_CHANGED event
4355fdc4257SSteve Yin  *
4365fdc4257SSteve Yin  * @param	oldValue	the old value of the source of event
4375fdc4257SSteve Yin  * @param	newValue	the new value of the source of event
4385fdc4257SSteve Yin  */
handleValueChangedEvent(Any oldValue,Any newValue)4395fdc4257SSteve Yin void AccContainerEventListener::handleValueChangedEvent(Any oldValue, Any newValue)
4405fdc4257SSteve Yin {
4415fdc4257SSteve Yin     pAgent->UpdateValue(pAccessible);
4425fdc4257SSteve Yin     pAgent->NotifyAccEvent(UM_EVENT_OBJECT_VALUECHANGE, pAccessible);
4435fdc4257SSteve Yin }
4445fdc4257SSteve Yin 
IsEditable(Reference<XAccessibleContext> xContext)4455fdc4257SSteve Yin bool AccContainerEventListener::IsEditable(Reference<XAccessibleContext> xContext)
4465fdc4257SSteve Yin {
4475fdc4257SSteve Yin     bool ret = false;
4485fdc4257SSteve Yin     Reference< XAccessibleStateSet > pRState = xContext->getAccessibleStateSet();
4495fdc4257SSteve Yin     if( !pRState.is() )
4505fdc4257SSteve Yin         return false;
4515fdc4257SSteve Yin 
4525fdc4257SSteve Yin     Sequence<short> pStates = pRState->getStates();
4535fdc4257SSteve Yin     int count = pStates.getLength();
4545fdc4257SSteve Yin     for( int iIndex = 0;iIndex < count;iIndex++ )
4555fdc4257SSteve Yin     {
4565fdc4257SSteve Yin         if(pStates[iIndex] == AccessibleStateType::EDITABLE)
4575fdc4257SSteve Yin             return true;
4585fdc4257SSteve Yin     }
4595fdc4257SSteve Yin     return ret;
4605fdc4257SSteve Yin }
4615fdc4257SSteve Yin 
NotifyChildEvent(short nWinEvent,const Any & Value)4625fdc4257SSteve Yin bool AccContainerEventListener::NotifyChildEvent(short nWinEvent,const Any &Value)
4635fdc4257SSteve Yin {
4645fdc4257SSteve Yin     Reference< XAccessible > xChild;
4655fdc4257SSteve Yin     if(Value >>= xChild )
4665fdc4257SSteve Yin     {
4675fdc4257SSteve Yin         if(xChild.is())
4685fdc4257SSteve Yin         {
4695fdc4257SSteve Yin             XAccessible* pAcc = xChild.get();
4705fdc4257SSteve Yin             pAgent->NotifyAccEvent(nWinEvent, pAcc);
4715fdc4257SSteve Yin             return true;
4725fdc4257SSteve Yin         }
4735fdc4257SSteve Yin     }
4745fdc4257SSteve Yin     return false;
4755fdc4257SSteve Yin }
4765fdc4257SSteve Yin 
handleSelectionChangedAddEvent(const Any &,const Any & newValue)4775fdc4257SSteve Yin void AccContainerEventListener::handleSelectionChangedAddEvent(const Any& /*oldValue*/, const Any& newValue)
4785fdc4257SSteve Yin {
4795fdc4257SSteve Yin     if(NotifyChildEvent(UM_EVENT_SELECTION_CHANGED_ADD,newValue))
4805fdc4257SSteve Yin     {
4815fdc4257SSteve Yin         return ;
4825fdc4257SSteve Yin     }
4835fdc4257SSteve Yin     pAgent->NotifyAccEvent(UM_EVENT_SELECTION_CHANGED_ADD,pAccessible);
4845fdc4257SSteve Yin }
handleSelectionChangedRemoveEvent(const Any &,const Any & newValue)4855fdc4257SSteve Yin void AccContainerEventListener::handleSelectionChangedRemoveEvent(const Any& /*oldValue*/, const Any& newValue)
4865fdc4257SSteve Yin {
4875fdc4257SSteve Yin     if(NotifyChildEvent(UM_EVENT_SELECTION_CHANGED_REMOVE,newValue))
4885fdc4257SSteve Yin     {
4895fdc4257SSteve Yin         return ;
4905fdc4257SSteve Yin     }
4915fdc4257SSteve Yin     pAgent->NotifyAccEvent(UM_EVENT_SELECTION_CHANGED_REMOVE,pAccessible);
4925fdc4257SSteve Yin }
handleSelectionChangedWithinEvent(const Any &,const Any & newValue)4935fdc4257SSteve Yin void AccContainerEventListener::handleSelectionChangedWithinEvent(const Any& /*oldValue*/, const Any& newValue)
4945fdc4257SSteve Yin {
4955fdc4257SSteve Yin     if(NotifyChildEvent(UM_EVENT_SELECTION_CHANGED_WITHIN,newValue))
4965fdc4257SSteve Yin     {
4975fdc4257SSteve Yin         return ;
4985fdc4257SSteve Yin     }
4995fdc4257SSteve Yin     pAgent->NotifyAccEvent(UM_EVENT_SELECTION_CHANGED_WITHIN,pAccessible);
5005fdc4257SSteve Yin }
5015fdc4257SSteve Yin 
UpdateAllChildrenState(com::sun::star::accessibility::XAccessible * pXAccessible)5025fdc4257SSteve Yin void SAL_CALL AccContainerEventListener::UpdateAllChildrenState( com::sun::star::accessibility::XAccessible* pXAccessible )
5035fdc4257SSteve Yin {
5045fdc4257SSteve Yin     Reference<com::sun::star::accessibility::XAccessibleContext> xContext(pXAccessible->getAccessibleContext(),UNO_QUERY);
5055fdc4257SSteve Yin     if(!xContext.is())
5065fdc4257SSteve Yin     {
5075fdc4257SSteve Yin         return;
5085fdc4257SSteve Yin     }
5095fdc4257SSteve Yin     com::sun::star::accessibility::XAccessibleContext* pAccessibleContext = xContext.get();
5105fdc4257SSteve Yin     if(pAccessibleContext == NULL)
5115fdc4257SSteve Yin     {
5125fdc4257SSteve Yin         return;
5135fdc4257SSteve Yin     }
5145fdc4257SSteve Yin 
5155fdc4257SSteve Yin 	if (pAgent && pAgent->IsStateManageDescendant(pXAccessible))
5165fdc4257SSteve Yin 	{
5175fdc4257SSteve Yin 		return;
5185fdc4257SSteve Yin 	}
5195fdc4257SSteve Yin 
5205fdc4257SSteve Yin     int count = pAccessibleContext->getAccessibleChildCount();
5215fdc4257SSteve Yin     for (int i=0;i<count;i++)
5225fdc4257SSteve Yin     {
5235fdc4257SSteve Yin         Reference<com::sun::star::accessibility::XAccessible> mxAccessible
5245fdc4257SSteve Yin         = pAccessibleContext->getAccessibleChild(i);
5255fdc4257SSteve Yin 
5265fdc4257SSteve Yin         com::sun::star::accessibility::XAccessible* mpAccessible = mxAccessible.get();
5275fdc4257SSteve Yin         if(mpAccessible != NULL)
5285fdc4257SSteve Yin         {
5295fdc4257SSteve Yin             pAgent->UpdateState(mpAccessible);
5305fdc4257SSteve Yin             UpdateAllChildrenState(mpAccessible);
5315fdc4257SSteve Yin         }
5325fdc4257SSteve Yin     }
5335fdc4257SSteve Yin }
5345fdc4257SSteve Yin 
5355fdc4257SSteve Yin 
handlePageChangedEvent(const Any &,const Any &)5365fdc4257SSteve Yin void AccContainerEventListener::handlePageChangedEvent(const Any& /*oldValue*/, const Any& /*newValue*/)
5375fdc4257SSteve Yin {
5385fdc4257SSteve Yin     pAgent->NotifyAccEvent(UM_EVENT_OBJECT_PAGECHANGED, pAccessible);
5395fdc4257SSteve Yin }
5405fdc4257SSteve Yin 
handleSectionChangedEvent(const Any &,const Any &)5415fdc4257SSteve Yin void AccContainerEventListener::handleSectionChangedEvent(const Any& /*oldValue*/, const Any& /*newValue*/ )
5425fdc4257SSteve Yin {
5435fdc4257SSteve Yin     pAgent->NotifyAccEvent(UM_EVENT_SECTION_CHANGED, pAccessible);
5445fdc4257SSteve Yin }
5455fdc4257SSteve Yin 
handleColumnChangedEvent(const Any &,const Any &)5465fdc4257SSteve Yin void AccContainerEventListener::handleColumnChangedEvent(const Any& /*oldValue*/, const Any& /*newValue*/)
5475fdc4257SSteve Yin {
5485fdc4257SSteve Yin     pAgent->NotifyAccEvent(UM_EVENT_COLUMN_CHANGED, pAccessible);
5495fdc4257SSteve Yin }
5505fdc4257SSteve Yin 
handleNameChangedEvent(Any name)5515fdc4257SSteve Yin void  AccContainerEventListener::handleNameChangedEvent( Any name )
5525fdc4257SSteve Yin {
5535fdc4257SSteve Yin 	if (getRole() == AccessibleRole::COMBO_BOX)
5545fdc4257SSteve Yin 	{
5555fdc4257SSteve Yin 		Reference<XAccessibleContext> mxContext(pAccessible->getAccessibleContext(),UNO_QUERY);
5565fdc4257SSteve Yin 		if(mxContext.is())
5575fdc4257SSteve Yin 		{
5585fdc4257SSteve Yin 			Reference<XAccessible> mxChild = mxContext->getAccessibleChild(0);
5595fdc4257SSteve Yin 			if(mxChild.is())
5605fdc4257SSteve Yin 			{
5615fdc4257SSteve Yin 				Reference<XAccessibleContext> mxChildContext(mxChild->getAccessibleContext(),UNO_QUERY);
5625fdc4257SSteve Yin 				short childrole = mxChildContext->getAccessibleRole();
5635fdc4257SSteve Yin 				if (childrole == AccessibleRole::TEXT)
5645fdc4257SSteve Yin 				{
5655fdc4257SSteve Yin 					pAgent->UpdateAccName(mxChild.get(), name);
5665fdc4257SSteve Yin 				}
5675fdc4257SSteve Yin 			}
5685fdc4257SSteve Yin 		}
5695fdc4257SSteve Yin 	}
5705fdc4257SSteve Yin 	AccEventListener::handleNameChangedEvent(name);
5715fdc4257SSteve Yin }
572