1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright IBM Corporation 2010.
6  * Copyright 2000, 2010 Oracle and/or its affiliates.
7  *
8  * OpenOffice.org - a multi-platform office productivity suite
9  *
10  * This file is part of OpenOffice.org.
11  *
12  * OpenOffice.org is free software: you can redistribute it and/or modify
13  * it under the terms of the GNU Lesser General Public License version 3
14  * only, as published by the Free Software Foundation.
15  *
16  * OpenOffice.org is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU Lesser General Public License version 3 for more details
20  * (a copy is included in the LICENSE file that accompanied this code).
21  *
22  * You should have received a copy of the GNU Lesser General Public License
23  * version 3 along with OpenOffice.org.  If not, see
24  * <http://www.openoffice.org/license.html>
25  * for a copy of the LGPLv3 License.
26  *
27  ************************************************************************/
28 
29 #include <cassert>
30 
31 #include <com/sun/star/accessibility/XAccessibleEventBroadcaster.hpp>
32 #include <com/sun/star/accessibility/XAccessibleEventListener.hpp>
33 #include <com/sun/star/accessibility/XAccessibleComponent.hpp>
34 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
35 
36 #include <oleacc.h>
37 #ifndef _SV_AccObjectWinManager_HXX
38 #include "AccObjectWinManager.hxx"
39 #endif
40 #include "AccEventListener.hxx"
41 #include "AccComponentEventListener.hxx"
42 #include "AccContainerEventListener.hxx"
43 #include "AccDialogEventListener.hxx"
44 #include "AccWindowEventListener.hxx"
45 #include "AccFrameEventListener.hxx"
46 #include "AccMenuEventListener.hxx"
47 #include "AccObjectContainerEventListener.hxx"
48 #include "AccParagraphEventListener.hxx"
49 #include "AccTextComponentEventListener.hxx"
50 #include "AccListEventListener.hxx"
51 #include "AccTreeEventListener.hxx"
52 #include "AccTableEventListener.hxx"
53 #include "AccObject.hxx"
54 #include "AccessibleEventId.h"
55 #include "AccessibleApplication.h"
56 #include "AccessibleApplication_i.c"
57 #include "unomsaaevent.hxx"
58 #include "checkmt.hxx"
59 
60 #define CHILDID_SELF             0
61 
62 
63 using namespace std;
64 using namespace com::sun::star::accessibility;
65 using namespace com::sun::star::uno;
66 
67 AccObjectWinManager* g_acc_manager = NULL;
68 AccObjectWinManager* AccObjectWinManager::me = NULL;
69 
70 /**
71    * Implementation of interface XMSAAService's method getAccObjectPtr() that return the
72    * corresponding com interface with the MS event.
73    *
74    * @param
75    * @return  Com interface.
76    */
77 long GetMSComPtr(long hWnd, long lParam, long wParam)
78 {
79     if( g_acc_manager )
80         return (long)g_acc_manager->Get_ToATInterface(HWND((void*)hWnd),lParam,wParam );
81     return NULL;
82 }
83 
84 /**
85    * constructor
86    * @param   Agent The agent kept in all listeners,it's the sole interface by which
87    *                listener communicate with windows manager.
88    *          pEventAccObj The present event accobject.
89    *          oldFocus     Last focused object.
90    *          isSelectionChanged flag that identifies if there is selection changed.
91    *		  selectionChildObj  Selected object.
92    *          dChildID	Chile resource ID.
93    *          hAcc TopWindowHWND
94    * @return
95    */
96 AccObjectWinManager::AccObjectWinManager( AccObjectManagerAgent* Agent ):
97         pAgent( Agent ),
98         oldFocus( NULL )
99 {
100 	m_bBridgeRegistered =IsBridgeRegisteredAcc();
101 }
102 
103 /**
104    * Public method to produce manager
105    * @param   Agent The agent kept in all listeners,it's the sole interface by which
106    *          listener communicate with windows manager.
107    * @return
108    */
109 AccObjectWinManager* AccObjectWinManager::CreateAccObjectWinManagerInstance( AccObjectManagerAgent* Agent )
110 {
111     if( me == NULL )
112     {
113         me = new AccObjectWinManager( Agent );
114         g_acc_manager = me;
115         return me;
116     }
117 
118     return me;
119 }
120 
121 
122 /**
123    * Destructor,clear all resource.
124    * @param
125    * @return
126    */
127 AccObjectWinManager::~AccObjectWinManager()
128 {
129     XIdAccList.clear();
130     HwndXAcc.clear();
131     XResIdAccList.clear();
132     XHWNDDocList.clear();
133 #ifdef ACC_DEBUG
134 
135     fclose( pFile );
136 #endif
137 }
138 
139 
140 /**
141    * Get valid com object interface when notifying some MSAA event
142    * @param pWND The top window handle that contains that event control.
143    * @param wParam Windows system interface.
144    * @return Com interface with event.
145    */
146 
147 long AccObjectWinManager::Get_ToATInterface( HWND hWnd, long lParam, long wParam)
148 {
149     vos::OGuard localGuard(maATInterfaceMutex);//
150 
151     IMAccessible* pRetIMAcc = NULL;
152 
153     if(lParam == OBJID_CLIENT )
154     {
155         AccObject* topWindowAccObj = GetTopWindowAccObj(hWnd);
156         if(topWindowAccObj)
157         {
158             pRetIMAcc = topWindowAccObj->GetIMAccessible();
159             if(pRetIMAcc)
160                 pRetIMAcc->AddRef();//increase COM reference count
161         }
162     }
163 
164     if ( pRetIMAcc && lParam == OBJID_CLIENT )
165     {
166         IAccessible* pTemp = dynamic_cast<IAccessible*>( pRetIMAcc );
167         HRESULT result = LresultFromObject(IID_IAccessible, wParam, pTemp);
168         pTemp->Release();
169         return result;
170     }
171     return 0;
172 }
173 
174 /**
175    * Search AccObject by XAccessible pointer from our container.
176    * @param pXAcc XAccessible interface.
177    * @return Pointer of accObject that is found.
178    */
179 AccObject* AccObjectWinManager::GetAccObjByXAcc( XAccessible* pXAcc)
180 {
181     if( pXAcc == NULL)
182         return NULL;
183 
184     XIdToAccObjHash::iterator pIndTemp = XIdAccList.find( (void*)pXAcc );
185     if ( pIndTemp == XIdAccList.end() )
186         return NULL;
187 
188     return &(pIndTemp->second);
189 }
190 
191 /**
192    * Search XAccessible by AccObject pointer from our container.
193    * @param pAccObj AccObject pointer.
194    * @return Pointer of XAccessible Interface.
195    */
196 XAccessible* AccObjectWinManager::GetXAccByAccObj(AccObject* pAccObj)
197 {
198     XIdToAccObjHash::iterator iter = XIdAccList.begin();
199     while(iter!=XIdAccList.end())
200     {
201         AccObject* tmp = &(iter->second);
202         if(tmp== pAccObj)
203             return (XAccessible*)(iter->first);
204         iter++;
205     }
206     return NULL;
207 }
208 
209 /**
210    * get acc object of top window by its handle
211    * @param hWnd, top window handle
212    * @return pointer to AccObject
213    */
214 AccObject* AccObjectWinManager::GetTopWindowAccObj(HWND hWnd)
215 {
216     XHWNDToXAccHash::iterator iterResult =HwndXAcc.find(hWnd);
217     if(iterResult == HwndXAcc.end())
218         return NULL;
219     XAccessible* pXAcc = (XAccessible*)(iterResult->second);
220     return GetAccObjByXAcc(pXAcc);
221 }
222 
223 /**
224    * Simulate MSAA event via XAccessible interface and event type.
225    * @param pXAcc XAccessible interface.
226    * @param state Customize Interface
227    * @return The terminate result that identifies if the call is successful.
228    */
229 sal_Bool AccObjectWinManager::NotifyAccEvent(XAccessible* pXAcc,short state)
230 {
231     vos::OGuard aGuard(aNotifyMutex);
232 
233 	if (!m_bBridgeRegistered)
234 	{
235 		return sal_False;
236 	}
237     if (!IsInMainThread())
238     {
239         return sal_False;
240     }
241 
242     Reference< XAccessibleContext > pRContext;
243 
244     if( pXAcc == NULL)
245         return sal_False;
246 
247 
248     pRContext = pXAcc->getAccessibleContext();
249     if( !pRContext.is() )
250         return sal_False;
251 
252 
253     AccObject* selfAccObj= GetAccObjByXAcc(pXAcc);
254 
255     if(selfAccObj==NULL)
256         return sal_False;
257 
258     int selectNum =0;
259 
260     long dChildID = selfAccObj->GetResID();
261     HWND hAcc = selfAccObj->GetParentHWND();
262 
263     switch(state)
264     {
265     case UM_EVENT_STATE_FOCUSED:
266         {
267             UpdateAccFocus(pXAcc);
268             if( selfAccObj )
269                 selfAccObj->UpdateDefaultAction( );
270             UpdateValue(pXAcc);
271             NotifyWinEvent( EVENT_OBJECT_FOCUS,hAcc, OBJID_CLIENT,dChildID  );
272             break;
273         }
274     case UM_EVENT_STATE_BUSY:
275         NotifyWinEvent( EVENT_OBJECT_STATECHANGE,hAcc, OBJID_CLIENT,dChildID  );
276         break;
277     case UM_EVENT_STATE_CHECKED:
278         NotifyWinEvent( EVENT_OBJECT_STATECHANGE,hAcc, OBJID_CLIENT,dChildID  );
279         break;
280     case UM_EVENT_STATE_PRESSED:
281         NotifyWinEvent( EVENT_OBJECT_STATECHANGE,hAcc, OBJID_CLIENT,dChildID  );
282         break;
283 
284     //Removed fire out selected event
285     //case UM_EVENT_STATE_SELECTED:
286     //	NotifyWinEvent( EVENT_OBJECT_STATECHANGE,hAcc, OBJID_CLIENT,dChildID  );
287     //	break;
288     case UM_EVENT_STATE_ARMED:
289         UpdateAccFocus(pXAcc);
290         NotifyWinEvent( EVENT_OBJECT_FOCUS,hAcc, OBJID_CLIENT,dChildID  );
291         break;
292     case UM_EVENT_MENU_START:
293         NotifyWinEvent( EVENT_SYSTEM_MENUSTART,hAcc, OBJID_CLIENT,dChildID  );
294         break;
295     case UM_EVENT_MENU_END:
296         NotifyWinEvent( EVENT_SYSTEM_MENUEND,hAcc, OBJID_CLIENT,dChildID  );
297         break;
298     case UM_EVENT_MENUPOPUPSTART:
299         NotifyWinEvent( EVENT_SYSTEM_MENUPOPUPSTART,hAcc, OBJID_CLIENT,dChildID  );
300         break;
301     case UM_EVENT_MENUPOPUPEND:
302         NotifyWinEvent( EVENT_SYSTEM_MENUPOPUPEND,hAcc, OBJID_CLIENT,dChildID  );
303         break;
304     case UM_EVENT_SELECTION_CHANGED:
305         NotifyWinEvent( EVENT_OBJECT_SELECTION,hAcc, OBJID_CLIENT,dChildID  );
306         break;
307     case UM_EVENT_SELECTION_CHANGED_ADD:
308        	NotifyWinEvent( EVENT_OBJECT_SELECTIONADD,hAcc, OBJID_CLIENT,dChildID  );
309        	break;
310     case UM_EVENT_SELECTION_CHANGED_REMOVE:
311        	NotifyWinEvent( EVENT_OBJECT_SELECTIONREMOVE,hAcc, OBJID_CLIENT,dChildID  );
312        	break;
313     case UM_EVENT_SELECTION_CHANGED_WITHIN:
314        	NotifyWinEvent( EVENT_OBJECT_SELECTIONWITHIN,hAcc, OBJID_CLIENT,dChildID  );
315        	break;
316     case UM_EVENT_OBJECT_VALUECHANGE:
317         UpdateValue(pXAcc);
318         NotifyWinEvent( EVENT_OBJECT_VALUECHANGE,hAcc, OBJID_CLIENT,dChildID  );
319         break;
320     case UM_EVENT_OBJECT_NAMECHANGE:
321         NotifyWinEvent( EVENT_OBJECT_NAMECHANGE,hAcc, OBJID_CLIENT,dChildID  );
322         break;
323     case UM_EVENT_OBJECT_DESCRIPTIONCHANGE:
324         NotifyWinEvent( EVENT_OBJECT_DESCRIPTIONCHANGE,hAcc, OBJID_CLIENT,dChildID  );
325         break;
326     case UM_EVENT_OBJECT_DEFACTIONCHANGE:
327         NotifyWinEvent( IA2_EVENT_ACTION_CHANGED,hAcc, OBJID_CLIENT,dChildID  );
328         break;
329     case UM_EVENT_OBJECT_CARETCHANGE:
330         NotifyWinEvent( IA2_EVENT_TEXT_CARET_MOVED,hAcc, OBJID_CLIENT,dChildID  );
331         break;
332     case UM_EVENT_OBJECT_TEXTCHANGE:
333         NotifyWinEvent( IA2_EVENT_TEXT_CHANGED,hAcc, OBJID_CLIENT,dChildID  );
334         break;
335     case UM_EVENT_ACTIVE_DESCENDANT_CHANGED:
336         UpdateAccFocus(pXAcc);
337         NotifyWinEvent( EVENT_OBJECT_FOCUS,hAcc, OBJID_CLIENT,dChildID  );
338         break;
339     case UM_EVENT_BOUNDRECT_CHANGED:
340         NotifyWinEvent( EVENT_OBJECT_LOCATIONCHANGE,hAcc, OBJID_CLIENT,dChildID  );
341         break;
342     case UM_EVENT_VISIBLE_DATA_CHANGED:
343         NotifyWinEvent( IA2_EVENT_VISIBLE_DATA_CHANGED,hAcc, OBJID_CLIENT,dChildID  );
344         break;
345     case UM_EVENT_SHOW :
346         NotifyWinEvent( EVENT_OBJECT_SHOW,hAcc, OBJID_CLIENT,dChildID  );
347         NotifyWinEvent( EVENT_SYSTEM_FOREGROUND,hAcc, OBJID_CLIENT,dChildID  );
348 	break;
349     case UM_EVENT_TABLE_CAPTION_CHANGED:
350         NotifyWinEvent( IA2_EVENT_TABLE_CAPTION_CHANGED,hAcc, OBJID_CLIENT,dChildID  );
351         break;
352     case UM_EVENT_TABLE_COLUMN_DESCRIPTION_CHANGED:
353         NotifyWinEvent( IA2_EVENT_TABLE_COLUMN_DESCRIPTION_CHANGED,hAcc, OBJID_CLIENT,dChildID  );
354         break;
355     case UM_EVENT_TABLE_COLUMN_HEADER_CHANGED:
356         NotifyWinEvent( IA2_EVENT_TABLE_COLUMN_HEADER_CHANGED,hAcc, OBJID_CLIENT,dChildID  );
357         break;
358     case UM_EVENT_TABLE_MODEL_CHANGED:
359         NotifyWinEvent( IA2_EVENT_TABLE_MODEL_CHANGED,hAcc, OBJID_CLIENT,dChildID  );
360         break;
361     case UM_EVENT_TABLE_ROW_HEADER_CHANGED:
362         NotifyWinEvent( IA2_EVENT_TABLE_ROW_HEADER_CHANGED,hAcc, OBJID_CLIENT,dChildID  );
363         break;
364     case UM_EVENT_TABLE_SUMMARY_CHANGED:
365         NotifyWinEvent( IA2_EVENT_TABLE_SUMMARY_CHANGED,hAcc, OBJID_CLIENT,dChildID  );
366         break;
367     case UM_EVENT_TABLE_ROW_DESCRIPTION_CHANGED:
368         NotifyWinEvent( IA2_EVENT_TABLE_ROW_DESCRIPTION_CHANGED,hAcc, OBJID_CLIENT,dChildID  );
369         break;
370     case UM_EVENT_OBJECT_REORDER:
371         NotifyWinEvent( EVENT_OBJECT_REORDER,hAcc, OBJID_CLIENT,dChildID  );
372         break;
373     case UM_EVENT_PAGE_CHANGED:
374         NotifyWinEvent( IA2_EVENT_PAGE_CHANGED,hAcc, OBJID_CLIENT,dChildID  );
375         break;
376     case UM_EVENT_CHILD_REMOVED:
377         NotifyWinEvent( EVENT_OBJECT_DESTROY,hAcc, OBJID_CLIENT,dChildID  );
378         break;
379     case UM_EVENT_CHILD_ADDED:
380         NotifyWinEvent( EVENT_OBJECT_CREATE ,hAcc, OBJID_CLIENT,dChildID  );
381         break;
382     case UM_EVENT_OBJECT_PAGECHANGED:
383         NotifyWinEvent( IA2_EVENT_PAGE_CHANGED ,hAcc, OBJID_CLIENT,dChildID  );
384         break;
385     case UM_EVENT_TEXT_SELECTION_CHANGED:
386         NotifyWinEvent( IA2_EVENT_TEXT_SELECTION_CHANGED ,hAcc, OBJID_CLIENT,dChildID  );
387         break;
388     case UM_EVENT_SECTION_CHANGED:
389         NotifyWinEvent( IA2_EVENT_SECTION_CHANGED ,hAcc, OBJID_CLIENT,dChildID  );
390         break;
391     case UM_EVENT_COLUMN_CHANGED:
392         NotifyWinEvent( IA2_EVENT_TEXT_COLUMN_CHANGED ,hAcc, OBJID_CLIENT,dChildID  );
393         break;
394     default:
395         break;
396     }
397 
398     return sal_True;
399 }
400 
401 /**
402    * Get Parent XAccessible interface by XAccessible interface.
403    * @param pXAcc XAccessible interface.
404    * @return Parent XAccessible interface.
405    */
406 XAccessible* AccObjectWinManager::GetParentXAccessible( XAccessible* pXAcc )
407 {
408     AccObject* pObj= GetAccObjByXAcc(pXAcc);
409     if( pObj ==NULL )
410         return NULL;
411     if(pObj->GetParentObj())
412     {
413         pObj = pObj->GetParentObj();
414         return pObj->GetXAccessible().get();
415     }
416     return NULL;
417 }
418 
419 /**
420    * Get Parent role by XAccessible interface.
421    * @param pXAcc XAccessible interface.
422    * @return Parent role.
423    */
424 short AccObjectWinManager::GetParentRole( XAccessible* pXAcc )
425 {
426     AccObject* pObj= GetAccObjByXAcc(pXAcc);
427     if( pObj ==NULL )
428         return -1;
429     if(pObj->GetParentObj())
430     {
431         pObj = pObj->GetParentObj();
432         if(pObj->GetXAccessible().is())
433         {
434             XAccessible* pXAcc = pObj->GetXAccessible().get();
435             Reference< XAccessibleContext > pRContext = pXAcc->getAccessibleContext();
436             if(pRContext.is())
437                 return pRContext->getAccessibleRole();
438         }
439     }
440     return -1;
441 }
442 
443 /**
444    * Update focus objcet by new focused XAccessible interface.
445    * @param newFocus New XAccessible interface that gets focus.
446    * @return
447    */
448 void AccObjectWinManager::UpdateAccFocus(XAccessible* newFocus)
449 {
450     AccObject* pAccObjNew = GetAccObjByXAcc(newFocus);
451     if(pAccObjNew)
452     {
453         AccObject* pAccObjOld = GetAccObjByXAcc(oldFocus);
454         oldFocus = newFocus;
455         pAccObjNew->setFocus();
456         //if old == new, the pAccObjNew will be without focused state
457         if (pAccObjOld && pAccObjOld != pAccObjNew)
458             pAccObjOld->unsetFocus();
459     }
460 }
461 
462 /**
463    * Update selected objcet by new focused XAccessible interface.
464    * @param pXAcc XAccessible interface that has selected child changed.
465    * @return Selected children count.
466    */
467 int AccObjectWinManager::UpdateAccSelection(XAccessible* pXAcc)
468 {
469     XAccessibleSelection* pSelection = NULL;
470     Reference< XAccessibleContext > pRContext;
471 
472     if( pXAcc == NULL)
473         return sal_False;
474 
475     pRContext = pXAcc->getAccessibleContext();
476     if( !pRContext.is() )
477         return sal_False;
478 
479     Reference< XAccessibleSelection > pRSelection(pRContext,UNO_QUERY);
480     if( !pRSelection.is() )
481         return sal_False;
482 
483     AccObject* pAccObj = GetAccObjByXAcc(pXAcc);
484     if(pAccObj==NULL)
485         return sal_False;
486 
487     Reference<XAccessible> pRChild = NULL;
488     AccObject* pAccChildObj = NULL;
489     int selectNum= pRSelection->getSelectedAccessibleChildCount();
490 
491     IAccSelectionList oldSelection = pAccObj->GetSelection();
492 
493     if(selectNum > 4)//for selected.
494         return selectNum;
495     if(selectNum == 1 && oldSelection.size() == 0)
496         return 1;
497 
498     for (int i=0;i<selectNum;i++)
499     {
500         pRChild = pRSelection->getSelectedAccessibleChild(i);
501         if(!pRChild.is())
502         {
503             continue;
504         }
505         Reference<XAccessibleContext> pRChildContext = pRChild->getAccessibleContext();
506         if(!pRChildContext.is())
507         {
508             continue;
509         }
510         long index = pRChildContext->getAccessibleIndexInParent();
511         IAccSelectionList::iterator temp = oldSelection.find(index);
512         if ( temp != oldSelection.end() )
513         {
514             oldSelection.erase(index);
515             continue;
516         }
517 
518         pAccChildObj = NULL;
519         pAccChildObj = GetAccObjByXAcc(pRChild.get());
520         if(!pAccChildObj)
521         {
522             InsertAccObj(pRChild.get(), pXAcc,pAccObj->GetParentHWND());
523             pAccChildObj = GetAccObjByXAcc(pRChild.get());
524         }
525 
526         pAccObj->AddSelect(index, pAccChildObj);
527 
528         if(pAccChildObj != NULL)
529             NotifyWinEvent(EVENT_OBJECT_SELECTIONADD,pAccObj->GetParentHWND(), OBJID_CLIENT,pAccChildObj->GetResID());
530     }
531 
532     IAccSelectionList::iterator iter = oldSelection.begin();
533     while(iter!=oldSelection.end())
534     {
535         pAccObj->GetSelection().erase(iter->first);
536         pAccChildObj = (AccObject*)(iter->second);
537         if(pAccChildObj != NULL)
538             NotifyWinEvent(EVENT_OBJECT_SELECTIONREMOVE,pAccObj->GetParentHWND(), OBJID_CLIENT,pAccChildObj->GetResID());
539         iter++;
540     }
541     return 0;
542 
543 }
544 
545 /**
546    * Delete child element from children list.
547    * @param pObj Child element that should be removed from parant child list.
548    * @return
549    */
550 void AccObjectWinManager::DeleteAccChildNode( AccObject* pObj )
551 {
552     AccObject *parentAccObj = pObj->GetParentObj();
553     if( parentAccObj )
554         parentAccObj->DeleteChild( pObj );
555 }
556 
557 /**
558    * Delete XAccessible items in top window handle hashtable
559    * @param pXAcc XAccessible interface.
560    * @return
561    */
562 void AccObjectWinManager::DeleteFromHwndXAcc(XAccessible* pXAcc )
563 {
564     XHWNDToXAccHash::iterator iter = HwndXAcc.begin();
565     while(iter!=HwndXAcc.end())
566     {
567         if(iter->second == pXAcc )
568         {
569             HwndXAcc.erase(iter);
570             return;
571         }
572         iter++;
573     }
574 }
575 
576 /**
577    * Delete Delete all children with the tree root of XAccessible pointer
578    * @param pXAcc Tree root XAccessible interface.
579    * @return
580    */
581 void AccObjectWinManager::DeleteChildrenAccObj(XAccessible* pXAcc)
582 {
583     vos::OGuard aGuard( aDeleteMutex );
584     AccObject* currentObj=NULL;
585     AccObject* childObj=NULL;
586     XAccessible* pTmpXAcc=NULL;
587 
588     currentObj =  GetAccObjByXAcc( pXAcc);
589     if(currentObj)
590     {
591         childObj = currentObj->NextChild();
592         while(childObj)
593         {
594             pTmpXAcc = GetXAccByAccObj(childObj);
595             if(pTmpXAcc)
596             {
597                 DeleteChildrenAccObj(pTmpXAcc);
598                 DeleteAccObj(pTmpXAcc);
599             }
600             childObj = currentObj->NextChild();
601         }
602     }
603 }
604 
605 /**
606    * Delete Delete Acc object self.
607    * @param pXAcc The XAccessible interface.
608    * @return
609    */
610 void AccObjectWinManager::DeleteAccObj( XAccessible* pXAcc )
611 {
612     vos::OGuard aGuard( aDeleteMutex );
613     if( pXAcc == NULL )
614         return;
615     XIdToAccObjHash::iterator temp = XIdAccList.find(pXAcc);
616     if( temp != XIdAccList.end() )
617     {
618         ResIdGen.SetSub( temp->second.GetResID() );
619     }
620     else
621     {
622         return;
623     }
624 
625     AccObject& accObj = temp->second;
626     DeleteAccChildNode( &accObj );
627     DeleteAccListener( &accObj );
628     if( accObj.GetIMAccessible() )
629     {
630         accObj.GetIMAccessible()->Release();
631     }
632     XIdAccList.erase( pXAcc );
633     XResIdAccList.erase( accObj.GetResID() );
634     DeleteFromHwndXAcc(pXAcc);
635 }
636 
637 /**
638    * Delete listener that inspects some XAccessible object
639    * @param pAccObj Accobject pointer.
640    * @return
641    */
642 void AccObjectWinManager::DeleteAccListener( AccObject*  pAccObj )
643 {
644     AccEventListener* listener = pAccObj->getListener();
645     if( listener==NULL )
646         return;
647     listener->removeMeFromBroadcaster();
648     pAccObj->SetListener(NULL);
649 }
650 
651 /**
652    * Generate a child ID, which is used for AT
653    * @param
654    * @return New resource ID.
655    */
656 inline long AccObjectWinManager::ImpleGenerateResID()
657 {
658     return ResIdGen.GenerateNewResID();
659 }
660 
661 /**
662    * Insert all children of the current acc object
663    * @param pXAcc XAccessible interface
664    * @param pWnd  Top Window handle
665    * @return The calling result.
666    */
667 sal_Bool AccObjectWinManager::InsertChildrenAccObj( com::sun::star::accessibility::XAccessible* pXAcc,
668         HWND pWnd)
669 {
670     if(!IsContainer(pXAcc))
671         return sal_False;
672 
673     Reference< XAccessibleContext > pRContext;
674 
675     if( pXAcc == NULL)
676         return sal_False;
677     pRContext = pXAcc->getAccessibleContext();
678     if( !pRContext.is() )
679         return sal_False;
680 
681     short role = pRContext->getAccessibleRole();
682 
683     if(com::sun::star::accessibility::AccessibleRole::DOCUMENT == role )
684     {
685         if(IsStateManageDescendant(pXAcc))
686         {
687             return sal_True;
688         }
689     }
690 
691     int count = pRContext->getAccessibleChildCount();
692     for (int i=0;i<count;i++)
693     {
694         Reference<XAccessible> mxAccessible
695         = pRContext->getAccessibleChild(i);
696         XAccessible* mpAccessible = mxAccessible.get();
697         if(mpAccessible != NULL)
698         {
699             InsertAccObj( mpAccessible,pXAcc,pWnd );
700             InsertChildrenAccObj(mpAccessible,pWnd);
701         }
702     }
703 
704     return sal_True;
705 }
706 
707 /**
708    * Insert child object.
709    * @param pCurObj The child object
710    * @param pParentObj The parant object
711    * @param pWnd Top window handle.
712    * @return
713    */
714 void AccObjectWinManager::InsertAccChildNode( AccObject* pCurObj, AccObject* pParentObj, HWND /* pWnd */ )
715 {
716     if(pCurObj)
717     {
718         if(pParentObj)
719         {
720             pParentObj->InsertChild(pCurObj);
721         }
722         else
723         {
724             pCurObj->UpdateValidWindow();
725         }
726     }
727 }
728 
729 /**
730    * Insert child object.
731    * @param pCurObj The child object
732    * @param pParentObj The parant object
733    * @param pWnd Top window handle.
734    * @return
735    */
736 sal_Bool AccObjectWinManager::InsertAccObj( XAccessible* pXAcc,XAccessible* pParentXAcc,HWND pWnd )
737 {
738 	if (!m_bBridgeRegistered)
739 	{
740 		return sal_False;
741 	}
742     XIdToAccObjHash::iterator itXacc = XIdAccList.find( (void*)pXAcc );
743     if (itXacc != XIdAccList.end() )
744     {
745         short nCurRole =GetRole(pXAcc);
746         if (AccessibleRole::SHAPE == nCurRole)
747         {
748             AccObject &objXacc = itXacc->second;
749             AccObject *pObjParent = objXacc.GetParentObj();
750             if (pObjParent &&
751                     pObjParent->GetXAccessible().is() &&
752                     pObjParent->GetXAccessible().get() != pParentXAcc)
753             {
754                 XIdToAccObjHash::iterator itXaccParent  = XIdAccList.find( (void*)pParentXAcc );
755                 if(itXaccParent != XIdAccList.end())
756                 {
757                     objXacc.SetParentObj(&(itXaccParent->second));
758                 }
759             }
760         }
761         return sal_False;
762     }
763 
764 
765     Reference< XAccessibleContext > pRContext;
766 
767     if( pXAcc == NULL)
768         return sal_False;
769 
770     pRContext = pXAcc->getAccessibleContext();
771     if( !pRContext.is() )
772         return sal_False;
773 
774     if( pWnd == NULL )
775     {
776         if(pParentXAcc)
777         {
778             AccObject* pObj = GetAccObjByXAcc(pParentXAcc);
779             if(pObj)
780                 pWnd = pObj->GetParentHWND();
781         }
782         if( pWnd == NULL )
783             return sal_False;
784     }
785 
786     AccObject pObj( pXAcc,pAgent );
787     if( pObj.GetIMAccessible() == NULL )
788         return sal_False;
789     pObj.SetResID( this->ImpleGenerateResID());
790     pObj.SetParentHWND( pWnd );
791 
792     //for file name support
793     if ( pObj.GetRole() == DOCUMENT )
794     {
795         XHWNDToDocumentHash::iterator aIter = XHWNDDocList.find( (long)pWnd );
796         if ( aIter != XHWNDDocList.end() )
797         {
798             XHWNDDocList.erase( aIter );
799         }
800         XHWNDDocList.insert( XHWNDToDocumentHash::value_type( (long)pWnd, pXAcc ) );
801 
802     }
803     //end of file name
804 
805     AccEventListener* listener = createAccEventListener(pXAcc, pAgent);
806     if(listener==NULL)
807         return sal_False;
808     Reference<XAccessibleComponent> xComponent(pRContext,UNO_QUERY);
809     Reference<XAccessibleEventBroadcaster> broadcaster(xComponent,UNO_QUERY);
810     if (broadcaster.is())
811     {
812         Reference <XAccessibleEventListener> pp (
813             static_cast< XAccessibleEventListener* >(listener),UNO_QUERY );
814         if(pp.is())
815         {
816             broadcaster->addEventListener(pp);
817         }
818         else
819         {
820             delete listener;
821             return sal_False;
822         }
823     }
824     else
825         return sal_False;
826 
827     XIdAccList.insert( XIdToAccObjHash::value_type( (void*)pXAcc, pObj ));
828     XIdToAccObjHash::iterator pIndTemp = XIdAccList.find( (void*)pXAcc );
829     XResIdAccList.insert(XResIdToAccObjHash::value_type(pObj.GetResID(),&(pIndTemp->second)));
830 
831     AccObject* pCurObj = GetAccObjByXAcc(pXAcc);
832     if( pCurObj )
833     {
834         pCurObj->SetListener( listener );
835         if(listener != NULL)
836             listener->acquire();
837     }
838 
839     AccObject* pParentObj = GetAccObjByXAcc(pParentXAcc);
840     InsertAccChildNode(pCurObj,pParentObj,pWnd);
841     if( pCurObj )
842         pCurObj->UpdateAccessibleInfoFromUnoToMSAA();
843     return sal_True;
844 }
845 
846 
847 /**
848    * save the pair <topwindowhandle, XAccessible>
849    * @param hWnd, top window handle
850    * @param pXAcc XAccessible interface for top window
851    * @return void
852    */
853 void AccObjectWinManager::SaveTopWindowHandle(HWND hWnd, com::sun::star::accessibility::XAccessible* pXAcc)
854 {
855     HwndXAcc.insert( XHWNDToXAccHash::value_type( hWnd,(void*)pXAcc ) );
856 }
857 
858 
859 /**
860    * create the corresponding listener.
861    * @param pXAcc XAccessible interface.
862    * @param Agent The agent kept in all listeners,it's the sole interface by which
863    *        listener communicate with windows manager.
864    * @return
865    */
866 AccEventListener* AccObjectWinManager::createAccEventListener(XAccessible* pXAcc, AccObjectManagerAgent* /* Agent */ )
867 {
868     AccEventListener* listener = NULL;
869     Reference<XAccessibleContext> xContext(pXAcc->getAccessibleContext(),UNO_QUERY);
870     if(xContext.is())
871     {
872         switch( xContext->getAccessibleRole() )
873         {
874         case /*AccessibleRole::*/DIALOG:
875             listener = new AccDialogEventListener(pXAcc,pAgent);
876             break;
877         case /*AccessibleRole::*/FRAME:
878             listener = new AccFrameEventListener(pXAcc,pAgent);
879             break;
880         case /*AccessibleRole::*/WINDOW:
881             listener = new AccWindowEventListener(pXAcc,pAgent);
882             break;
883         case /*AccessibleRole::*/ROOT_PANE:
884             listener = new AccFrameEventListener(pXAcc,pAgent);
885             break;
886             //Container
887         case /*AccessibleRole::*/CANVAS:
888         case /*AccessibleRole::*/COMBO_BOX:
889         case /*AccessibleRole::*/DOCUMENT:
890         case /*AccessibleRole::*/END_NOTE:
891         case /*AccessibleRole::*/FILLER:
892         case /*AccessibleRole::*/FOOTNOTE:
893         case /*AccessibleRole::*/FOOTER:
894         case /*AccessibleRole::*/HEADER:
895         case /*AccessibleRole::*/LAYERED_PANE:
896         case /*AccessibleRole::*/MENU_BAR:
897         case /*AccessibleRole::*/POPUP_MENU:
898         case /*AccessibleRole::*/OPTION_PANE:
899         case /*AccessibleRole::*/PAGE_TAB:
900         case /*AccessibleRole::*/PAGE_TAB_LIST:
901         case /*AccessibleRole::*/PANEL:
902         case /*AccessibleRole::*/SCROLL_PANE:
903         case /*AccessibleRole::*/SPLIT_PANE:
904         case /*AccessibleRole::*/STATUS_BAR:
905         case /*AccessibleRole::*/TABLE_CELL:
906         case /*AccessibleRole::*/TOOL_BAR:
907         case /*AccessibleRole::*/VIEW_PORT:
908             listener = new AccContainerEventListener(pXAcc,pAgent);
909             break;
910         case /*AccessibleRole::*/PARAGRAPH:
911         case /*AccessibleRole::*/HEADING:
912             listener = new AccParagraphEventListener(pXAcc,pAgent);
913             break;
914             //Component
915         case /*AccessibleRole::*/CHECK_BOX:
916         case /*AccessibleRole::*/ICON:
917         case /*AccessibleRole::*/LABEL:
918         case /*AccessibleRole::*/MENU_ITEM:
919         case /*AccessibleRole::*/CHECK_MENU_ITEM:
920         case /*AccessibleRole::*/RADIO_MENU_ITEM:
921         case /*AccessibleRole::*/PUSH_BUTTON:
922         case /*AccessibleRole::*/RADIO_BUTTON:
923         case /*AccessibleRole::*/SCROLL_BAR:
924         case /*AccessibleRole::*/SEPARATOR:
925         case /*AccessibleRole::*/TOGGLE_BUTTON:
926         case /*AccessibleRole::*/BUTTON_DROPDOWN:
927         case /*AccessibleRole::*/TOOL_TIP:
928         case /*AccessibleRole::*/SPIN_BOX:
929         case DATE_EDITOR:
930             listener = new AccComponentEventListener(pXAcc,pAgent);
931             break;
932             //text component
933         case /*AccessibleRole::*/TEXT:
934             listener = new AccTextComponentEventListener(pXAcc,pAgent);
935             break;
936             //menu
937         case /*AccessibleRole::*/MENU:
938             listener = new AccMenuEventListener(pXAcc,pAgent);
939             break;
940             //object container
941         case /*AccessibleRole::*/SHAPE:
942 
943         case /*AccessibleRole::*/EMBEDDED_OBJECT:
944         case /*AccessibleRole::*/GRAPHIC:
945         case /*AccessibleRole::*/TEXT_FRAME:
946             listener = new AccObjectContainerEventListener(pXAcc,pAgent);
947             break;
948             //descendmanager
949         case /*AccessibleRole::*/LIST:
950             listener = new AccListEventListener(pXAcc,pAgent);
951             break;
952         case /*AccessibleRole::*/TREE:
953             listener = new AccTreeEventListener(pXAcc,pAgent);
954             break;
955             //special
956         case /*AccessibleRole::*/COLUMN_HEADER:
957         case /*AccessibleRole::*/TABLE:
958             listener = new AccTableEventListener(pXAcc,pAgent);
959             break;
960         default:
961             listener = new AccContainerEventListener(pXAcc,pAgent);
962             break;
963         }
964     }
965 
966     return listener;
967 }
968 
969 /**
970    * state is a combination integer, each bit of which represents a single state,
971    * such as focused,1 for the state on,0 for the state off. Here call COM interface
972    * to modify the state value, including DecreaseState.
973    * @param pXAcc XAccessible interface.
974    * @param pState Changed state.
975    * @return
976    */
977 void AccObjectWinManager::DecreaseState( XAccessible* pXAcc,unsigned short pState )
978 {
979     AccObject* pAccObj = GetAccObjByXAcc( pXAcc );
980     if( pAccObj )
981         pAccObj->DecreaseState( pState );
982 }
983 
984 /**
985    * state is a combination integer, each bit of which represents a single state,such as focused,1 for
986    * the state on,0 for the state off. Here call COM interface to modify the state value, including
987    * IncreaseState.
988    * @param pXAcc XAccessible interface.
989    * @param pState Changed state.
990    * @return
991    */
992 void AccObjectWinManager::IncreaseState( XAccessible* pXAcc,unsigned short pState )
993 {
994     AccObject* pAccObj = GetAccObjByXAcc( pXAcc );
995     if( pAccObj )
996         pAccObj->IncreaseState( pState );
997 }
998 
999 void  AccObjectWinManager::UpdateState( com::sun::star::accessibility::XAccessible* pXAcc )
1000 {
1001     AccObject* pAccObj = GetAccObjByXAcc( pXAcc );
1002     if( pAccObj )
1003         pAccObj->UpdateState( );
1004 }
1005 
1006 /**
1007    * Set corresponding com object's accessible name via XAccessilbe interface and new
1008    * name
1009    * @param pXAcc XAccessible interface.
1010    * @return
1011    */
1012 void  AccObjectWinManager::UpdateAccName( XAccessible* pXAcc )
1013 {
1014     AccObject* pAccObj = GetAccObjByXAcc( pXAcc );
1015     if( pAccObj )
1016         pAccObj->UpdateName();
1017 }
1018 
1019 void  AccObjectWinManager::UpdateAction( XAccessible* pXAcc )
1020 {
1021     AccObject* pAccObj = GetAccObjByXAcc( pXAcc );
1022     if( pAccObj )
1023         pAccObj->UpdateAction();
1024 }
1025 
1026 void AccObjectWinManager::UpdateDescription( XAccessible* pXAcc )
1027 {
1028     AccObject* pAccObj = GetAccObjByXAcc( pXAcc );
1029     if ( pAccObj )
1030         pAccObj->UpdateDescription();
1031 }
1032 
1033 /**
1034    * Set corresponding com object's accessible location via XAccessilbe interface and new
1035    * location.
1036    * @param pXAcc XAccessible interface.
1037    * @return
1038    */
1039 void  AccObjectWinManager::SetLocation( XAccessible* pXAcc, long /*top*/, long /*left*/, long /*width*/, long /*height*/ )
1040 {
1041     AccObject* pObj = GetAccObjByXAcc( pXAcc );
1042     //get the location from XComponent.
1043     Reference< XAccessibleContext > pRContext = pXAcc->getAccessibleContext();
1044     if( pObj )
1045         pObj->UpdateLocation();
1046 }
1047 
1048 /**
1049    * Set corresponding com object's value  via XAccessilbe interface and new value.
1050    * @param pXAcc XAccessible interface.
1051    * @param pAny new value.
1052    * @return
1053    */
1054 void  AccObjectWinManager::SetValue( XAccessible* pXAcc, Any pAny )
1055 {
1056     AccObject* pAccObj = GetAccObjByXAcc( pXAcc );
1057     if( pAccObj )
1058         pAccObj->SetValue( pAny );
1059 }
1060 
1061 /**
1062    * Set corresponding com object's value  via XAccessilbe interface.
1063    * @param pXAcc XAccessible interface.
1064    * @return
1065    */
1066 void  AccObjectWinManager::UpdateValue( XAccessible* pXAcc )
1067 {
1068     AccObject* pAccObj = GetAccObjByXAcc( pXAcc );
1069     if( pAccObj )
1070         pAccObj->UpdateValue();
1071 }
1072 
1073 /**
1074    * Set corresponding com object's name via XAccessilbe interface and new name.
1075    * @param pXAcc XAccessible interface.
1076    * @param newName new name
1077    * @return
1078    */
1079 void  AccObjectWinManager::SetAccName( XAccessible* pXAcc, Any newName)
1080 {
1081     AccObject* pAccObj = GetAccObjByXAcc( pXAcc );
1082     if( pAccObj )
1083         pAccObj->SetName( newName );
1084 }
1085 
1086 /**
1087    * Set corresponding com object's description via XAccessilbe interface and new description.
1088    * @param pXAcc XAccessible interface.
1089    * @param newDesc new description
1090    * @return
1091    */
1092 void  AccObjectWinManager::SetDescription( XAccessible* pXAcc, Any newDesc )
1093 {
1094     AccObject* pAccObj = GetAccObjByXAcc( pXAcc );
1095     if( pAccObj )
1096         pAccObj->SetDescription( newDesc );
1097 }
1098 
1099 /**
1100    * Set corresponding com object's role via XAccessilbe interface and new role.
1101    * @param pXAcc XAccessible interface.
1102    * @param Role new role
1103    * @return
1104    */
1105 void  AccObjectWinManager::SetRole( XAccessible* pXAcc, long Role )
1106 {
1107     AccObject* pAccObj = GetAccObjByXAcc( pXAcc );
1108     if( pAccObj )
1109         pAccObj->SetRole( (short)Role );
1110 }
1111 
1112 /**
1113    * Judge if a XAccessible object is a container object.
1114    * @param pAccessible XAccessible interface.
1115    * @return If XAccessible object is container.
1116    */
1117 sal_Bool AccObjectWinManager::IsContainer(XAccessible* pAccessible)
1118 {
1119     try
1120     {
1121         if(pAccessible)
1122         {
1123             Reference<XAccessibleContext> xContext(pAccessible->getAccessibleContext(),UNO_QUERY);
1124             if(xContext.is())
1125             {
1126                 switch( xContext->getAccessibleRole() )
1127                 {
1128                 case /*AccessibleRole::*/DIALOG:
1129                 case /*AccessibleRole::*/FRAME:
1130                 case /*AccessibleRole::*/WINDOW:
1131                 case /*AccessibleRole::*/ROOT_PANE:
1132                 case /*AccessibleRole::*/CANVAS:
1133                 case /*AccessibleRole::*/COMBO_BOX:
1134                 case /*AccessibleRole::*/DOCUMENT:
1135                 case /*AccessibleRole::*/EMBEDDED_OBJECT:
1136                 case /*AccessibleRole::*/END_NOTE:
1137                 case /*AccessibleRole::*/FILLER:
1138                 case /*AccessibleRole::*/FOOTNOTE:
1139                 case /*AccessibleRole::*/FOOTER:
1140                 case /*AccessibleRole::*/GRAPHIC:
1141                 case /*AccessibleRole::*/GROUP_BOX:
1142                 case /*AccessibleRole::*/HEADER:
1143                 case /*AccessibleRole::*/LAYERED_PANE:
1144                 case /*AccessibleRole::*/MENU_BAR:
1145                 case /*AccessibleRole::*/POPUP_MENU:
1146                 case /*AccessibleRole::*/OPTION_PANE:
1147                 case /*AccessibleRole::*/PAGE_TAB:
1148                 case /*AccessibleRole::*/PAGE_TAB_LIST:
1149                 case /*AccessibleRole::*/PANEL:
1150                 case /*AccessibleRole::*/SCROLL_PANE:
1151                 case /*AccessibleRole::*/SPLIT_PANE:
1152                 case /*AccessibleRole::*/STATUS_BAR:
1153                 case /*AccessibleRole::*/TABLE_CELL:
1154                 case /*AccessibleRole::*/TEXT_FRAME:
1155                 case /*AccessibleRole::*/TOOL_BAR:
1156                 case /*AccessibleRole::*/VIEW_PORT:
1157                 case /*AccessibleRole::*/SHAPE:
1158                     return sal_True;
1159                     break;
1160                 case /*AccessibleRole::*/COLUMN_HEADER:
1161                 case /*AccessibleRole::*/TABLE:
1162                     if(!IsStateManageDescendant(pAccessible))
1163                         return sal_True;
1164                     break;
1165                 case /*AccessibleRole::*/MENU:
1166                     return sal_True;
1167                     break;
1168                 default:
1169                     return sal_False;
1170                 }
1171             }
1172         }
1173     }
1174     catch(...)
1175     {
1176         return sal_False;
1177     }
1178     return sal_False;
1179 }
1180 
1181 /**
1182    * Judge if a XAccessible object has ManageDescendant event.
1183    * @param pAccessible XAccessible interface.
1184    * @return If XAccessible object is managedescendant.
1185    */
1186 bool AccObjectWinManager::IsStateManageDescendant(XAccessible* pAccessible)
1187 {
1188     if(pAccessible)
1189     {
1190         Reference<XAccessibleContext> xContext(pAccessible->getAccessibleContext(),UNO_QUERY);
1191         if(xContext.is())
1192         {
1193             Reference< XAccessibleStateSet > pRState = xContext->getAccessibleStateSet();
1194             if( !pRState.is() )
1195                 return sal_False;
1196 
1197             Sequence<short> pStates = pRState->getStates();
1198             int count = pStates.getLength();
1199             for( int iIndex = 0;iIndex < count;iIndex++ )
1200             {
1201                 if(pStates[iIndex] == /*AccessibleStateType::*/MANAGES_DESCENDANTS)
1202                     return sal_True;
1203             }
1204         }
1205     }
1206     return sal_False;
1207 }
1208 
1209 /**
1210    * Query and get IAccessible interface by XAccessible interface from list.
1211    * @param pXAcc XAccessible interface.
1212    * @return Com accobject interface.
1213    */
1214 IMAccessible* AccObjectWinManager::GetIMAccByXAcc(XAccessible* pXAcc)
1215 {
1216     AccObject* pAccObj = GetAccObjByXAcc(pXAcc);
1217     if(pAccObj)
1218     {
1219         return pAccObj->GetIMAccessible();
1220     }
1221     else
1222     {
1223         return NULL;
1224     }
1225 }
1226 
1227 /**
1228    * Query and get IAccessible interface by child id from list.
1229    * @param resID, childID.
1230    * @return Com accobject interface.
1231    */
1232 IMAccessible * AccObjectWinManager::GetIAccessibleFromResID(long resID)
1233 {
1234     XResIdToAccObjHash::iterator pIndTemp = XResIdAccList.find( resID );
1235     if ( pIndTemp == XResIdAccList.end() )
1236         return NULL;
1237 
1238     AccObject* pObj = pIndTemp->second;
1239 
1240     if(pObj->GetIMAccessible())
1241         return pObj->GetIMAccessible();
1242     return NULL;
1243 }
1244 /**
1245    * Notify some object will be destroyed.
1246    * @param pXAcc XAccessible interface.
1247    * @return Com accobject interface.
1248    */
1249 void AccObjectWinManager::NotifyDestroy(XAccessible* pXAcc)
1250 {
1251     AccObject* accObj = GetAccObjByXAcc(pXAcc);
1252     if(accObj)
1253     {
1254         accObj->NotifyDestroy(sal_True);
1255     }
1256 }
1257 
1258 
1259 void AccObjectWinManager::UpdateChildState(com::sun::star::accessibility::XAccessible* pAccSubMenu)
1260 {
1261     Reference<com::sun::star::accessibility::XAccessibleContext> xContext(pAccSubMenu,UNO_QUERY);
1262     if (!xContext.is())
1263     {
1264         return;
1265     }
1266     sal_Int32 nCount = xContext->getAccessibleChildCount();
1267     for (sal_Int32 i = 0 ; i < nCount ; ++i)
1268     {
1269         Reference<com::sun::star::accessibility::XAccessible> xChild = xContext->getAccessibleChild(i);
1270         if (xChild.is())
1271         {
1272             AccObject *pObj =  GetAccObjByXAcc(xChild.get());
1273             if (pObj)
1274             {
1275                 pObj->UpdateState();
1276             }
1277         }
1278     }
1279 }
1280 
1281 
1282 bool AccObjectWinManager::IsSpecialToolboItem(com::sun::star::accessibility::XAccessible* pXAcc)
1283 {
1284     if (pXAcc && oldFocus != pXAcc)
1285     {
1286         if(GetParentRole(pXAcc) == TOOL_BAR)
1287         {
1288             Reference< XAccessibleContext > pRContext(pXAcc->getAccessibleContext());
1289             if (pRContext.is())
1290             {
1291                 if(pRContext->getAccessibleRole() == TOGGLE_BUTTON)
1292                 {
1293                     return true;
1294                 }
1295             }
1296         }
1297     }
1298     return false;
1299 }
1300 
1301 short AccObjectWinManager::GetRole(com::sun::star::accessibility::XAccessible* pXAcc)
1302 {
1303     assert(pXAcc != NULL);
1304     Reference<com::sun::star::accessibility::XAccessibleContext> xContext(pXAcc->getAccessibleContext(),UNO_QUERY);
1305     if(xContext.is())
1306     {
1307         return xContext->getAccessibleRole();
1308     }
1309     return -1;
1310 }
1311 
1312 XAccessible* AccObjectWinManager::GetAccDocByHWND( long pWnd )
1313 {
1314     XHWNDToDocumentHash::iterator aIter;
1315     aIter = XHWNDDocList.find( pWnd );
1316     if ( aIter != XHWNDDocList.end() )
1317     {
1318         return aIter->second;
1319     }
1320 
1321     return NULL;
1322 }
1323 
1324 XAccessible* AccObjectWinManager::GetAccDocByAccTopWin( XAccessible* pXAcc )
1325 {
1326     AccObject* pAccObj = GetAccObjByXAcc( pXAcc );
1327     long pWnd = (long)( pAccObj->GetParentHWND() );
1328     return GetAccDocByHWND( pWnd );
1329 }
1330 
1331 bool AccObjectWinManager::IsTopWinAcc( com::sun::star::accessibility::XAccessible* pXAcc )
1332 {
1333     bool bRet = false;
1334     AccObject* pAccObj = GetAccObjByXAcc( pXAcc );
1335     if ( pAccObj )
1336     {
1337         bRet = ( pAccObj->GetParentObj() == NULL );
1338     }
1339     return bRet;
1340 }
1341