1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
22 #include <com/sun/star/accessibility/XAccessibleEventBroadcaster.hpp>
23 #include <com/sun/star/accessibility/XAccessibleEventListener.hpp>
24 #include <com/sun/star/accessibility/XAccessibleComponent.hpp>
25 #include <com/sun/star/accessibility/AccessibleRole.hpp>
26 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
29 #include "AccObjectWinManager.hxx"
30 #include "AccEventListener.hxx"
31 #include "AccComponentEventListener.hxx"
32 #include "AccContainerEventListener.hxx"
33 #include "AccDialogEventListener.hxx"
34 #include "AccWindowEventListener.hxx"
35 #include "AccFrameEventListener.hxx"
36 #include "AccMenuEventListener.hxx"
37 #include "AccObjectContainerEventListener.hxx"
38 #include "AccParagraphEventListener.hxx"
39 #include "AccTextComponentEventListener.hxx"
40 #include "AccListEventListener.hxx"
41 #include "AccTreeEventListener.hxx"
42 #include "AccTableEventListener.hxx"
43 #include "AccObject.hxx"
44 #include "unomsaaevent.hxx"
48 using namespace com::sun::star::accessibility
;
49 using namespace com::sun::star::accessibility::AccessibleRole
;
50 using namespace com::sun::star::accessibility::AccessibleStateType
;
51 using namespace com::sun::star::uno
;
55 * @param Agent The agent kept in all listeners,it's the sole interface by which
56 * listener communicate with windows manager.
57 * pEventAccObj The present event accobject.
58 * oldFocus Last focused object.
59 * isSelectionChanged flag that identifies if there is selection changed.
60 * selectionChildObj Selected object.
61 * dChildID Chile resource ID.
65 AccObjectWinManager::AccObjectWinManager( AccObjectManagerAgent
* Agent
):
72 * Destructor,clear all resource.
76 AccObjectWinManager::~AccObjectWinManager()
80 XResIdAccList
.clear();
90 * Get valid com object interface when notifying some MSAA event
91 * @param pWND The top window handle that contains that event control.
92 * @param wParam Windows system interface.
93 * @return Com interface with event.
97 AccObjectWinManager::Get_ToATInterface(HWND hWnd
, long lParam
, WPARAM wParam
)
99 IMAccessible
* pRetIMAcc
= NULL
;
101 if(lParam
== OBJID_CLIENT
)
103 AccObject
* topWindowAccObj
= GetTopWindowAccObj(hWnd
);
106 pRetIMAcc
= topWindowAccObj
->GetIMAccessible();
108 pRetIMAcc
->AddRef();//increase COM reference count
112 if ( pRetIMAcc
&& lParam
== OBJID_CLIENT
)
114 IAccessible
* pTemp
= dynamic_cast<IAccessible
*>( pRetIMAcc
);
115 LRESULT result
= LresultFromObject(IID_IAccessible
, wParam
, pTemp
);
123 * Search AccObject by XAccessible pointer from our container.
124 * @param pXAcc XAccessible interface.
125 * @return Pointer of accObject that is found.
127 AccObject
* AccObjectWinManager::GetAccObjByXAcc( XAccessible
* pXAcc
)
132 XIdToAccObjHash::iterator pIndTemp
= XIdAccList
.find( (void*)pXAcc
);
133 if ( pIndTemp
== XIdAccList
.end() )
136 return &(pIndTemp
->second
);
140 * get acc object of top window by its handle
141 * @param hWnd, top window handle
142 * @return pointer to AccObject
144 AccObject
* AccObjectWinManager::GetTopWindowAccObj(HWND hWnd
)
146 XHWNDToXAccHash::iterator iterResult
=HwndXAcc
.find(hWnd
);
147 if(iterResult
== HwndXAcc
.end())
149 XAccessible
* pXAcc
= (XAccessible
*)(iterResult
->second
);
150 return GetAccObjByXAcc(pXAcc
);
154 * Simulate MSAA event via XAccessible interface and event type.
155 * @param pXAcc XAccessible interface.
156 * @param state Customize Interface
157 * @return The terminate result that identifies if the call is successful.
159 sal_Bool
AccObjectWinManager::NotifyAccEvent(XAccessible
* pXAcc
,short state
)
161 Reference
< XAccessibleContext
> pRContext
;
167 pRContext
= pXAcc
->getAccessibleContext();
168 if( !pRContext
.is() )
172 AccObject
* selfAccObj
= GetAccObjByXAcc(pXAcc
);
177 long dChildID
= selfAccObj
->GetResID();
178 HWND hAcc
= selfAccObj
->GetParentHWND();
182 case UM_EVENT_STATE_FOCUSED
:
184 UpdateAccFocus(pXAcc
);
186 selfAccObj
->UpdateDefaultAction( );
188 NotifyWinEvent( EVENT_OBJECT_FOCUS
,hAcc
, OBJID_CLIENT
,dChildID
);
191 case UM_EVENT_STATE_BUSY
:
192 NotifyWinEvent( EVENT_OBJECT_STATECHANGE
,hAcc
, OBJID_CLIENT
,dChildID
);
194 case UM_EVENT_STATE_CHECKED
:
195 NotifyWinEvent( EVENT_OBJECT_STATECHANGE
,hAcc
, OBJID_CLIENT
,dChildID
);
197 case UM_EVENT_STATE_PRESSED
:
198 NotifyWinEvent( EVENT_OBJECT_STATECHANGE
,hAcc
, OBJID_CLIENT
,dChildID
);
201 //Removed fire out selected event
202 //case UM_EVENT_STATE_SELECTED:
203 // NotifyWinEvent( EVENT_OBJECT_STATECHANGE,hAcc, OBJID_CLIENT,dChildID );
205 case UM_EVENT_STATE_ARMED
:
206 UpdateAccFocus(pXAcc
);
207 NotifyWinEvent( EVENT_OBJECT_FOCUS
,hAcc
, OBJID_CLIENT
,dChildID
);
209 case UM_EVENT_MENU_START
:
210 NotifyWinEvent( EVENT_SYSTEM_MENUSTART
,hAcc
, OBJID_CLIENT
,dChildID
);
212 case UM_EVENT_MENU_END
:
213 NotifyWinEvent( EVENT_SYSTEM_MENUEND
,hAcc
, OBJID_CLIENT
,dChildID
);
215 case UM_EVENT_MENUPOPUPSTART
:
216 NotifyWinEvent( EVENT_SYSTEM_MENUPOPUPSTART
,hAcc
, OBJID_CLIENT
,dChildID
);
218 case UM_EVENT_MENUPOPUPEND
:
219 NotifyWinEvent( EVENT_SYSTEM_MENUPOPUPEND
,hAcc
, OBJID_CLIENT
,dChildID
);
221 case UM_EVENT_SELECTION_CHANGED
:
222 NotifyWinEvent( EVENT_OBJECT_SELECTION
,hAcc
, OBJID_CLIENT
,dChildID
);
224 case UM_EVENT_SELECTION_CHANGED_ADD
:
225 NotifyWinEvent( EVENT_OBJECT_SELECTIONADD
,hAcc
, OBJID_CLIENT
,dChildID
);
227 case UM_EVENT_SELECTION_CHANGED_REMOVE
:
228 NotifyWinEvent( EVENT_OBJECT_SELECTIONREMOVE
,hAcc
, OBJID_CLIENT
,dChildID
);
230 case UM_EVENT_SELECTION_CHANGED_WITHIN
:
231 NotifyWinEvent( EVENT_OBJECT_SELECTIONWITHIN
,hAcc
, OBJID_CLIENT
,dChildID
);
233 case UM_EVENT_OBJECT_VALUECHANGE
:
235 NotifyWinEvent( EVENT_OBJECT_VALUECHANGE
,hAcc
, OBJID_CLIENT
,dChildID
);
237 case UM_EVENT_OBJECT_NAMECHANGE
:
238 NotifyWinEvent( EVENT_OBJECT_NAMECHANGE
,hAcc
, OBJID_CLIENT
,dChildID
);
240 case UM_EVENT_OBJECT_DESCRIPTIONCHANGE
:
241 NotifyWinEvent( EVENT_OBJECT_DESCRIPTIONCHANGE
,hAcc
, OBJID_CLIENT
,dChildID
);
243 case UM_EVENT_OBJECT_DEFACTIONCHANGE
:
244 NotifyWinEvent( IA2_EVENT_ACTION_CHANGED
,hAcc
, OBJID_CLIENT
,dChildID
);
246 case UM_EVENT_OBJECT_CARETCHANGE
:
247 NotifyWinEvent( IA2_EVENT_TEXT_CARET_MOVED
,hAcc
, OBJID_CLIENT
,dChildID
);
249 case UM_EVENT_OBJECT_TEXTCHANGE
:
250 NotifyWinEvent( IA2_EVENT_TEXT_CHANGED
,hAcc
, OBJID_CLIENT
,dChildID
);
252 case UM_EVENT_ACTIVE_DESCENDANT_CHANGED
:
253 UpdateAccFocus(pXAcc
);
254 NotifyWinEvent( EVENT_OBJECT_FOCUS
,hAcc
, OBJID_CLIENT
,dChildID
);
256 case UM_EVENT_BOUNDRECT_CHANGED
:
257 NotifyWinEvent( EVENT_OBJECT_LOCATIONCHANGE
,hAcc
, OBJID_CLIENT
,dChildID
);
259 case UM_EVENT_VISIBLE_DATA_CHANGED
:
260 NotifyWinEvent( IA2_EVENT_VISIBLE_DATA_CHANGED
,hAcc
, OBJID_CLIENT
,dChildID
);
263 NotifyWinEvent( EVENT_OBJECT_SHOW
,hAcc
, OBJID_CLIENT
,dChildID
);
264 NotifyWinEvent( EVENT_SYSTEM_FOREGROUND
,hAcc
, OBJID_CLIENT
,dChildID
);
266 case UM_EVENT_TABLE_CAPTION_CHANGED
:
267 NotifyWinEvent( IA2_EVENT_TABLE_CAPTION_CHANGED
,hAcc
, OBJID_CLIENT
,dChildID
);
269 case UM_EVENT_TABLE_COLUMN_DESCRIPTION_CHANGED
:
270 NotifyWinEvent( IA2_EVENT_TABLE_COLUMN_DESCRIPTION_CHANGED
,hAcc
, OBJID_CLIENT
,dChildID
);
272 case UM_EVENT_TABLE_COLUMN_HEADER_CHANGED
:
273 NotifyWinEvent( IA2_EVENT_TABLE_COLUMN_HEADER_CHANGED
,hAcc
, OBJID_CLIENT
,dChildID
);
275 case UM_EVENT_TABLE_MODEL_CHANGED
:
276 NotifyWinEvent( IA2_EVENT_TABLE_MODEL_CHANGED
,hAcc
, OBJID_CLIENT
,dChildID
);
278 case UM_EVENT_TABLE_ROW_HEADER_CHANGED
:
279 NotifyWinEvent( IA2_EVENT_TABLE_ROW_HEADER_CHANGED
,hAcc
, OBJID_CLIENT
,dChildID
);
281 case UM_EVENT_TABLE_SUMMARY_CHANGED
:
282 NotifyWinEvent( IA2_EVENT_TABLE_SUMMARY_CHANGED
,hAcc
, OBJID_CLIENT
,dChildID
);
284 case UM_EVENT_TABLE_ROW_DESCRIPTION_CHANGED
:
285 NotifyWinEvent( IA2_EVENT_TABLE_ROW_DESCRIPTION_CHANGED
,hAcc
, OBJID_CLIENT
,dChildID
);
287 case UM_EVENT_OBJECT_REORDER
:
288 NotifyWinEvent( EVENT_OBJECT_REORDER
,hAcc
, OBJID_CLIENT
,dChildID
);
290 case UM_EVENT_PAGE_CHANGED
:
291 NotifyWinEvent( IA2_EVENT_PAGE_CHANGED
,hAcc
, OBJID_CLIENT
,dChildID
);
293 case UM_EVENT_CHILD_REMOVED
:
294 NotifyWinEvent( EVENT_OBJECT_DESTROY
,hAcc
, OBJID_CLIENT
,dChildID
);
296 case UM_EVENT_CHILD_ADDED
:
297 NotifyWinEvent( EVENT_OBJECT_CREATE
,hAcc
, OBJID_CLIENT
,dChildID
);
299 case UM_EVENT_OBJECT_PAGECHANGED
:
300 NotifyWinEvent( IA2_EVENT_PAGE_CHANGED
,hAcc
, OBJID_CLIENT
,dChildID
);
302 case UM_EVENT_TEXT_SELECTION_CHANGED
:
303 NotifyWinEvent( IA2_EVENT_TEXT_SELECTION_CHANGED
,hAcc
, OBJID_CLIENT
,dChildID
);
305 case UM_EVENT_SECTION_CHANGED
:
306 NotifyWinEvent( IA2_EVENT_SECTION_CHANGED
,hAcc
, OBJID_CLIENT
,dChildID
);
308 case UM_EVENT_COLUMN_CHANGED
:
309 NotifyWinEvent( IA2_EVENT_TEXT_COLUMN_CHANGED
,hAcc
, OBJID_CLIENT
,dChildID
);
319 * Get Parent XAccessible interface by XAccessible interface.
320 * @param pXAcc XAccessible interface.
321 * @return Parent XAccessible interface.
323 XAccessible
* AccObjectWinManager::GetParentXAccessible( XAccessible
* pXAcc
)
325 AccObject
* pObj
= GetAccObjByXAcc(pXAcc
);
328 if(pObj
->GetParentObj())
330 pObj
= pObj
->GetParentObj();
331 return pObj
->GetXAccessible().get();
337 * Get Parent role by XAccessible interface.
338 * @param pXAcc XAccessible interface.
339 * @return Parent role.
341 short AccObjectWinManager::GetParentRole( XAccessible
* pXAcc
)
343 AccObject
* pObj
= GetAccObjByXAcc(pXAcc
);
346 if(pObj
->GetParentObj())
348 pObj
= pObj
->GetParentObj();
349 if(pObj
->GetXAccessible().is())
351 XAccessible
* pXAcc
= pObj
->GetXAccessible().get();
352 Reference
< XAccessibleContext
> pRContext
= pXAcc
->getAccessibleContext();
354 return pRContext
->getAccessibleRole();
361 * Update focus objcet by new focused XAccessible interface.
362 * @param newFocus New XAccessible interface that gets focus.
365 void AccObjectWinManager::UpdateAccFocus(XAccessible
* newFocus
)
367 AccObject
* pAccObjNew
= GetAccObjByXAcc(newFocus
);
370 AccObject
* pAccObjOld
= GetAccObjByXAcc(oldFocus
);
372 pAccObjNew
->setFocus();
373 //if old == new, the pAccObjNew will be without focused state
374 if (pAccObjOld
&& pAccObjOld
!= pAccObjNew
)
375 pAccObjOld
->unsetFocus();
380 * Update selected objcet by new focused XAccessible interface.
381 * @param pXAcc XAccessible interface that has selected child changed.
382 * @return Selected children count.
384 int AccObjectWinManager::UpdateAccSelection(XAccessible
* pXAcc
)
386 Reference
< XAccessibleContext
> pRContext
;
391 pRContext
= pXAcc
->getAccessibleContext();
392 if( !pRContext
.is() )
395 Reference
< XAccessibleSelection
> pRSelection(pRContext
,UNO_QUERY
);
396 if( !pRSelection
.is() )
399 AccObject
* pAccObj
= GetAccObjByXAcc(pXAcc
);
403 Reference
<XAccessible
> pRChild
= NULL
;
404 AccObject
* pAccChildObj
= NULL
;
405 int selectNum
= pRSelection
->getSelectedAccessibleChildCount();
407 IAccSelectionList oldSelection
= pAccObj
->GetSelection();
409 if(selectNum
> 4)//for selected.
411 if(selectNum
== 1 && oldSelection
.size() == 0)
414 for (int i
=0;i
<selectNum
;i
++)
416 pRChild
= pRSelection
->getSelectedAccessibleChild(i
);
421 Reference
<XAccessibleContext
> pRChildContext
= pRChild
->getAccessibleContext();
422 if(!pRChildContext
.is())
426 long index
= pRChildContext
->getAccessibleIndexInParent();
427 IAccSelectionList::iterator temp
= oldSelection
.find(index
);
428 if ( temp
!= oldSelection
.end() )
430 oldSelection
.erase(index
);
435 pAccChildObj
= GetAccObjByXAcc(pRChild
.get());
438 InsertAccObj(pRChild
.get(), pXAcc
,pAccObj
->GetParentHWND());
439 pAccChildObj
= GetAccObjByXAcc(pRChild
.get());
442 pAccObj
->AddSelect(index
, pAccChildObj
);
444 if(pAccChildObj
!= NULL
)
445 NotifyWinEvent(EVENT_OBJECT_SELECTIONADD
,pAccObj
->GetParentHWND(), OBJID_CLIENT
,pAccChildObj
->GetResID());
448 IAccSelectionList::iterator iter
= oldSelection
.begin();
449 while(iter
!=oldSelection
.end())
451 pAccObj
->GetSelection().erase(iter
->first
);
452 pAccChildObj
= (AccObject
*)(iter
->second
);
453 if(pAccChildObj
!= NULL
)
454 NotifyWinEvent(EVENT_OBJECT_SELECTIONREMOVE
,pAccObj
->GetParentHWND(), OBJID_CLIENT
,pAccChildObj
->GetResID());
462 * Delete child element from children list.
463 * @param pObj Child element that should be removed from parant child list.
466 void AccObjectWinManager::DeleteAccChildNode( AccObject
* pObj
)
468 AccObject
*parentAccObj
= pObj
->GetParentObj();
470 parentAccObj
->DeleteChild( pObj
);
474 * Delete XAccessible items in top window handle hashtable
475 * @param pXAcc XAccessible interface.
478 void AccObjectWinManager::DeleteFromHwndXAcc(XAccessible
* pXAcc
)
480 XHWNDToXAccHash::iterator iter
= HwndXAcc
.begin();
481 while(iter
!=HwndXAcc
.end())
483 if(iter
->second
== pXAcc
)
485 HwndXAcc
.erase(iter
);
493 * Delete all children with the tree root of XAccessible pointer
494 * @param pXAcc Tree root XAccessible interface.
497 void AccObjectWinManager::DeleteChildrenAccObj(XAccessible
* pXAcc
)
499 AccObject
* currentObj
=NULL
;
500 AccObject
* childObj
=NULL
;
502 currentObj
= GetAccObjByXAcc( pXAcc
);
505 childObj
= currentObj
->NextChild();
508 XAccessible
*const pTmpXAcc
= childObj
->GetXAccessible().get();
511 DeleteChildrenAccObj(pTmpXAcc
);
512 DeleteAccObj(pTmpXAcc
);
514 childObj
= currentObj
->NextChild();
520 * Delete Acc object self.
521 * @param pXAcc The XAccessible interface.
524 void AccObjectWinManager::DeleteAccObj( XAccessible
* pXAcc
)
528 XIdToAccObjHash::iterator temp
= XIdAccList
.find(pXAcc
);
529 if( temp
!= XIdAccList
.end() )
531 ResIdGen
.SetSub( temp
->second
.GetResID() );
538 AccObject
& accObj
= temp
->second
;
539 DeleteAccChildNode( &accObj
);
540 DeleteAccListener( &accObj
);
541 if( accObj
.GetIMAccessible() )
543 accObj
.GetIMAccessible()->Release();
545 size_t i
= XResIdAccList
.erase(accObj
.GetResID());
547 DeleteFromHwndXAcc(pXAcc
);
548 if( accObj
.GetRole() == DOCUMENT
||
549 accObj
.GetRole() == DOCUMENT_PRESENTATION
||
550 accObj
.GetRole() == DOCUMENT_SPREADSHEET
||
551 accObj
.GetRole() == DOCUMENT_TEXT
)
553 XHWNDDocList
.erase(accObj
.GetParentHWND());
555 XIdAccList
.erase(pXAcc
); // note: this invalidates accObj so do it last!
559 * Delete listener that inspects some XAccessible object
560 * @param pAccObj Accobject pointer.
563 void AccObjectWinManager::DeleteAccListener( AccObject
* pAccObj
)
565 AccEventListener
* listener
= pAccObj
->getListener();
568 listener
->RemoveMeFromBroadcaster();
569 pAccObj
->SetListener(NULL
);
573 * Generate a child ID, which is used for AT
575 * @return New resource ID.
577 inline long AccObjectWinManager::ImpleGenerateResID()
579 return ResIdGen
.GenerateNewResID();
583 * Insert all children of the current acc object
584 * @param pXAcc XAccessible interface
585 * @param pWnd Top Window handle
586 * @return The calling result.
588 sal_Bool
AccObjectWinManager::InsertChildrenAccObj( com::sun::star::accessibility::XAccessible
* pXAcc
,
591 if(!IsContainer(pXAcc
))
594 Reference
< XAccessibleContext
> pRContext
;
598 pRContext
= pXAcc
->getAccessibleContext();
599 if( !pRContext
.is() )
602 short role
= pRContext
->getAccessibleRole();
604 if(com::sun::star::accessibility::AccessibleRole::DOCUMENT
== role
||
605 com::sun::star::accessibility::AccessibleRole::DOCUMENT_PRESENTATION
== role
||
606 com::sun::star::accessibility::AccessibleRole::DOCUMENT_SPREADSHEET
== role
||
607 com::sun::star::accessibility::AccessibleRole::DOCUMENT_TEXT
== role
)
609 if(IsStateManageDescendant(pXAcc
))
615 int count
= pRContext
->getAccessibleChildCount();
616 for (int i
=0;i
<count
;i
++)
618 Reference
<XAccessible
> mxAccessible
619 = pRContext
->getAccessibleChild(i
);
620 XAccessible
* mpAccessible
= mxAccessible
.get();
621 if(mpAccessible
!= NULL
)
623 InsertAccObj( mpAccessible
,pXAcc
,pWnd
);
624 InsertChildrenAccObj(mpAccessible
,pWnd
);
632 * Insert child object.
633 * @param pCurObj The child object
634 * @param pParentObj The parant object
635 * @param pWnd Top window handle.
638 void AccObjectWinManager::InsertAccChildNode( AccObject
* pCurObj
, AccObject
* pParentObj
, HWND
/* pWnd */ )
644 pParentObj
->InsertChild(pCurObj
);
648 pCurObj
->UpdateValidWindow();
654 * Insert child object.
655 * @param pCurObj The child object
656 * @param pParentObj The parant object
657 * @param pWnd Top window handle.
660 sal_Bool
AccObjectWinManager::InsertAccObj( XAccessible
* pXAcc
,XAccessible
* pParentXAcc
,HWND pWnd
)
662 XIdToAccObjHash::iterator itXacc
= XIdAccList
.find( (void*)pXAcc
);
663 if (itXacc
!= XIdAccList
.end() )
665 short nCurRole
=GetRole(pXAcc
);
666 if (AccessibleRole::SHAPE
== nCurRole
)
668 AccObject
&objXacc
= itXacc
->second
;
669 AccObject
*pObjParent
= objXacc
.GetParentObj();
671 pObjParent
->GetXAccessible().is() &&
672 pObjParent
->GetXAccessible().get() != pParentXAcc
)
674 XIdToAccObjHash::iterator itXaccParent
= XIdAccList
.find( (void*)pParentXAcc
);
675 if(itXaccParent
!= XIdAccList
.end())
677 objXacc
.SetParentObj(&(itXaccParent
->second
));
685 Reference
< XAccessibleContext
> pRContext
;
690 pRContext
= pXAcc
->getAccessibleContext();
691 if( !pRContext
.is() )
698 AccObject
* pObj
= GetAccObjByXAcc(pParentXAcc
);
700 pWnd
= pObj
->GetParentHWND();
706 AccObject
pObj( pXAcc
,pAgent
);
707 if( pObj
.GetIMAccessible() == NULL
)
709 pObj
.SetResID( this->ImpleGenerateResID());
710 pObj
.SetParentHWND( pWnd
);
712 //for file name support
713 if( pObj
.GetRole() == DOCUMENT
||
714 pObj
.GetRole() == DOCUMENT_PRESENTATION
||
715 pObj
.GetRole() == DOCUMENT_SPREADSHEET
||
716 pObj
.GetRole() == DOCUMENT_TEXT
)
718 XHWNDToDocumentHash::iterator aIter
= XHWNDDocList
.find(pWnd
);
719 if ( aIter
!= XHWNDDocList
.end() )
721 XHWNDDocList
.erase( aIter
);
723 XHWNDDocList
.insert( XHWNDToDocumentHash::value_type(pWnd
, pXAcc
) );
727 ::rtl::Reference
<AccEventListener
> const pListener
=
728 CreateAccEventListener(pXAcc
);
731 Reference
<XAccessibleComponent
> xComponent(pRContext
,UNO_QUERY
);
732 Reference
<XAccessibleEventBroadcaster
> broadcaster(xComponent
,UNO_QUERY
);
733 if (broadcaster
.is())
735 Reference
<XAccessibleEventListener
> const xListener(pListener
.get());
736 broadcaster
->addAccessibleEventListener(xListener
);
741 XIdAccList
.insert( XIdToAccObjHash::value_type( (void*)pXAcc
, pObj
));
742 XIdToAccObjHash::iterator pIndTemp
= XIdAccList
.find( (void*)pXAcc
);
743 XResIdAccList
.insert(XResIdToAccObjHash::value_type(pObj
.GetResID(),&(pIndTemp
->second
)));
745 AccObject
* pCurObj
= GetAccObjByXAcc(pXAcc
);
748 pCurObj
->SetListener(pListener
);
751 AccObject
* pParentObj
= GetAccObjByXAcc(pParentXAcc
);
752 InsertAccChildNode(pCurObj
,pParentObj
,pWnd
);
754 pCurObj
->UpdateAccessibleInfoFromUnoToMSAA();
760 * save the pair <topwindowhandle, XAccessible>
761 * @param hWnd, top window handle
762 * @param pXAcc XAccessible interface for top window
765 void AccObjectWinManager::SaveTopWindowHandle(HWND hWnd
, com::sun::star::accessibility::XAccessible
* pXAcc
)
767 HwndXAcc
.insert( XHWNDToXAccHash::value_type( hWnd
,(void*)pXAcc
) );
771 /** Create the corresponding listener.
772 * @param pXAcc XAccessible interface.
774 ::rtl::Reference
<AccEventListener
>
775 AccObjectWinManager::CreateAccEventListener(XAccessible
* pXAcc
)
777 ::rtl::Reference
<AccEventListener
> pRet
;
778 Reference
<XAccessibleContext
> xContext(pXAcc
->getAccessibleContext(),UNO_QUERY
);
781 switch( xContext
->getAccessibleRole() )
783 case /*AccessibleRole::*/DIALOG
:
784 pRet
= new AccDialogEventListener(pXAcc
,pAgent
);
786 case /*AccessibleRole::*/FRAME
:
787 pRet
= new AccFrameEventListener(pXAcc
,pAgent
);
789 case /*AccessibleRole::*/WINDOW
:
790 pRet
= new AccWindowEventListener(pXAcc
,pAgent
);
792 case /*AccessibleRole::*/ROOT_PANE
:
793 pRet
= new AccFrameEventListener(pXAcc
,pAgent
);
796 case /*AccessibleRole::*/CANVAS
:
797 case /*AccessibleRole::*/COMBO_BOX
:
798 case /*AccessibleRole::*/DOCUMENT
:
799 case /*AccessibleRole::*/DOCUMENT_PRESENTATION
:
800 case /*AccessibleRole::*/DOCUMENT_SPREADSHEET
:
801 case /*AccessibleRole::*/DOCUMENT_TEXT
:
802 case /*AccessibleRole::*/END_NOTE
:
803 case /*AccessibleRole::*/FILLER
:
804 case /*AccessibleRole::*/FOOTNOTE
:
805 case /*AccessibleRole::*/FOOTER
:
806 case /*AccessibleRole::*/HEADER
:
807 case /*AccessibleRole::*/LAYERED_PANE
:
808 case /*AccessibleRole::*/MENU_BAR
:
809 case /*AccessibleRole::*/POPUP_MENU
:
810 case /*AccessibleRole::*/OPTION_PANE
:
811 case /*AccessibleRole::*/PAGE_TAB
:
812 case /*AccessibleRole::*/PAGE_TAB_LIST
:
813 case /*AccessibleRole::*/PANEL
:
814 case /*AccessibleRole::*/SCROLL_PANE
:
815 case /*AccessibleRole::*/SPLIT_PANE
:
816 case /*AccessibleRole::*/STATUS_BAR
:
817 case /*AccessibleRole::*/TABLE_CELL
:
818 case /*AccessibleRole::*/TOOL_BAR
:
819 case /*AccessibleRole::*/VIEW_PORT
:
820 pRet
= new AccContainerEventListener(pXAcc
,pAgent
);
822 case /*AccessibleRole::*/PARAGRAPH
:
823 case /*AccessibleRole::*/HEADING
:
824 pRet
= new AccParagraphEventListener(pXAcc
,pAgent
);
827 case /*AccessibleRole::*/CHECK_BOX
:
828 case /*AccessibleRole::*/ICON
:
829 case /*AccessibleRole::*/LABEL
:
830 case /*AccessibleRole::*/MENU_ITEM
:
831 case /*AccessibleRole::*/CHECK_MENU_ITEM
:
832 case /*AccessibleRole::*/RADIO_MENU_ITEM
:
833 case /*AccessibleRole::*/PUSH_BUTTON
:
834 case /*AccessibleRole::*/RADIO_BUTTON
:
835 case /*AccessibleRole::*/SCROLL_BAR
:
836 case /*AccessibleRole::*/SEPARATOR
:
837 case /*AccessibleRole::*/TOGGLE_BUTTON
:
838 case /*AccessibleRole::*/BUTTON_DROPDOWN
:
839 case /*AccessibleRole::*/TOOL_TIP
:
840 case /*AccessibleRole::*/SPIN_BOX
:
842 pRet
= new AccComponentEventListener(pXAcc
,pAgent
);
845 case /*AccessibleRole::*/TEXT
:
846 pRet
= new AccTextComponentEventListener(pXAcc
,pAgent
);
849 case /*AccessibleRole::*/MENU
:
850 pRet
= new AccMenuEventListener(pXAcc
,pAgent
);
853 case /*AccessibleRole::*/SHAPE
:
855 case /*AccessibleRole::*/EMBEDDED_OBJECT
:
856 case /*AccessibleRole::*/GRAPHIC
:
857 case /*AccessibleRole::*/TEXT_FRAME
:
858 pRet
= new AccObjectContainerEventListener(pXAcc
,pAgent
);
861 case /*AccessibleRole::*/LIST
:
862 pRet
= new AccListEventListener(pXAcc
,pAgent
);
864 case /*AccessibleRole::*/TREE
:
865 pRet
= new AccTreeEventListener(pXAcc
,pAgent
);
868 case /*AccessibleRole::*/COLUMN_HEADER
:
869 case /*AccessibleRole::*/TABLE
:
870 pRet
= new AccTableEventListener(pXAcc
,pAgent
);
873 pRet
= new AccContainerEventListener(pXAcc
,pAgent
);
881 * state is a combination integer, each bit of which represents a single state,
882 * such as focused,1 for the state on,0 for the state off. Here call COM interface
883 * to modify the state value, including DecreaseState.
884 * @param pXAcc XAccessible interface.
885 * @param pState Changed state.
888 void AccObjectWinManager::DecreaseState( XAccessible
* pXAcc
,unsigned short pState
)
890 AccObject
* pAccObj
= GetAccObjByXAcc( pXAcc
);
892 pAccObj
->DecreaseState( pState
);
896 * state is a combination integer, each bit of which represents a single state,such as focused,1 for
897 * the state on,0 for the state off. Here call COM interface to modify the state value, including
899 * @param pXAcc XAccessible interface.
900 * @param pState Changed state.
903 void AccObjectWinManager::IncreaseState( XAccessible
* pXAcc
,unsigned short pState
)
905 AccObject
* pAccObj
= GetAccObjByXAcc( pXAcc
);
907 pAccObj
->IncreaseState( pState
);
910 void AccObjectWinManager::UpdateState( com::sun::star::accessibility::XAccessible
* pXAcc
)
912 AccObject
* pAccObj
= GetAccObjByXAcc( pXAcc
);
914 pAccObj
->UpdateState( );
918 * Set corresponding com object's accessible name via XAccessilbe interface and new
920 * @param pXAcc XAccessible interface.
923 void AccObjectWinManager::UpdateAccName( XAccessible
* pXAcc
)
925 AccObject
* pAccObj
= GetAccObjByXAcc( pXAcc
);
927 pAccObj
->UpdateName();
930 void AccObjectWinManager::UpdateAction( XAccessible
* pXAcc
)
932 AccObject
* pAccObj
= GetAccObjByXAcc( pXAcc
);
934 pAccObj
->UpdateAction();
937 void AccObjectWinManager::UpdateDescription( XAccessible
* pXAcc
)
939 AccObject
* pAccObj
= GetAccObjByXAcc( pXAcc
);
941 pAccObj
->UpdateDescription();
945 * Set corresponding com object's accessible location via XAccessilbe interface and new
947 * @param pXAcc XAccessible interface.
950 void AccObjectWinManager::SetLocation( XAccessible
* pXAcc
, long /*top*/, long /*left*/, long /*width*/, long /*height*/ )
952 AccObject
* pObj
= GetAccObjByXAcc( pXAcc
);
953 //get the location from XComponent.
954 Reference
< XAccessibleContext
> pRContext
= pXAcc
->getAccessibleContext();
956 pObj
->UpdateLocation();
960 * Set corresponding com object's value via XAccessilbe interface and new value.
961 * @param pXAcc XAccessible interface.
962 * @param pAny new value.
965 void AccObjectWinManager::SetValue( XAccessible
* pXAcc
, Any pAny
)
967 AccObject
* pAccObj
= GetAccObjByXAcc( pXAcc
);
969 pAccObj
->SetValue( pAny
);
973 * Set corresponding com object's value via XAccessilbe interface.
974 * @param pXAcc XAccessible interface.
977 void AccObjectWinManager::UpdateValue( XAccessible
* pXAcc
)
979 AccObject
* pAccObj
= GetAccObjByXAcc( pXAcc
);
981 pAccObj
->UpdateValue();
985 * Set corresponding com object's name via XAccessilbe interface and new name.
986 * @param pXAcc XAccessible interface.
987 * @param newName new name
990 void AccObjectWinManager::SetAccName( XAccessible
* pXAcc
, Any newName
)
992 AccObject
* pAccObj
= GetAccObjByXAcc( pXAcc
);
994 pAccObj
->SetName( newName
);
998 * Set corresponding com object's description via XAccessilbe interface and new description.
999 * @param pXAcc XAccessible interface.
1000 * @param newDesc new description
1003 void AccObjectWinManager::SetDescription( XAccessible
* pXAcc
, Any newDesc
)
1005 AccObject
* pAccObj
= GetAccObjByXAcc( pXAcc
);
1007 pAccObj
->SetDescription( newDesc
);
1011 * Set corresponding com object's role via XAccessilbe interface and new role.
1012 * @param pXAcc XAccessible interface.
1013 * @param Role new role
1016 void AccObjectWinManager::SetRole( XAccessible
* pXAcc
, long Role
)
1018 AccObject
* pAccObj
= GetAccObjByXAcc( pXAcc
);
1020 pAccObj
->SetRole( (short)Role
);
1024 * Judge if a XAccessible object is a container object.
1025 * @param pAccessible XAccessible interface.
1026 * @return If XAccessible object is container.
1028 sal_Bool
AccObjectWinManager::IsContainer(XAccessible
* pAccessible
)
1034 Reference
<XAccessibleContext
> xContext(pAccessible
->getAccessibleContext(),UNO_QUERY
);
1037 switch( xContext
->getAccessibleRole() )
1039 case /*AccessibleRole::*/DIALOG
:
1040 case /*AccessibleRole::*/FRAME
:
1041 case /*AccessibleRole::*/WINDOW
:
1042 case /*AccessibleRole::*/ROOT_PANE
:
1043 case /*AccessibleRole::*/CANVAS
:
1044 case /*AccessibleRole::*/COMBO_BOX
:
1045 case /*AccessibleRole::*/DOCUMENT
:
1046 case /*AccessibleRole::*/DOCUMENT_PRESENTATION
:
1047 case /*AccessibleRole::*/DOCUMENT_SPREADSHEET
:
1048 case /*AccessibleRole::*/DOCUMENT_TEXT
:
1049 case /*AccessibleRole::*/EMBEDDED_OBJECT
:
1050 case /*AccessibleRole::*/END_NOTE
:
1051 case /*AccessibleRole::*/FILLER
:
1052 case /*AccessibleRole::*/FOOTNOTE
:
1053 case /*AccessibleRole::*/FOOTER
:
1054 case /*AccessibleRole::*/GRAPHIC
:
1055 case /*AccessibleRole::*/GROUP_BOX
:
1056 case /*AccessibleRole::*/HEADER
:
1057 case /*AccessibleRole::*/LAYERED_PANE
:
1058 case /*AccessibleRole::*/MENU_BAR
:
1059 case /*AccessibleRole::*/POPUP_MENU
:
1060 case /*AccessibleRole::*/OPTION_PANE
:
1061 case /*AccessibleRole::*/PAGE_TAB
:
1062 case /*AccessibleRole::*/PAGE_TAB_LIST
:
1063 case /*AccessibleRole::*/PANEL
:
1064 case /*AccessibleRole::*/SCROLL_PANE
:
1065 case /*AccessibleRole::*/SPLIT_PANE
:
1066 case /*AccessibleRole::*/STATUS_BAR
:
1067 case /*AccessibleRole::*/TABLE_CELL
:
1068 case /*AccessibleRole::*/TEXT_FRAME
:
1069 case /*AccessibleRole::*/TOOL_BAR
:
1070 case /*AccessibleRole::*/VIEW_PORT
:
1071 case /*AccessibleRole::*/SHAPE
:
1074 case /*AccessibleRole::*/COLUMN_HEADER
:
1075 case /*AccessibleRole::*/TABLE
:
1076 if(!IsStateManageDescendant(pAccessible
))
1079 case /*AccessibleRole::*/MENU
:
1096 * Judge if a XAccessible object has ManageDescendant event.
1097 * @param pAccessible XAccessible interface.
1098 * @return If XAccessible object is managedescendant.
1100 bool AccObjectWinManager::IsStateManageDescendant(XAccessible
* pAccessible
)
1104 Reference
<XAccessibleContext
> xContext(pAccessible
->getAccessibleContext(),UNO_QUERY
);
1107 Reference
< XAccessibleStateSet
> pRState
= xContext
->getAccessibleStateSet();
1111 Sequence
<short> pStates
= pRState
->getStates();
1112 int count
= pStates
.getLength();
1113 for( int iIndex
= 0;iIndex
< count
;iIndex
++ )
1115 if(pStates
[iIndex
] == /*AccessibleStateType::*/MANAGES_DESCENDANTS
)
1124 * Query and get IAccessible interface by XAccessible interface from list.
1125 * @param pXAcc XAccessible interface.
1126 * @return Com accobject interface.
1128 IMAccessible
* AccObjectWinManager::GetIMAccByXAcc(XAccessible
* pXAcc
)
1130 AccObject
* pAccObj
= GetAccObjByXAcc(pXAcc
);
1133 return pAccObj
->GetIMAccessible();
1142 * Query and get IAccessible interface by child id from list.
1143 * @param resID, childID.
1144 * @return Com accobject interface.
1146 IMAccessible
* AccObjectWinManager::GetIAccessibleFromResID(long resID
)
1148 XResIdToAccObjHash::iterator pIndTemp
= XResIdAccList
.find( resID
);
1149 if ( pIndTemp
== XResIdAccList
.end() )
1152 AccObject
* pObj
= pIndTemp
->second
;
1154 if(pObj
->GetIMAccessible())
1155 return pObj
->GetIMAccessible();
1159 * Notify some object will be destroyed.
1160 * @param pXAcc XAccessible interface.
1161 * @return Com accobject interface.
1163 void AccObjectWinManager::NotifyDestroy(XAccessible
* pXAcc
)
1165 AccObject
* accObj
= GetAccObjByXAcc(pXAcc
);
1168 accObj
->NotifyDestroy(sal_True
);
1173 void AccObjectWinManager::UpdateChildState(com::sun::star::accessibility::XAccessible
* pAccSubMenu
)
1175 Reference
<com::sun::star::accessibility::XAccessibleContext
> xContext(pAccSubMenu
,UNO_QUERY
);
1180 sal_Int32 nCount
= xContext
->getAccessibleChildCount();
1181 for (sal_Int32 i
= 0 ; i
< nCount
; ++i
)
1183 Reference
<com::sun::star::accessibility::XAccessible
> xChild
= xContext
->getAccessibleChild(i
);
1186 AccObject
*pObj
= GetAccObjByXAcc(xChild
.get());
1189 pObj
->UpdateState();
1196 bool AccObjectWinManager::IsSpecialToolboItem(com::sun::star::accessibility::XAccessible
* pXAcc
)
1198 if (pXAcc
&& oldFocus
!= pXAcc
)
1200 if(GetParentRole(pXAcc
) == TOOL_BAR
)
1202 Reference
< XAccessibleContext
> pRContext(pXAcc
->getAccessibleContext());
1205 if(pRContext
->getAccessibleRole() == TOGGLE_BUTTON
)
1215 short AccObjectWinManager::GetRole(com::sun::star::accessibility::XAccessible
* pXAcc
)
1217 assert(pXAcc
!= NULL
);
1218 Reference
<com::sun::star::accessibility::XAccessibleContext
> xContext(pXAcc
->getAccessibleContext(),UNO_QUERY
);
1221 return xContext
->getAccessibleRole();
1226 XAccessible
* AccObjectWinManager::GetAccDocByHWND(HWND pWnd
)
1228 XHWNDToDocumentHash::iterator aIter
;
1229 aIter
= XHWNDDocList
.find( pWnd
);
1230 if ( aIter
!= XHWNDDocList
.end() )
1232 return aIter
->second
;
1238 XAccessible
* AccObjectWinManager::GetAccDocByAccTopWin( XAccessible
* pXAcc
)
1240 AccObject
* pAccObj
= GetAccObjByXAcc( pXAcc
);
1241 HWND hWnd
= pAccObj
->GetParentHWND();
1242 return GetAccDocByHWND(hWnd
);
1245 bool AccObjectWinManager::IsTopWinAcc( com::sun::star::accessibility::XAccessible
* pXAcc
)
1248 AccObject
* pAccObj
= GetAccObjByXAcc( pXAcc
);
1251 bRet
= ( pAccObj
->GetParentObj() == NULL
);
1255 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */