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/XAccessible.hpp>
23 #include <com/sun/star/accessibility/XAccessibleEventBroadcaster.hpp>
24 #include <com/sun/star/accessibility/XAccessibleEventListener.hpp>
25 #include <com/sun/star/accessibility/XAccessibleComponent.hpp>
26 #include <com/sun/star/accessibility/AccessibleRole.hpp>
27 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
30 #include <AccObjectWinManager.hxx>
31 #include <AccEventListener.hxx>
32 #include <AccComponentEventListener.hxx>
33 #include <AccContainerEventListener.hxx>
34 #include <AccDialogEventListener.hxx>
35 #include <AccWindowEventListener.hxx>
36 #include <AccFrameEventListener.hxx>
37 #include <AccMenuEventListener.hxx>
38 #include <AccObjectContainerEventListener.hxx>
39 #include <AccParagraphEventListener.hxx>
40 #include <AccTextComponentEventListener.hxx>
41 #include <AccListEventListener.hxx>
42 #include <AccTreeEventListener.hxx>
43 #include <AccTableEventListener.hxx>
44 #include <AccObject.hxx>
45 #include <unomsaaevent.hxx>
48 using namespace com::sun::star::accessibility
;
49 using namespace com::sun::star::uno
;
53 * @param Agent The agent kept in all listeners,it's the sole interface by which
54 * listener communicate with windows manager.
55 * pEventAccObj The present event accobject.
56 * oldFocus Last focused object.
57 * isSelectionChanged flag that identifies if there is selection changed.
58 * selectionChildObj Selected object.
59 * dChildID Chile resource ID.
63 AccObjectWinManager::AccObjectWinManager( AccObjectManagerAgent
* Agent
):
70 * Destructor,clear all resource.
74 AccObjectWinManager::~AccObjectWinManager()
77 std::scoped_lock
l(m_Mutex
);
82 XResIdAccList
.clear();
88 * Get valid com object interface when notifying some MSAA event
89 * @param pWND The top window handle that contains that event control.
90 * @param wParam Windows system interface.
91 * @return Com interface with event.
95 AccObjectWinManager::Get_ToATInterface(HWND hWnd
, long lParam
, WPARAM wParam
)
97 IMAccessible
* pRetIMAcc
= nullptr;
99 if(lParam
== OBJID_CLIENT
)
101 pRetIMAcc
= GetTopWindowIMAccessible(hWnd
);
104 if ( pRetIMAcc
&& lParam
== OBJID_CLIENT
)
106 LRESULT result
= LresultFromObject(IID_IAccessible
, wParam
, pRetIMAcc
);
107 pRetIMAcc
->Release();
114 * Search AccObject by XAccessible pointer from our container.
115 * @param pXAcc XAccessible interface.
116 * @return Pointer of accObject that is found.
118 AccObject
* AccObjectWinManager::GetAccObjByXAcc( XAccessible
* pXAcc
)
120 if( pXAcc
== nullptr)
123 std::scoped_lock
l(m_Mutex
);
125 XIdToAccObjHash::iterator pIndTemp
= XIdAccList
.find( pXAcc
);
126 if ( pIndTemp
== XIdAccList
.end() )
129 return &(pIndTemp
->second
);
133 * get acc object of top window by its handle
134 * @param hWnd, top window handle
135 * @return pointer to AccObject
137 IMAccessible
* AccObjectWinManager::GetTopWindowIMAccessible(HWND hWnd
)
139 std::scoped_lock
l(m_Mutex
); // tdf#155794 for HwndXAcc and XIdAccList
141 XHWNDToXAccHash::iterator iterResult
=HwndXAcc
.find(hWnd
);
142 if(iterResult
== HwndXAcc
.end())
144 XAccessible
* pXAcc
= iterResult
->second
;
145 AccObject
*const pAccObject(GetAccObjByXAcc(pXAcc
));
150 IMAccessible
*const pRet(pAccObject
->GetIMAccessible());
160 * Simulate MSAA event via XAccessible interface and event type.
161 * @param pXAcc XAccessible interface.
162 * @param eEvent event type
163 * @return The terminate result that identifies if the call is successful.
165 bool AccObjectWinManager::NotifyAccEvent(XAccessible
* pXAcc
, UnoMSAAEvent eEvent
)
167 Reference
< XAccessibleContext
> pRContext
;
169 if( pXAcc
== nullptr)
173 pRContext
= pXAcc
->getAccessibleContext();
174 if( !pRContext
.is() )
178 AccObject
* selfAccObj
= GetAccObjByXAcc(pXAcc
);
180 if(selfAccObj
==nullptr)
183 long dChildID
= selfAccObj
->GetResID();
184 HWND hAcc
= selfAccObj
->GetParentHWND();
188 case UnoMSAAEvent::STATE_FOCUSED
:
190 UpdateAccFocus(pXAcc
);
191 selfAccObj
->UpdateDefaultAction( );
193 NotifyWinEvent( EVENT_OBJECT_FOCUS
,hAcc
, OBJID_CLIENT
,dChildID
);
196 case UnoMSAAEvent::STATE_BUSY
:
197 NotifyWinEvent( EVENT_OBJECT_STATECHANGE
,hAcc
, OBJID_CLIENT
,dChildID
);
199 case UnoMSAAEvent::STATE_CHECKED
:
200 NotifyWinEvent( EVENT_OBJECT_STATECHANGE
,hAcc
, OBJID_CLIENT
,dChildID
);
202 case UnoMSAAEvent::STATE_PRESSED
:
203 NotifyWinEvent( EVENT_OBJECT_STATECHANGE
,hAcc
, OBJID_CLIENT
,dChildID
);
206 //Removed fire out selected event
207 //case UnoMSAAEvent::STATE_SELECTED:
208 // NotifyWinEvent( EVENT_OBJECT_STATECHANGE,hAcc, OBJID_CLIENT,dChildID );
210 case UnoMSAAEvent::STATE_ARMED
:
211 UpdateAccFocus(pXAcc
);
212 NotifyWinEvent( EVENT_OBJECT_FOCUS
,hAcc
, OBJID_CLIENT
,dChildID
);
214 case UnoMSAAEvent::STATE_SHOWING
:
215 // send EVENT_SYSTEM_ALERT when notification gets shown
216 if (pRContext
->getAccessibleRole() == AccessibleRole::NOTIFICATION
)
217 NotifyWinEvent(EVENT_SYSTEM_ALERT
, hAcc
, OBJID_CLIENT
, dChildID
);
219 case UnoMSAAEvent::MENU_START
:
220 NotifyWinEvent( EVENT_SYSTEM_MENUSTART
,hAcc
, OBJID_CLIENT
,dChildID
);
222 case UnoMSAAEvent::MENU_END
:
223 NotifyWinEvent( EVENT_SYSTEM_MENUEND
,hAcc
, OBJID_CLIENT
,dChildID
);
225 case UnoMSAAEvent::MENUPOPUPSTART
:
226 NotifyWinEvent( EVENT_SYSTEM_MENUPOPUPSTART
,hAcc
, OBJID_CLIENT
,dChildID
);
228 case UnoMSAAEvent::MENUPOPUPEND
:
229 NotifyWinEvent( EVENT_SYSTEM_MENUPOPUPEND
,hAcc
, OBJID_CLIENT
,dChildID
);
231 case UnoMSAAEvent::SELECTION_CHANGED
:
232 NotifyWinEvent( EVENT_OBJECT_SELECTION
,hAcc
, OBJID_CLIENT
,dChildID
);
234 case UnoMSAAEvent::SELECTION_CHANGED_ADD
:
235 NotifyWinEvent( EVENT_OBJECT_SELECTIONADD
,hAcc
, OBJID_CLIENT
,dChildID
);
237 case UnoMSAAEvent::SELECTION_CHANGED_REMOVE
:
238 NotifyWinEvent( EVENT_OBJECT_SELECTIONREMOVE
,hAcc
, OBJID_CLIENT
,dChildID
);
240 case UnoMSAAEvent::SELECTION_CHANGED_WITHIN
:
241 NotifyWinEvent( EVENT_OBJECT_SELECTIONWITHIN
,hAcc
, OBJID_CLIENT
,dChildID
);
243 case UnoMSAAEvent::OBJECT_VALUECHANGE
:
245 NotifyWinEvent( EVENT_OBJECT_VALUECHANGE
,hAcc
, OBJID_CLIENT
,dChildID
);
247 case UnoMSAAEvent::OBJECT_NAMECHANGE
:
248 NotifyWinEvent( EVENT_OBJECT_NAMECHANGE
,hAcc
, OBJID_CLIENT
,dChildID
);
250 case UnoMSAAEvent::OBJECT_DESCRIPTIONCHANGE
:
251 NotifyWinEvent( EVENT_OBJECT_DESCRIPTIONCHANGE
,hAcc
, OBJID_CLIENT
,dChildID
);
253 case UnoMSAAEvent::OBJECT_DEFACTIONCHANGE
:
254 NotifyWinEvent( IA2_EVENT_ACTION_CHANGED
,hAcc
, OBJID_CLIENT
,dChildID
);
256 case UnoMSAAEvent::OBJECT_CARETCHANGE
:
257 NotifyWinEvent( IA2_EVENT_TEXT_CARET_MOVED
,hAcc
, OBJID_CLIENT
,dChildID
);
259 case UnoMSAAEvent::OBJECT_TEXTCHANGE
:
260 NotifyWinEvent( IA2_EVENT_TEXT_CHANGED
,hAcc
, OBJID_CLIENT
,dChildID
);
262 case UnoMSAAEvent::ACTIVE_DESCENDANT_CHANGED
:
263 UpdateAccFocus(pXAcc
);
264 NotifyWinEvent( EVENT_OBJECT_FOCUS
,hAcc
, OBJID_CLIENT
,dChildID
);
266 case UnoMSAAEvent::BOUNDRECT_CHANGED
:
267 NotifyWinEvent( EVENT_OBJECT_LOCATIONCHANGE
,hAcc
, OBJID_CLIENT
,dChildID
);
269 case UnoMSAAEvent::VISIBLE_DATA_CHANGED
:
270 NotifyWinEvent( IA2_EVENT_VISIBLE_DATA_CHANGED
,hAcc
, OBJID_CLIENT
,dChildID
);
272 case UnoMSAAEvent::SHOW
:
273 NotifyWinEvent( EVENT_OBJECT_SHOW
,hAcc
, OBJID_CLIENT
,dChildID
);
274 NotifyWinEvent( EVENT_SYSTEM_FOREGROUND
,hAcc
, OBJID_CLIENT
,dChildID
);
276 case UnoMSAAEvent::TABLE_CAPTION_CHANGED
:
277 NotifyWinEvent( IA2_EVENT_TABLE_CAPTION_CHANGED
,hAcc
, OBJID_CLIENT
,dChildID
);
279 case UnoMSAAEvent::TABLE_COLUMN_DESCRIPTION_CHANGED
:
280 NotifyWinEvent( IA2_EVENT_TABLE_COLUMN_DESCRIPTION_CHANGED
,hAcc
, OBJID_CLIENT
,dChildID
);
282 case UnoMSAAEvent::TABLE_COLUMN_HEADER_CHANGED
:
283 NotifyWinEvent( IA2_EVENT_TABLE_COLUMN_HEADER_CHANGED
,hAcc
, OBJID_CLIENT
,dChildID
);
285 case UnoMSAAEvent::TABLE_MODEL_CHANGED
:
286 NotifyWinEvent( IA2_EVENT_TABLE_MODEL_CHANGED
,hAcc
, OBJID_CLIENT
,dChildID
);
288 case UnoMSAAEvent::TABLE_ROW_HEADER_CHANGED
:
289 NotifyWinEvent( IA2_EVENT_TABLE_ROW_HEADER_CHANGED
,hAcc
, OBJID_CLIENT
,dChildID
);
291 case UnoMSAAEvent::TABLE_SUMMARY_CHANGED
:
292 NotifyWinEvent( IA2_EVENT_TABLE_SUMMARY_CHANGED
,hAcc
, OBJID_CLIENT
,dChildID
);
294 case UnoMSAAEvent::TABLE_ROW_DESCRIPTION_CHANGED
:
295 NotifyWinEvent( IA2_EVENT_TABLE_ROW_DESCRIPTION_CHANGED
,hAcc
, OBJID_CLIENT
,dChildID
);
297 case UnoMSAAEvent::OBJECT_REORDER
:
298 NotifyWinEvent( EVENT_OBJECT_REORDER
,hAcc
, OBJID_CLIENT
,dChildID
);
300 case UnoMSAAEvent::PAGE_CHANGED
:
301 NotifyWinEvent( IA2_EVENT_PAGE_CHANGED
,hAcc
, OBJID_CLIENT
,dChildID
);
303 case UnoMSAAEvent::CHILD_REMOVED
:
304 NotifyWinEvent( EVENT_OBJECT_DESTROY
,hAcc
, OBJID_CLIENT
,dChildID
);
306 case UnoMSAAEvent::CHILD_ADDED
:
307 NotifyWinEvent( EVENT_OBJECT_CREATE
,hAcc
, OBJID_CLIENT
,dChildID
);
309 case UnoMSAAEvent::OBJECT_PAGECHANGED
:
310 NotifyWinEvent( IA2_EVENT_PAGE_CHANGED
,hAcc
, OBJID_CLIENT
,dChildID
);
312 case UnoMSAAEvent::TEXT_SELECTION_CHANGED
:
313 NotifyWinEvent( IA2_EVENT_TEXT_SELECTION_CHANGED
,hAcc
, OBJID_CLIENT
,dChildID
);
315 case UnoMSAAEvent::SECTION_CHANGED
:
316 NotifyWinEvent( IA2_EVENT_SECTION_CHANGED
,hAcc
, OBJID_CLIENT
,dChildID
);
318 case UnoMSAAEvent::COLUMN_CHANGED
:
319 NotifyWinEvent( IA2_EVENT_TEXT_COLUMN_CHANGED
,hAcc
, OBJID_CLIENT
,dChildID
);
329 * Get Parent XAccessible interface by XAccessible interface.
330 * @param pXAcc XAccessible interface.
331 * @return Parent XAccessible interface.
333 XAccessible
* AccObjectWinManager::GetParentXAccessible( XAccessible
* pXAcc
)
335 AccObject
* pObj
= GetAccObjByXAcc(pXAcc
);
338 if(pObj
->GetParentObj())
340 pObj
= pObj
->GetParentObj();
341 return pObj
->GetXAccessible().get();
347 * Get Parent role by XAccessible interface.
348 * @param pXAcc XAccessible interface.
349 * @return Parent role.
351 short AccObjectWinManager::GetParentRole( XAccessible
* pXAcc
)
353 AccObject
* pObj
= GetAccObjByXAcc(pXAcc
);
356 if(pObj
->GetParentObj())
358 pObj
= pObj
->GetParentObj();
359 if(pObj
->GetXAccessible().is())
361 Reference
< XAccessibleContext
> pRContext
= pObj
->GetXAccessible()->getAccessibleContext();
363 return pRContext
->getAccessibleRole();
370 * Update focus object by new focused XAccessible interface.
371 * @param newFocus New XAccessible interface that gets focus.
374 void AccObjectWinManager::UpdateAccFocus(XAccessible
* newFocus
)
376 AccObject
* pAccObjNew
= GetAccObjByXAcc(newFocus
);
379 AccObject
* pAccObjOld
= GetAccObjByXAcc(oldFocus
);
381 pAccObjNew
->setFocus();
382 //if old == new, the pAccObjNew will be without focused state
383 if (pAccObjOld
&& pAccObjOld
!= pAccObjNew
)
384 pAccObjOld
->unsetFocus();
389 * Delete child element from children list.
390 * @param pObj Child element that should be removed from parent child list.
393 void AccObjectWinManager::DeleteAccChildNode( AccObject
* pObj
)
395 AccObject
*parentAccObj
= pObj
->GetParentObj();
397 parentAccObj
->DeleteChild( pObj
);
401 * Delete XAccessible items in top window handle hashtable
402 * @param pXAcc XAccessible interface.
405 void AccObjectWinManager::DeleteFromHwndXAcc(XAccessible
const * pXAcc
)
407 std::scoped_lock
l(m_Mutex
);
409 auto iter
= std::find_if(HwndXAcc
.begin(), HwndXAcc
.end(),
410 [&pXAcc
](XHWNDToXAccHash::value_type
& rEntry
) { return rEntry
.second
== pXAcc
; });
411 if (iter
!= HwndXAcc
.end())
412 HwndXAcc
.erase(iter
);
416 * Delete all children with the tree root of XAccessible pointer
417 * @param pXAcc Tree root XAccessible interface.
420 void AccObjectWinManager::DeleteChildrenAccObj(XAccessible
* pXAcc
)
422 AccObject
* currentObj
=nullptr;
423 AccObject
* childObj
=nullptr;
425 currentObj
= GetAccObjByXAcc( pXAcc
);
428 childObj
= currentObj
->NextChild();
431 XAccessible
*const pTmpXAcc
= childObj
->GetXAccessible().get();
434 DeleteChildrenAccObj(pTmpXAcc
);
435 DeleteAccObj(pTmpXAcc
);
437 childObj
= currentObj
->NextChild();
443 * Delete Acc object self.
444 * @param pXAcc The XAccessible interface.
447 void AccObjectWinManager::DeleteAccObj( XAccessible
* pXAcc
)
449 if( pXAcc
== nullptr )
452 rtl::Reference
<AccEventListener
> pListener
;
455 std::scoped_lock
l(m_Mutex
);
457 XIdToAccObjHash::iterator temp
= XIdAccList
.find(pXAcc
);
458 if( temp
!= XIdAccList
.end() )
460 ResIdGen
.SetSub( temp
->second
.GetResID() );
467 AccObject
& accObj
= temp
->second
;
468 DeleteAccChildNode( &accObj
);
469 pListener
= DeleteAccListener(&accObj
);
470 accObj
.NotifyDestroy();
471 if( accObj
.GetIMAccessible() )
473 accObj
.GetIMAccessible()->Release();
475 size_t i
= XResIdAccList
.erase(accObj
.GetResID());
478 DeleteFromHwndXAcc(pXAcc
);
479 if (accObj
.GetRole() == AccessibleRole::DOCUMENT
||
480 accObj
.GetRole() == AccessibleRole::DOCUMENT_PRESENTATION
||
481 accObj
.GetRole() == AccessibleRole::DOCUMENT_SPREADSHEET
||
482 accObj
.GetRole() == AccessibleRole::DOCUMENT_TEXT
)
484 XHWNDDocList
.erase(accObj
.GetParentHWND());
486 XIdAccList
.erase(pXAcc
); // note: this invalidates accObj so do it last!
490 pListener
->RemoveMeFromBroadcaster(false);
495 * Delete listener that inspects some XAccessible object
496 * @param pAccObj Accobject pointer.
499 rtl::Reference
<AccEventListener
> AccObjectWinManager::DeleteAccListener( AccObject
* pAccObj
)
501 return pAccObj
->SetListener(nullptr);
505 * Generate a child ID, which is used for AT
507 * @return New resource ID.
509 inline long AccObjectWinManager::ImpleGenerateResID()
511 return ResIdGen
.GenerateNewResID();
515 * Insert all children of the current acc object
516 * @param pXAcc XAccessible interface
517 * @param pWnd Top Window handle
518 * @return The calling result.
520 bool AccObjectWinManager::InsertChildrenAccObj( css::accessibility::XAccessible
* pXAcc
,
523 if(!IsContainer(pXAcc
))
526 Reference
< XAccessibleContext
> pRContext
;
528 if( pXAcc
== nullptr)
530 pRContext
= pXAcc
->getAccessibleContext();
531 if( !pRContext
.is() )
534 short role
= pRContext
->getAccessibleRole();
536 if(css::accessibility::AccessibleRole::DOCUMENT
== role
||
537 css::accessibility::AccessibleRole::DOCUMENT_PRESENTATION
== role
||
538 css::accessibility::AccessibleRole::DOCUMENT_SPREADSHEET
== role
||
539 css::accessibility::AccessibleRole::DOCUMENT_TEXT
== role
)
541 if(IsStateManageDescendant(pXAcc
))
547 const sal_Int64 nCount
= pRContext
->getAccessibleChildCount();
548 for (sal_Int64 i
= 0; i
< nCount
; i
++)
550 Reference
<XAccessible
> mxAccessible
551 = pRContext
->getAccessibleChild(i
);
552 XAccessible
* mpAccessible
= mxAccessible
.get();
553 if(mpAccessible
!= nullptr)
555 InsertAccObj( mpAccessible
,pXAcc
,pWnd
);
556 InsertChildrenAccObj(mpAccessible
,pWnd
);
564 * Insert child object.
565 * @param pCurObj The child object
566 * @param pParentObj The parent object
567 * @param pWnd Top window handle.
570 void AccObjectWinManager::InsertAccChildNode( AccObject
* pCurObj
, AccObject
* pParentObj
, HWND
/* pWnd */ )
576 pParentObj
->InsertChild(pCurObj
);
580 pCurObj
->UpdateValidWindow();
586 * Insert child object.
587 * @param pCurObj The child object
588 * @param pParentObj The parent object
589 * @param pWnd Top window handle.
592 bool AccObjectWinManager::InsertAccObj( XAccessible
* pXAcc
,XAccessible
* pParentXAcc
,HWND pWnd
)
594 Reference
< XAccessibleContext
> pRContext
;
596 if( pXAcc
== nullptr)
599 pRContext
= pXAcc
->getAccessibleContext();
600 if( !pRContext
.is() )
604 short nCurRole
= GetRole(pXAcc
);
606 std::scoped_lock
l(m_Mutex
);
608 XIdToAccObjHash::iterator itXacc
= XIdAccList
.find( pXAcc
);
609 if (itXacc
!= XIdAccList
.end() )
611 if (AccessibleRole::SHAPE
== nCurRole
)
613 AccObject
&objXacc
= itXacc
->second
;
614 AccObject
*pObjParent
= objXacc
.GetParentObj();
616 pObjParent
->GetXAccessible().is() &&
617 pObjParent
->GetXAccessible().get() != pParentXAcc
)
619 XIdToAccObjHash::iterator itXaccParent
= XIdAccList
.find( pParentXAcc
);
620 if(itXaccParent
!= XIdAccList
.end())
622 objXacc
.SetParentObj(&(itXaccParent
->second
));
630 if( pWnd
== nullptr )
634 AccObject
* pObj
= GetAccObjByXAcc(pParentXAcc
);
636 pWnd
= pObj
->GetParentHWND();
638 if( pWnd
== nullptr )
642 AccObject
pObj( pXAcc
,pAgent
);
643 if( pObj
.GetIMAccessible() == nullptr )
645 pObj
.SetResID( this->ImpleGenerateResID());
646 pObj
.SetParentHWND( pWnd
);
648 //for file name support
649 if (pObj
.GetRole() == AccessibleRole::DOCUMENT
||
650 pObj
.GetRole() == AccessibleRole::DOCUMENT_PRESENTATION
||
651 pObj
.GetRole() == AccessibleRole::DOCUMENT_SPREADSHEET
||
652 pObj
.GetRole() == AccessibleRole::DOCUMENT_TEXT
)
654 XHWNDToDocumentHash::iterator aIter
= XHWNDDocList
.find(pWnd
);
655 if ( aIter
!= XHWNDDocList
.end() )
657 XHWNDDocList
.erase( aIter
);
659 XHWNDDocList
.emplace( pWnd
, pXAcc
);
663 ::rtl::Reference
<AccEventListener
> const pListener
=
664 CreateAccEventListener(pXAcc
);
667 Reference
<XAccessibleComponent
> xComponent(pRContext
,UNO_QUERY
);
668 Reference
<XAccessibleEventBroadcaster
> broadcaster(xComponent
,UNO_QUERY
);
669 if (broadcaster
.is())
671 Reference
<XAccessibleEventListener
> const xListener(pListener
);
672 broadcaster
->addAccessibleEventListener(xListener
);
678 std::scoped_lock
l(m_Mutex
);
680 XIdAccList
.emplace(pXAcc
, pObj
);
681 XIdToAccObjHash::iterator pIndTemp
= XIdAccList
.find( pXAcc
);
682 XResIdAccList
.emplace(pObj
.GetResID(),&(pIndTemp
->second
));
685 AccObject
* pCurObj
= GetAccObjByXAcc(pXAcc
);
688 pCurObj
->SetListener(pListener
);
691 AccObject
* pParentObj
= GetAccObjByXAcc(pParentXAcc
);
692 InsertAccChildNode(pCurObj
,pParentObj
,pWnd
);
694 pCurObj
->UpdateAccessibleInfoFromUnoToMSAA();
700 * save the pair <topwindowhandle, XAccessible>
701 * @param hWnd, top window handle
702 * @param pXAcc XAccessible interface for top window
705 void AccObjectWinManager::SaveTopWindowHandle(HWND hWnd
, css::accessibility::XAccessible
* pXAcc
)
707 std::scoped_lock
l(m_Mutex
);
709 HwndXAcc
.emplace(hWnd
,pXAcc
);
713 /** Create the corresponding listener.
714 * @param pXAcc XAccessible interface.
716 ::rtl::Reference
<AccEventListener
>
717 AccObjectWinManager::CreateAccEventListener(XAccessible
* pXAcc
)
719 ::rtl::Reference
<AccEventListener
> pRet
;
720 Reference
<XAccessibleContext
> xContext
= pXAcc
->getAccessibleContext();
723 switch( xContext
->getAccessibleRole() )
725 case AccessibleRole::DIALOG
:
726 pRet
= new AccDialogEventListener(pXAcc
,pAgent
);
728 case AccessibleRole::FRAME
:
729 pRet
= new AccFrameEventListener(pXAcc
,pAgent
);
731 case AccessibleRole::WINDOW
:
732 pRet
= new AccWindowEventListener(pXAcc
,pAgent
);
734 case AccessibleRole::ROOT_PANE
:
735 pRet
= new AccFrameEventListener(pXAcc
,pAgent
);
738 case AccessibleRole::CANVAS
:
739 case AccessibleRole::COMBO_BOX
:
740 case AccessibleRole::DOCUMENT
:
741 case AccessibleRole::DOCUMENT_PRESENTATION
:
742 case AccessibleRole::DOCUMENT_SPREADSHEET
:
743 case AccessibleRole::DOCUMENT_TEXT
:
744 case AccessibleRole::END_NOTE
:
745 case AccessibleRole::FILLER
:
746 case AccessibleRole::FOOTNOTE
:
747 case AccessibleRole::FOOTER
:
748 case AccessibleRole::HEADER
:
749 case AccessibleRole::LAYERED_PANE
:
750 case AccessibleRole::MENU_BAR
:
751 case AccessibleRole::POPUP_MENU
:
752 case AccessibleRole::OPTION_PANE
:
753 case AccessibleRole::PAGE_TAB
:
754 case AccessibleRole::PAGE_TAB_LIST
:
755 case AccessibleRole::PANEL
:
756 case AccessibleRole::SCROLL_PANE
:
757 case AccessibleRole::SPLIT_PANE
:
758 case AccessibleRole::STATUS_BAR
:
759 case AccessibleRole::TABLE_CELL
:
760 case AccessibleRole::TOOL_BAR
:
761 case AccessibleRole::VIEW_PORT
:
762 pRet
= new AccContainerEventListener(pXAcc
,pAgent
);
764 case AccessibleRole::PARAGRAPH
:
765 case AccessibleRole::HEADING
:
766 pRet
= new AccParagraphEventListener(pXAcc
,pAgent
);
769 case AccessibleRole::CHECK_BOX
:
770 case AccessibleRole::ICON
:
771 case AccessibleRole::LABEL
:
772 case AccessibleRole::STATIC
:
773 case AccessibleRole::NOTIFICATION
:
774 case AccessibleRole::MENU_ITEM
:
775 case AccessibleRole::CHECK_MENU_ITEM
:
776 case AccessibleRole::RADIO_MENU_ITEM
:
777 case AccessibleRole::PUSH_BUTTON
:
778 case AccessibleRole::RADIO_BUTTON
:
779 case AccessibleRole::SCROLL_BAR
:
780 case AccessibleRole::SEPARATOR
:
781 case AccessibleRole::TOGGLE_BUTTON
:
782 case AccessibleRole::BUTTON_DROPDOWN
:
783 case AccessibleRole::TOOL_TIP
:
784 case AccessibleRole::SPIN_BOX
:
785 case AccessibleRole::DATE_EDITOR
:
786 pRet
= new AccComponentEventListener(pXAcc
,pAgent
);
789 case AccessibleRole::TEXT
:
790 pRet
= new AccTextComponentEventListener(pXAcc
,pAgent
);
793 case AccessibleRole::MENU
:
794 pRet
= new AccMenuEventListener(pXAcc
,pAgent
);
797 case AccessibleRole::SHAPE
:
799 case AccessibleRole::EMBEDDED_OBJECT
:
800 case AccessibleRole::GRAPHIC
:
801 case AccessibleRole::TEXT_FRAME
:
802 pRet
= new AccObjectContainerEventListener(pXAcc
,pAgent
);
805 case AccessibleRole::LIST
:
806 pRet
= new AccListEventListener(pXAcc
,pAgent
);
808 case AccessibleRole::TREE
:
809 pRet
= new AccTreeEventListener(pXAcc
,pAgent
);
812 case AccessibleRole::COLUMN_HEADER
:
813 case AccessibleRole::TABLE
:
814 pRet
= new AccTableEventListener(pXAcc
,pAgent
);
817 pRet
= new AccContainerEventListener(pXAcc
,pAgent
);
825 * state is a combination integer, each bit of which represents a single state,
826 * such as focused,1 for the state on,0 for the state off. Here call COM interface
827 * to modify the state value, including DecreaseState.
828 * @param pXAcc XAccessible interface.
829 * @param pState Changed state.
832 void AccObjectWinManager::DecreaseState(XAccessible
* pXAcc
, sal_Int64 nState
)
834 AccObject
* pAccObj
= GetAccObjByXAcc( pXAcc
);
836 pAccObj
->DecreaseState(nState
);
840 * state is a combination integer, each bit of which represents a single state,such as focused,1 for
841 * the state on,0 for the state off. Here call COM interface to modify the state value, including
843 * @param pXAcc XAccessible interface.
844 * @param pState Changed state.
847 void AccObjectWinManager::IncreaseState(XAccessible
* pXAcc
, sal_Int64 nState
)
849 AccObject
* pAccObj
= GetAccObjByXAcc( pXAcc
);
851 pAccObj
->IncreaseState(nState
);
854 void AccObjectWinManager::UpdateState( css::accessibility::XAccessible
* pXAcc
)
856 AccObject
* pAccObj
= GetAccObjByXAcc( pXAcc
);
858 pAccObj
->UpdateState( );
862 * Set corresponding com object's accessible name via XAccessible interface and new
864 * @param pXAcc XAccessible interface.
867 void AccObjectWinManager::UpdateAccName( XAccessible
* pXAcc
)
869 AccObject
* pAccObj
= GetAccObjByXAcc( pXAcc
);
871 pAccObj
->UpdateName();
874 void AccObjectWinManager::UpdateAction( XAccessible
* pXAcc
)
876 AccObject
* pAccObj
= GetAccObjByXAcc( pXAcc
);
878 pAccObj
->UpdateAction();
882 * Set corresponding com object's value via XAccessible interface and new value.
883 * @param pXAcc XAccessible interface.
884 * @param pAny new value.
887 void AccObjectWinManager::SetValue( XAccessible
* pXAcc
, Any pAny
)
889 AccObject
* pAccObj
= GetAccObjByXAcc( pXAcc
);
891 pAccObj
->SetValue( pAny
);
895 * Set corresponding com object's value via XAccessible interface.
896 * @param pXAcc XAccessible interface.
899 void AccObjectWinManager::UpdateValue( XAccessible
* pXAcc
)
901 AccObject
* pAccObj
= GetAccObjByXAcc( pXAcc
);
903 pAccObj
->UpdateValue();
907 * Set corresponding com object's name via XAccessible interface and new name.
908 * @param pXAcc XAccessible interface.
909 * @param newName new name
912 void AccObjectWinManager::SetAccName( XAccessible
* pXAcc
, Any newName
)
914 AccObject
* pAccObj
= GetAccObjByXAcc( pXAcc
);
916 pAccObj
->SetName( newName
);
920 * Judge if a XAccessible object is a container object.
921 * @param pAccessible XAccessible interface.
922 * @return If XAccessible object is container.
924 bool AccObjectWinManager::IsContainer(XAccessible
* pAccessible
)
930 Reference
<XAccessibleContext
> xContext
= pAccessible
->getAccessibleContext();
933 switch( xContext
->getAccessibleRole() )
935 case AccessibleRole::DIALOG
:
936 case AccessibleRole::FRAME
:
937 case AccessibleRole::WINDOW
:
938 case AccessibleRole::ROOT_PANE
:
939 case AccessibleRole::CANVAS
:
940 case AccessibleRole::COMBO_BOX
:
941 case AccessibleRole::DOCUMENT
:
942 case AccessibleRole::DOCUMENT_PRESENTATION
:
943 case AccessibleRole::DOCUMENT_SPREADSHEET
:
944 case AccessibleRole::DOCUMENT_TEXT
:
945 case AccessibleRole::EMBEDDED_OBJECT
:
946 case AccessibleRole::END_NOTE
:
947 case AccessibleRole::FILLER
:
948 case AccessibleRole::FOOTNOTE
:
949 case AccessibleRole::FOOTER
:
950 case AccessibleRole::GRAPHIC
:
951 case AccessibleRole::GROUP_BOX
:
952 case AccessibleRole::HEADER
:
953 case AccessibleRole::LAYERED_PANE
:
954 case AccessibleRole::MENU_BAR
:
955 case AccessibleRole::POPUP_MENU
:
956 case AccessibleRole::OPTION_PANE
:
957 case AccessibleRole::PAGE_TAB
:
958 case AccessibleRole::PAGE_TAB_LIST
:
959 case AccessibleRole::PANEL
:
960 case AccessibleRole::SCROLL_PANE
:
961 case AccessibleRole::SPLIT_PANE
:
962 case AccessibleRole::STATUS_BAR
:
963 case AccessibleRole::TABLE_CELL
:
964 case AccessibleRole::TEXT_FRAME
:
965 case AccessibleRole::TOOL_BAR
:
966 case AccessibleRole::VIEW_PORT
:
967 case AccessibleRole::SHAPE
:
969 case AccessibleRole::COLUMN_HEADER
:
970 case AccessibleRole::TABLE
:
971 if(!IsStateManageDescendant(pAccessible
))
974 case AccessibleRole::MENU
:
990 * Judge if a XAccessible object has ManageDescendant event.
991 * @param pAccessible XAccessible interface.
992 * @return If XAccessible object is managedescendant.
994 bool AccObjectWinManager::IsStateManageDescendant(XAccessible
* pAccessible
)
998 Reference
<XAccessibleContext
> xContext
= pAccessible
->getAccessibleContext();
1001 sal_Int64 nRState
= xContext
->getAccessibleStateSet();
1002 return nRState
& AccessibleStateType::MANAGES_DESCENDANTS
;
1009 * Query and get IAccessible interface by XAccessible interface from list.
1010 * @param pXAcc XAccessible interface.
1011 * @return Com accobject interface.
1013 IMAccessible
* AccObjectWinManager::GetIMAccByXAcc(XAccessible
* pXAcc
)
1015 AccObject
* pAccObj
= GetAccObjByXAcc(pXAcc
);
1018 return pAccObj
->GetIMAccessible();
1027 * Query and get IAccessible interface by child id from list.
1028 * @param resID, childID.
1029 * @return Com accobject interface.
1031 IMAccessible
* AccObjectWinManager::GetIAccessibleFromResID(long resID
)
1033 XResIdToAccObjHash::iterator pIndTemp
= XResIdAccList
.find( resID
);
1034 if ( pIndTemp
== XResIdAccList
.end() )
1037 AccObject
* pObj
= pIndTemp
->second
;
1039 if(pObj
->GetIMAccessible())
1040 return pObj
->GetIMAccessible();
1044 * Notify some object will be destroyed.
1045 * @param pXAcc XAccessible interface.
1046 * @return Com accobject interface.
1048 void AccObjectWinManager::NotifyDestroy(XAccessible
* pXAcc
)
1050 AccObject
* accObj
= GetAccObjByXAcc(pXAcc
);
1053 accObj
->NotifyDestroy();
1058 void AccObjectWinManager::UpdateChildState(css::accessibility::XAccessible
* pAccSubMenu
)
1060 Reference
<css::accessibility::XAccessibleContext
> xContext(pAccSubMenu
,UNO_QUERY
);
1065 const sal_Int64 nCount
= xContext
->getAccessibleChildCount();
1066 for (sal_Int64 i
= 0 ; i
< nCount
; ++i
)
1068 Reference
<css::accessibility::XAccessible
> xChild
= xContext
->getAccessibleChild(i
);
1071 AccObject
*pObj
= GetAccObjByXAcc(xChild
.get());
1074 pObj
->UpdateState();
1081 bool AccObjectWinManager::IsSpecialToolbarItem(css::accessibility::XAccessible
* pXAcc
)
1083 if (pXAcc
&& oldFocus
!= pXAcc
)
1085 if (GetParentRole(pXAcc
) == AccessibleRole::TOOL_BAR
)
1087 Reference
< XAccessibleContext
> pRContext(pXAcc
->getAccessibleContext());
1090 if (pRContext
->getAccessibleRole() == AccessibleRole::TOGGLE_BUTTON
)
1100 short AccObjectWinManager::GetRole(css::accessibility::XAccessible
* pXAcc
)
1102 assert(pXAcc
!= nullptr);
1103 Reference
<css::accessibility::XAccessibleContext
> xContext
= pXAcc
->getAccessibleContext();
1106 return xContext
->getAccessibleRole();
1111 XAccessible
* AccObjectWinManager::GetAccDocByHWND(HWND pWnd
)
1113 XHWNDToDocumentHash::iterator aIter
;
1114 aIter
= XHWNDDocList
.find( pWnd
);
1115 if ( aIter
!= XHWNDDocList
.end() )
1117 return aIter
->second
;
1123 XAccessible
* AccObjectWinManager::GetAccDocByAccTopWin( XAccessible
* pXAcc
)
1125 AccObject
* pAccObj
= GetAccObjByXAcc( pXAcc
);
1126 HWND hWnd
= pAccObj
->GetParentHWND();
1127 return GetAccDocByHWND(hWnd
);
1130 bool AccObjectWinManager::IsTopWinAcc( css::accessibility::XAccessible
* pXAcc
)
1133 AccObject
* pAccObj
= GetAccObjByXAcc( pXAcc
);
1136 bRet
= ( pAccObj
->GetParentObj() == nullptr );
1140 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */