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
;
51 AccObjectWinManager::AccObjectWinManager():
57 * Destructor,clear all resource.
61 AccObjectWinManager::~AccObjectWinManager()
64 std::scoped_lock
l(m_Mutex
);
69 XResIdAccList
.clear();
75 * Get valid com object interface when notifying some MSAA event
76 * @param pWND The top window handle that contains that event control.
77 * @param wParam Windows system interface.
78 * @return Com interface with event.
82 AccObjectWinManager::Get_ToATInterface(sal_Int64 nHWnd
, long lParam
, WPARAM wParam
)
84 IMAccessible
* pRetIMAcc
= nullptr;
86 if(lParam
== OBJID_CLIENT
)
88 HWND hWnd
= reinterpret_cast<HWND
>(nHWnd
);
89 pRetIMAcc
= GetTopWindowIMAccessible(hWnd
);
92 if ( pRetIMAcc
&& lParam
== OBJID_CLIENT
)
94 LRESULT result
= LresultFromObject(IID_IAccessible
, wParam
, pRetIMAcc
);
96 return static_cast<sal_Int64
>(result
);
102 * Search AccObject by XAccessible pointer from our container.
103 * @param pXAcc XAccessible interface.
104 * @return Pointer of accObject that is found.
106 AccObject
* AccObjectWinManager::GetAccObjByXAcc( XAccessible
* pXAcc
)
108 if( pXAcc
== nullptr)
111 std::scoped_lock
l(m_Mutex
);
113 XIdToAccObjHash::iterator pIndTemp
= XIdAccList
.find( pXAcc
);
114 if ( pIndTemp
== XIdAccList
.end() )
117 return &(pIndTemp
->second
);
121 * get acc object of top window by its handle
122 * @param hWnd, top window handle
123 * @return pointer to AccObject
125 IMAccessible
* AccObjectWinManager::GetTopWindowIMAccessible(HWND hWnd
)
127 std::scoped_lock
l(m_Mutex
); // tdf#155794 for HwndXAcc and XIdAccList
129 XHWNDToXAccHash::iterator iterResult
=HwndXAcc
.find(hWnd
);
130 if(iterResult
== HwndXAcc
.end())
132 XAccessible
* pXAcc
= iterResult
->second
;
133 AccObject
*const pAccObject(GetAccObjByXAcc(pXAcc
));
138 IMAccessible
*const pRet(pAccObject
->GetIMAccessible());
148 * Simulate MSAA event via XAccessible interface and event type.
149 * @param pXAcc XAccessible interface.
150 * @param eEvent event type
151 * @return The terminate result that identifies if the call is successful.
153 bool AccObjectWinManager::NotifyAccEvent(XAccessible
* pXAcc
, UnoMSAAEvent eEvent
)
155 Reference
< XAccessibleContext
> pRContext
;
157 if( pXAcc
== nullptr)
161 pRContext
= pXAcc
->getAccessibleContext();
162 if( !pRContext
.is() )
166 AccObject
* selfAccObj
= GetAccObjByXAcc(pXAcc
);
168 if(selfAccObj
==nullptr)
171 long dChildID
= selfAccObj
->GetResID();
172 HWND hAcc
= selfAccObj
->GetParentHWND();
176 case UnoMSAAEvent::STATE_FOCUSED
:
178 UpdateAccFocus(pXAcc
);
180 NotifyWinEvent( EVENT_OBJECT_FOCUS
,hAcc
, OBJID_CLIENT
,dChildID
);
183 case UnoMSAAEvent::STATE_BUSY
:
184 NotifyWinEvent( EVENT_OBJECT_STATECHANGE
,hAcc
, OBJID_CLIENT
,dChildID
);
186 case UnoMSAAEvent::STATE_CHECKED
:
187 NotifyWinEvent( EVENT_OBJECT_STATECHANGE
,hAcc
, OBJID_CLIENT
,dChildID
);
189 case UnoMSAAEvent::STATE_PRESSED
:
190 NotifyWinEvent( EVENT_OBJECT_STATECHANGE
,hAcc
, OBJID_CLIENT
,dChildID
);
193 //Removed fire out selected event
194 //case UnoMSAAEvent::STATE_SELECTED:
195 // NotifyWinEvent( EVENT_OBJECT_STATECHANGE,hAcc, OBJID_CLIENT,dChildID );
197 case UnoMSAAEvent::STATE_ARMED
:
198 UpdateAccFocus(pXAcc
);
199 NotifyWinEvent( EVENT_OBJECT_FOCUS
,hAcc
, OBJID_CLIENT
,dChildID
);
201 case UnoMSAAEvent::STATE_SHOWING
:
202 // send EVENT_SYSTEM_ALERT when notification gets shown
203 if (pRContext
->getAccessibleRole() == AccessibleRole::NOTIFICATION
)
204 NotifyWinEvent(EVENT_SYSTEM_ALERT
, hAcc
, OBJID_CLIENT
, dChildID
);
206 case UnoMSAAEvent::MENU_START
:
207 NotifyWinEvent( EVENT_SYSTEM_MENUSTART
,hAcc
, OBJID_CLIENT
,dChildID
);
209 case UnoMSAAEvent::MENU_END
:
210 NotifyWinEvent( EVENT_SYSTEM_MENUEND
,hAcc
, OBJID_CLIENT
,dChildID
);
212 case UnoMSAAEvent::MENUPOPUPSTART
:
213 NotifyWinEvent( EVENT_SYSTEM_MENUPOPUPSTART
,hAcc
, OBJID_CLIENT
,dChildID
);
215 case UnoMSAAEvent::MENUPOPUPEND
:
216 NotifyWinEvent( EVENT_SYSTEM_MENUPOPUPEND
,hAcc
, OBJID_CLIENT
,dChildID
);
218 case UnoMSAAEvent::SELECTION_CHANGED
:
219 NotifyWinEvent( EVENT_OBJECT_SELECTION
,hAcc
, OBJID_CLIENT
,dChildID
);
221 case UnoMSAAEvent::SELECTION_CHANGED_ADD
:
222 NotifyWinEvent( EVENT_OBJECT_SELECTIONADD
,hAcc
, OBJID_CLIENT
,dChildID
);
224 case UnoMSAAEvent::SELECTION_CHANGED_REMOVE
:
225 NotifyWinEvent( EVENT_OBJECT_SELECTIONREMOVE
,hAcc
, OBJID_CLIENT
,dChildID
);
227 case UnoMSAAEvent::SELECTION_CHANGED_WITHIN
:
228 NotifyWinEvent( EVENT_OBJECT_SELECTIONWITHIN
,hAcc
, OBJID_CLIENT
,dChildID
);
230 case UnoMSAAEvent::OBJECT_VALUECHANGE
:
232 NotifyWinEvent( EVENT_OBJECT_VALUECHANGE
,hAcc
, OBJID_CLIENT
,dChildID
);
234 case UnoMSAAEvent::OBJECT_NAMECHANGE
:
235 NotifyWinEvent( EVENT_OBJECT_NAMECHANGE
,hAcc
, OBJID_CLIENT
,dChildID
);
237 case UnoMSAAEvent::OBJECT_DESCRIPTIONCHANGE
:
238 NotifyWinEvent( EVENT_OBJECT_DESCRIPTIONCHANGE
,hAcc
, OBJID_CLIENT
,dChildID
);
240 case UnoMSAAEvent::OBJECT_DEFACTIONCHANGE
:
241 NotifyWinEvent( IA2_EVENT_ACTION_CHANGED
,hAcc
, OBJID_CLIENT
,dChildID
);
243 case UnoMSAAEvent::OBJECT_CARETCHANGE
:
244 NotifyWinEvent( IA2_EVENT_TEXT_CARET_MOVED
,hAcc
, OBJID_CLIENT
,dChildID
);
246 case UnoMSAAEvent::OBJECT_TEXTCHANGE
:
247 NotifyWinEvent(IA2_EVENT_TEXT_UPDATED
, hAcc
, OBJID_CLIENT
, dChildID
);
249 case UnoMSAAEvent::ACTIVE_DESCENDANT_CHANGED
:
250 UpdateAccFocus(pXAcc
);
251 NotifyWinEvent( EVENT_OBJECT_FOCUS
,hAcc
, OBJID_CLIENT
,dChildID
);
253 case UnoMSAAEvent::BOUNDRECT_CHANGED
:
254 NotifyWinEvent( EVENT_OBJECT_LOCATIONCHANGE
,hAcc
, OBJID_CLIENT
,dChildID
);
256 case UnoMSAAEvent::VISIBLE_DATA_CHANGED
:
257 NotifyWinEvent( IA2_EVENT_VISIBLE_DATA_CHANGED
,hAcc
, OBJID_CLIENT
,dChildID
);
259 case UnoMSAAEvent::SHOW
:
260 NotifyWinEvent( EVENT_OBJECT_SHOW
,hAcc
, OBJID_CLIENT
,dChildID
);
261 NotifyWinEvent( EVENT_SYSTEM_FOREGROUND
,hAcc
, OBJID_CLIENT
,dChildID
);
263 case UnoMSAAEvent::TABLE_CAPTION_CHANGED
:
264 NotifyWinEvent( IA2_EVENT_TABLE_CAPTION_CHANGED
,hAcc
, OBJID_CLIENT
,dChildID
);
266 case UnoMSAAEvent::TABLE_COLUMN_DESCRIPTION_CHANGED
:
267 NotifyWinEvent( IA2_EVENT_TABLE_COLUMN_DESCRIPTION_CHANGED
,hAcc
, OBJID_CLIENT
,dChildID
);
269 case UnoMSAAEvent::TABLE_COLUMN_HEADER_CHANGED
:
270 NotifyWinEvent( IA2_EVENT_TABLE_COLUMN_HEADER_CHANGED
,hAcc
, OBJID_CLIENT
,dChildID
);
272 case UnoMSAAEvent::TABLE_MODEL_CHANGED
:
273 NotifyWinEvent( IA2_EVENT_TABLE_MODEL_CHANGED
,hAcc
, OBJID_CLIENT
,dChildID
);
275 case UnoMSAAEvent::TABLE_ROW_HEADER_CHANGED
:
276 NotifyWinEvent( IA2_EVENT_TABLE_ROW_HEADER_CHANGED
,hAcc
, OBJID_CLIENT
,dChildID
);
278 case UnoMSAAEvent::TABLE_SUMMARY_CHANGED
:
279 NotifyWinEvent( IA2_EVENT_TABLE_SUMMARY_CHANGED
,hAcc
, OBJID_CLIENT
,dChildID
);
281 case UnoMSAAEvent::TABLE_ROW_DESCRIPTION_CHANGED
:
282 NotifyWinEvent( IA2_EVENT_TABLE_ROW_DESCRIPTION_CHANGED
,hAcc
, OBJID_CLIENT
,dChildID
);
284 case UnoMSAAEvent::OBJECT_REORDER
:
285 NotifyWinEvent( EVENT_OBJECT_REORDER
,hAcc
, OBJID_CLIENT
,dChildID
);
287 case UnoMSAAEvent::PAGE_CHANGED
:
288 NotifyWinEvent( IA2_EVENT_PAGE_CHANGED
,hAcc
, OBJID_CLIENT
,dChildID
);
290 case UnoMSAAEvent::CHILD_REMOVED
:
291 NotifyWinEvent( EVENT_OBJECT_DESTROY
,hAcc
, OBJID_CLIENT
,dChildID
);
293 case UnoMSAAEvent::CHILD_ADDED
:
294 NotifyWinEvent( EVENT_OBJECT_CREATE
,hAcc
, OBJID_CLIENT
,dChildID
);
296 case UnoMSAAEvent::OBJECT_PAGECHANGED
:
297 NotifyWinEvent( IA2_EVENT_PAGE_CHANGED
,hAcc
, OBJID_CLIENT
,dChildID
);
299 case UnoMSAAEvent::TEXT_SELECTION_CHANGED
:
300 NotifyWinEvent( IA2_EVENT_TEXT_SELECTION_CHANGED
,hAcc
, OBJID_CLIENT
,dChildID
);
302 case UnoMSAAEvent::SECTION_CHANGED
:
303 NotifyWinEvent( IA2_EVENT_SECTION_CHANGED
,hAcc
, OBJID_CLIENT
,dChildID
);
305 case UnoMSAAEvent::COLUMN_CHANGED
:
306 NotifyWinEvent( IA2_EVENT_TEXT_COLUMN_CHANGED
,hAcc
, OBJID_CLIENT
,dChildID
);
316 * Get Parent XAccessible interface by XAccessible interface.
317 * @param pXAcc XAccessible interface.
318 * @return Parent XAccessible interface.
320 XAccessible
* AccObjectWinManager::GetParentXAccessible( XAccessible
* pXAcc
)
322 AccObject
* pObj
= GetAccObjByXAcc(pXAcc
);
325 if(pObj
->GetParentObj())
327 pObj
= pObj
->GetParentObj();
328 return pObj
->GetXAccessible().get();
334 * Get Parent role by XAccessible interface.
335 * @param pXAcc XAccessible interface.
336 * @return Parent role.
338 short AccObjectWinManager::GetParentRole( XAccessible
* pXAcc
)
340 AccObject
* pObj
= GetAccObjByXAcc(pXAcc
);
343 if(pObj
->GetParentObj())
345 pObj
= pObj
->GetParentObj();
346 if(pObj
->GetXAccessible().is())
348 Reference
< XAccessibleContext
> pRContext
= pObj
->GetXAccessible()->getAccessibleContext();
350 return pRContext
->getAccessibleRole();
357 * Update focus object by new focused XAccessible interface.
358 * @param newFocus New XAccessible interface that gets focus.
361 void AccObjectWinManager::UpdateAccFocus(XAccessible
* newFocus
)
363 AccObject
* pAccObjNew
= GetAccObjByXAcc(newFocus
);
366 AccObject
* pAccObjOld
= GetAccObjByXAcc(oldFocus
);
368 pAccObjNew
->setFocus();
369 //if old == new, the pAccObjNew will be without focused state
370 if (pAccObjOld
&& pAccObjOld
!= pAccObjNew
)
371 pAccObjOld
->unsetFocus();
376 * Delete child element from children list.
377 * @param pObj Child element that should be removed from parent child list.
380 void AccObjectWinManager::DeleteAccChildNode( AccObject
* pObj
)
382 AccObject
*parentAccObj
= pObj
->GetParentObj();
384 parentAccObj
->DeleteChild( pObj
);
388 * Delete XAccessible items in top window handle hashtable
389 * @param pXAcc XAccessible interface.
392 void AccObjectWinManager::DeleteFromHwndXAcc(XAccessible
const * pXAcc
)
394 std::scoped_lock
l(m_Mutex
);
396 auto iter
= std::find_if(HwndXAcc
.begin(), HwndXAcc
.end(),
397 [&pXAcc
](XHWNDToXAccHash::value_type
& rEntry
) { return rEntry
.second
== pXAcc
; });
398 if (iter
!= HwndXAcc
.end())
399 HwndXAcc
.erase(iter
);
403 * Delete all children with the tree root of XAccessible pointer
404 * @param pXAcc Tree root XAccessible interface.
407 void AccObjectWinManager::DeleteChildrenAccObj(XAccessible
* pXAcc
)
409 AccObject
* currentObj
=nullptr;
410 AccObject
* childObj
=nullptr;
412 currentObj
= GetAccObjByXAcc( pXAcc
);
415 childObj
= currentObj
->NextChild();
418 XAccessible
*const pTmpXAcc
= childObj
->GetXAccessible().get();
421 DeleteChildrenAccObj(pTmpXAcc
);
422 DeleteAccObj(pTmpXAcc
);
424 childObj
= currentObj
->NextChild();
430 * Delete Acc object self.
431 * @param pXAcc The XAccessible interface.
434 void AccObjectWinManager::DeleteAccObj( XAccessible
* pXAcc
)
436 if( pXAcc
== nullptr )
439 rtl::Reference
<AccEventListener
> pListener
;
442 std::scoped_lock
l(m_Mutex
);
444 XIdToAccObjHash::iterator temp
= XIdAccList
.find(pXAcc
);
445 if( temp
!= XIdAccList
.end() )
447 ResIdGen
.SetSub( temp
->second
.GetResID() );
454 AccObject
& accObj
= temp
->second
;
455 DeleteAccChildNode( &accObj
);
456 pListener
= DeleteAccListener(&accObj
);
457 accObj
.NotifyDestroy();
458 if( accObj
.GetIMAccessible() )
460 accObj
.GetIMAccessible()->Release();
462 size_t i
= XResIdAccList
.erase(accObj
.GetResID());
465 DeleteFromHwndXAcc(pXAcc
);
466 if (accObj
.GetRole() == AccessibleRole::DOCUMENT
||
467 accObj
.GetRole() == AccessibleRole::DOCUMENT_PRESENTATION
||
468 accObj
.GetRole() == AccessibleRole::DOCUMENT_SPREADSHEET
||
469 accObj
.GetRole() == AccessibleRole::DOCUMENT_TEXT
)
471 XHWNDDocList
.erase(accObj
.GetParentHWND());
473 XIdAccList
.erase(pXAcc
); // note: this invalidates accObj so do it last!
477 pListener
->RemoveMeFromBroadcaster(false);
482 * Delete listener that inspects some XAccessible object
483 * @param pAccObj Accobject pointer.
486 rtl::Reference
<AccEventListener
> AccObjectWinManager::DeleteAccListener( AccObject
* pAccObj
)
488 return pAccObj
->SetListener(nullptr);
492 * Generate a child ID, which is used for AT
494 * @return New resource ID.
496 inline long AccObjectWinManager::ImpleGenerateResID()
498 return ResIdGen
.GenerateNewResID();
502 * Insert all children of the current acc object
503 * @param pXAcc XAccessible interface
504 * @param pWnd Top Window handle
505 * @return The calling result.
507 bool AccObjectWinManager::InsertChildrenAccObj( css::accessibility::XAccessible
* pXAcc
,
510 if(!IsContainer(pXAcc
))
513 if( pXAcc
== nullptr)
516 Reference
<XAccessibleContext
> xContext
= pXAcc
->getAccessibleContext();
520 short role
= xContext
->getAccessibleRole();
522 if(css::accessibility::AccessibleRole::DOCUMENT
== role
||
523 css::accessibility::AccessibleRole::DOCUMENT_PRESENTATION
== role
||
524 css::accessibility::AccessibleRole::DOCUMENT_SPREADSHEET
== role
||
525 css::accessibility::AccessibleRole::DOCUMENT_TEXT
== role
)
527 if(IsStateManageDescendant(pXAcc
))
533 const sal_Int64 nCount
= xContext
->getAccessibleChildCount();
534 for (sal_Int64 i
= 0; i
< nCount
; i
++)
536 Reference
<XAccessible
> mxAccessible
= xContext
->getAccessibleChild(i
);
537 XAccessible
* mpAccessible
= mxAccessible
.get();
538 if(mpAccessible
!= nullptr)
540 InsertAccObj( mpAccessible
,pXAcc
,pWnd
);
541 InsertChildrenAccObj(mpAccessible
,pWnd
);
549 * Insert child object.
550 * @param pCurObj The child object
551 * @param pParentObj The parent object
552 * @param pWnd Top window handle.
555 void AccObjectWinManager::InsertAccChildNode( AccObject
* pCurObj
, AccObject
* pParentObj
, HWND
/* pWnd */ )
561 pParentObj
->InsertChild(pCurObj
);
565 pCurObj
->UpdateValidWindow();
571 * Insert child object.
572 * @param pCurObj The child object
573 * @param pParentObj The parent object
574 * @param pWnd Top window handle.
577 bool AccObjectWinManager::InsertAccObj( XAccessible
* pXAcc
,XAccessible
* pParentXAcc
,HWND pWnd
)
579 if( pXAcc
== nullptr)
582 Reference
<XAccessibleContext
> xContext
= pXAcc
->getAccessibleContext();
587 short nCurRole
= xContext
->getAccessibleRole();
589 std::scoped_lock
l(m_Mutex
);
591 XIdToAccObjHash::iterator itXacc
= XIdAccList
.find( pXAcc
);
592 if (itXacc
!= XIdAccList
.end() )
594 if (AccessibleRole::SHAPE
== nCurRole
)
596 AccObject
&objXacc
= itXacc
->second
;
597 AccObject
*pObjParent
= objXacc
.GetParentObj();
599 pObjParent
->GetXAccessible().is() &&
600 pObjParent
->GetXAccessible().get() != pParentXAcc
)
602 XIdToAccObjHash::iterator itXaccParent
= XIdAccList
.find( pParentXAcc
);
603 if(itXaccParent
!= XIdAccList
.end())
605 objXacc
.SetParentObj(&(itXaccParent
->second
));
613 if( pWnd
== nullptr )
617 AccObject
* pObj
= GetAccObjByXAcc(pParentXAcc
);
619 // insert parent if necessary
622 Reference
<XAccessibleContext
> xParentContext
= pParentXAcc
->getAccessibleContext();
623 assert(xParentContext
.is() && "parent accessible has no context");
624 InsertAccObj(pParentXAcc
, xParentContext
->getAccessibleParent().get());
625 pObj
= GetAccObjByXAcc(pParentXAcc
);
629 pWnd
= pObj
->GetParentHWND();
631 if( pWnd
== nullptr )
635 AccObject
pObj(pXAcc
, this);
636 pObj
.SetResID( this->ImpleGenerateResID());
637 pObj
.SetParentHWND( pWnd
);
639 //for file name support
640 if (pObj
.GetRole() == AccessibleRole::DOCUMENT
||
641 pObj
.GetRole() == AccessibleRole::DOCUMENT_PRESENTATION
||
642 pObj
.GetRole() == AccessibleRole::DOCUMENT_SPREADSHEET
||
643 pObj
.GetRole() == AccessibleRole::DOCUMENT_TEXT
)
645 XHWNDToDocumentHash::iterator aIter
= XHWNDDocList
.find(pWnd
);
646 if ( aIter
!= XHWNDDocList
.end() )
648 XHWNDDocList
.erase( aIter
);
650 XHWNDDocList
.emplace( pWnd
, pXAcc
);
654 ::rtl::Reference
<AccEventListener
> const pListener
=
655 CreateAccEventListener(pXAcc
);
658 Reference
<XAccessibleComponent
> xComponent(xContext
, UNO_QUERY
);
659 Reference
<XAccessibleEventBroadcaster
> broadcaster(xComponent
,UNO_QUERY
);
660 if (broadcaster
.is())
662 Reference
<XAccessibleEventListener
> const xListener(pListener
);
663 broadcaster
->addAccessibleEventListener(xListener
);
669 std::scoped_lock
l(m_Mutex
);
671 XIdAccList
.emplace(pXAcc
, pObj
);
672 XIdToAccObjHash::iterator pIndTemp
= XIdAccList
.find( pXAcc
);
673 XResIdAccList
.emplace(pObj
.GetResID(),&(pIndTemp
->second
));
676 AccObject
* pCurObj
= GetAccObjByXAcc(pXAcc
);
679 pCurObj
->SetListener(pListener
);
682 AccObject
* pParentObj
= GetAccObjByXAcc(pParentXAcc
);
683 InsertAccChildNode(pCurObj
,pParentObj
,pWnd
);
685 pCurObj
->UpdateAccessibleInfoFromUnoToMSAA();
691 * save the pair <topwindowhandle, XAccessible>
692 * @param hWnd, top window handle
693 * @param pXAcc XAccessible interface for top window
696 void AccObjectWinManager::SaveTopWindowHandle(HWND hWnd
, css::accessibility::XAccessible
* pXAcc
)
698 std::scoped_lock
l(m_Mutex
);
700 HwndXAcc
.emplace(hWnd
,pXAcc
);
704 /** Create the corresponding listener.
705 * @param pXAcc XAccessible interface.
707 ::rtl::Reference
<AccEventListener
>
708 AccObjectWinManager::CreateAccEventListener(XAccessible
* pXAcc
)
710 ::rtl::Reference
<AccEventListener
> pRet
;
711 Reference
<XAccessibleContext
> xContext
= pXAcc
->getAccessibleContext();
714 switch( xContext
->getAccessibleRole() )
716 case AccessibleRole::DIALOG
:
717 pRet
= new AccDialogEventListener(pXAcc
, *this);
719 case AccessibleRole::FRAME
:
720 pRet
= new AccFrameEventListener(pXAcc
, *this);
722 case AccessibleRole::WINDOW
:
723 pRet
= new AccWindowEventListener(pXAcc
, *this);
725 case AccessibleRole::ROOT_PANE
:
726 pRet
= new AccFrameEventListener(pXAcc
, *this);
729 case AccessibleRole::CANVAS
:
730 case AccessibleRole::COMBO_BOX
:
731 case AccessibleRole::DOCUMENT
:
732 case AccessibleRole::DOCUMENT_PRESENTATION
:
733 case AccessibleRole::DOCUMENT_SPREADSHEET
:
734 case AccessibleRole::DOCUMENT_TEXT
:
735 case AccessibleRole::END_NOTE
:
736 case AccessibleRole::FILLER
:
737 case AccessibleRole::FOOTNOTE
:
738 case AccessibleRole::FOOTER
:
739 case AccessibleRole::HEADER
:
740 case AccessibleRole::LAYERED_PANE
:
741 case AccessibleRole::MENU_BAR
:
742 case AccessibleRole::POPUP_MENU
:
743 case AccessibleRole::OPTION_PANE
:
744 case AccessibleRole::PAGE_TAB
:
745 case AccessibleRole::PAGE_TAB_LIST
:
746 case AccessibleRole::PANEL
:
747 case AccessibleRole::SCROLL_PANE
:
748 case AccessibleRole::SPLIT_PANE
:
749 case AccessibleRole::STATUS_BAR
:
750 case AccessibleRole::TABLE_CELL
:
751 case AccessibleRole::TOOL_BAR
:
752 case AccessibleRole::VIEW_PORT
:
753 pRet
= new AccContainerEventListener(pXAcc
, *this);
755 case AccessibleRole::BLOCK_QUOTE
:
756 case AccessibleRole::PARAGRAPH
:
757 case AccessibleRole::HEADING
:
758 pRet
= new AccParagraphEventListener(pXAcc
, *this);
761 case AccessibleRole::CHECK_BOX
:
762 case AccessibleRole::ICON
:
763 case AccessibleRole::LABEL
:
764 case AccessibleRole::STATIC
:
765 case AccessibleRole::NOTIFICATION
:
766 case AccessibleRole::MENU_ITEM
:
767 case AccessibleRole::CHECK_MENU_ITEM
:
768 case AccessibleRole::RADIO_MENU_ITEM
:
769 case AccessibleRole::PUSH_BUTTON
:
770 case AccessibleRole::RADIO_BUTTON
:
771 case AccessibleRole::SCROLL_BAR
:
772 case AccessibleRole::SEPARATOR
:
773 case AccessibleRole::TOGGLE_BUTTON
:
774 case AccessibleRole::BUTTON_DROPDOWN
:
775 case AccessibleRole::TOOL_TIP
:
776 case AccessibleRole::SPIN_BOX
:
777 case AccessibleRole::DATE_EDITOR
:
778 pRet
= new AccComponentEventListener(pXAcc
, *this);
781 case AccessibleRole::TEXT
:
782 pRet
= new AccTextComponentEventListener(pXAcc
, *this);
785 case AccessibleRole::MENU
:
786 pRet
= new AccMenuEventListener(pXAcc
, *this);
789 case AccessibleRole::SHAPE
:
791 case AccessibleRole::EMBEDDED_OBJECT
:
792 case AccessibleRole::GRAPHIC
:
793 case AccessibleRole::TEXT_FRAME
:
794 pRet
= new AccObjectContainerEventListener(pXAcc
, *this);
797 case AccessibleRole::LIST
:
798 pRet
= new AccListEventListener(pXAcc
, *this);
800 case AccessibleRole::TREE
:
801 pRet
= new AccTreeEventListener(pXAcc
, *this);
804 case AccessibleRole::COLUMN_HEADER
:
805 case AccessibleRole::TABLE
:
806 pRet
= new AccTableEventListener(pXAcc
, *this);
809 pRet
= new AccContainerEventListener(pXAcc
, *this);
817 * state is a combination integer, each bit of which represents a single state,
818 * such as focused,1 for the state on,0 for the state off. Here call COM interface
819 * to modify the state value, including DecreaseState.
820 * @param pXAcc XAccessible interface.
821 * @param pState Changed state.
824 void AccObjectWinManager::DecreaseState(XAccessible
* pXAcc
, sal_Int64 nState
)
826 AccObject
* pAccObj
= GetAccObjByXAcc( pXAcc
);
828 pAccObj
->DecreaseState(nState
);
832 * state is a combination integer, each bit of which represents a single state,such as focused,1 for
833 * the state on,0 for the state off. Here call COM interface to modify the state value, including
835 * @param pXAcc XAccessible interface.
836 * @param pState Changed state.
839 void AccObjectWinManager::IncreaseState(XAccessible
* pXAcc
, sal_Int64 nState
)
841 AccObject
* pAccObj
= GetAccObjByXAcc( pXAcc
);
843 pAccObj
->IncreaseState(nState
);
846 void AccObjectWinManager::UpdateState( css::accessibility::XAccessible
* pXAcc
)
848 AccObject
* pAccObj
= GetAccObjByXAcc( pXAcc
);
850 pAccObj
->UpdateState( );
854 * Set corresponding com object's value via XAccessible interface and new value.
855 * @param pXAcc XAccessible interface.
856 * @param pAny new value.
859 void AccObjectWinManager::SetValue( XAccessible
* pXAcc
, Any pAny
)
861 AccObject
* pAccObj
= GetAccObjByXAcc( pXAcc
);
863 pAccObj
->SetValue( pAny
);
867 * Set corresponding com object's value via XAccessible interface.
868 * @param pXAcc XAccessible interface.
871 void AccObjectWinManager::UpdateValue( XAccessible
* pXAcc
)
873 AccObject
* pAccObj
= GetAccObjByXAcc( pXAcc
);
875 pAccObj
->UpdateValue();
879 * Judge if a XAccessible object is a container object.
880 * @param pAccessible XAccessible interface.
881 * @return If XAccessible object is container.
883 bool AccObjectWinManager::IsContainer(XAccessible
* pAccessible
)
889 Reference
<XAccessibleContext
> xContext
= pAccessible
->getAccessibleContext();
892 switch( xContext
->getAccessibleRole() )
894 case AccessibleRole::DIALOG
:
895 case AccessibleRole::FRAME
:
896 case AccessibleRole::WINDOW
:
897 case AccessibleRole::ROOT_PANE
:
898 case AccessibleRole::CANVAS
:
899 case AccessibleRole::COMBO_BOX
:
900 case AccessibleRole::DOCUMENT
:
901 case AccessibleRole::DOCUMENT_PRESENTATION
:
902 case AccessibleRole::DOCUMENT_SPREADSHEET
:
903 case AccessibleRole::DOCUMENT_TEXT
:
904 case AccessibleRole::EMBEDDED_OBJECT
:
905 case AccessibleRole::END_NOTE
:
906 case AccessibleRole::FILLER
:
907 case AccessibleRole::FOOTNOTE
:
908 case AccessibleRole::FOOTER
:
909 case AccessibleRole::GRAPHIC
:
910 case AccessibleRole::GROUP_BOX
:
911 case AccessibleRole::HEADER
:
912 case AccessibleRole::LAYERED_PANE
:
913 case AccessibleRole::MENU_BAR
:
914 case AccessibleRole::POPUP_MENU
:
915 case AccessibleRole::OPTION_PANE
:
916 case AccessibleRole::PAGE_TAB
:
917 case AccessibleRole::PAGE_TAB_LIST
:
918 case AccessibleRole::PANEL
:
919 case AccessibleRole::SCROLL_PANE
:
920 case AccessibleRole::SPLIT_PANE
:
921 case AccessibleRole::STATUS_BAR
:
922 case AccessibleRole::TABLE_CELL
:
923 case AccessibleRole::TEXT_FRAME
:
924 case AccessibleRole::TOOL_BAR
:
925 case AccessibleRole::VIEW_PORT
:
926 case AccessibleRole::SHAPE
:
928 case AccessibleRole::COLUMN_HEADER
:
929 case AccessibleRole::TABLE
:
930 if(!IsStateManageDescendant(pAccessible
))
933 case AccessibleRole::MENU
:
949 * Judge if a XAccessible object has ManageDescendant event.
950 * @param pAccessible XAccessible interface.
951 * @return If XAccessible object is managedescendant.
953 bool AccObjectWinManager::IsStateManageDescendant(XAccessible
* pAccessible
)
957 Reference
<XAccessibleContext
> xContext
= pAccessible
->getAccessibleContext();
960 sal_Int64 nRState
= xContext
->getAccessibleStateSet();
961 return nRState
& AccessibleStateType::MANAGES_DESCENDANTS
;
968 * Query and get IAccessible interface by XAccessible interface from list.
969 * @param pXAcc XAccessible interface.
970 * @return Com accobject interface.
972 IMAccessible
* AccObjectWinManager::GetIAccessibleFromXAccessible(XAccessible
* pXAcc
)
974 AccObject
* pAccObj
= GetAccObjByXAcc(pXAcc
);
976 return pAccObj
->GetIMAccessible();
982 * Query and get IAccessible interface by child id from list.
983 * @param resID, childID.
984 * @return Com accobject interface.
986 IMAccessible
* AccObjectWinManager::GetIAccessibleFromResID(long resID
)
988 XResIdToAccObjHash::iterator pIndTemp
= XResIdAccList
.find( resID
);
989 if ( pIndTemp
== XResIdAccList
.end() )
992 AccObject
* pObj
= pIndTemp
->second
;
994 if(pObj
->GetIMAccessible())
995 return pObj
->GetIMAccessible();
999 * Notify some object will be destroyed.
1000 * @param pXAcc XAccessible interface.
1001 * @return Com accobject interface.
1003 void AccObjectWinManager::NotifyDestroy(XAccessible
* pXAcc
)
1005 AccObject
* accObj
= GetAccObjByXAcc(pXAcc
);
1008 accObj
->NotifyDestroy();
1013 void AccObjectWinManager::UpdateChildState(css::accessibility::XAccessible
* pAccSubMenu
)
1015 Reference
<css::accessibility::XAccessibleContext
> xContext(pAccSubMenu
,UNO_QUERY
);
1020 const sal_Int64 nCount
= xContext
->getAccessibleChildCount();
1021 for (sal_Int64 i
= 0 ; i
< nCount
; ++i
)
1023 Reference
<css::accessibility::XAccessible
> xChild
= xContext
->getAccessibleChild(i
);
1026 AccObject
*pObj
= GetAccObjByXAcc(xChild
.get());
1029 pObj
->UpdateState();
1035 XAccessible
* AccObjectWinManager::GetAccDocByHWND(HWND pWnd
)
1037 XHWNDToDocumentHash::iterator aIter
;
1038 aIter
= XHWNDDocList
.find( pWnd
);
1039 if ( aIter
!= XHWNDDocList
.end() )
1041 return aIter
->second
;
1047 XAccessible
* AccObjectWinManager::GetAccDocByAccTopWin( XAccessible
* pXAcc
)
1049 AccObject
* pAccObj
= GetAccObjByXAcc( pXAcc
);
1050 HWND hWnd
= pAccObj
->GetParentHWND();
1051 return GetAccDocByHWND(hWnd
);
1054 bool AccObjectWinManager::IsTopWinAcc( css::accessibility::XAccessible
* pXAcc
)
1057 AccObject
* pAccObj
= GetAccObjByXAcc( pXAcc
);
1060 bRet
= ( pAccObj
->GetParentObj() == nullptr );
1064 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */