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
= nullptr;
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 LRESULT result
= LresultFromObject(IID_IAccessible
, wParam
, pRetIMAcc
);
115 pRetIMAcc
->Release();
122 * Search AccObject by XAccessible pointer from our container.
123 * @param pXAcc XAccessible interface.
124 * @return Pointer of accObject that is found.
126 AccObject
* AccObjectWinManager::GetAccObjByXAcc( XAccessible
* pXAcc
)
128 if( pXAcc
== nullptr)
131 XIdToAccObjHash::iterator pIndTemp
= XIdAccList
.find( pXAcc
);
132 if ( pIndTemp
== XIdAccList
.end() )
135 return &(pIndTemp
->second
);
139 * get acc object of top window by its handle
140 * @param hWnd, top window handle
141 * @return pointer to AccObject
143 AccObject
* AccObjectWinManager::GetTopWindowAccObj(HWND hWnd
)
145 XHWNDToXAccHash::iterator iterResult
=HwndXAcc
.find(hWnd
);
146 if(iterResult
== HwndXAcc
.end())
148 XAccessible
* pXAcc
= static_cast<XAccessible
*>(iterResult
->second
);
149 return GetAccObjByXAcc(pXAcc
);
153 * Simulate MSAA event via XAccessible interface and event type.
154 * @param pXAcc XAccessible interface.
155 * @param state Customize Interface
156 * @return The terminate result that identifies if the call is successful.
158 bool AccObjectWinManager::NotifyAccEvent(XAccessible
* pXAcc
,short state
)
160 Reference
< XAccessibleContext
> pRContext
;
162 if( pXAcc
== nullptr)
166 pRContext
= pXAcc
->getAccessibleContext();
167 if( !pRContext
.is() )
171 AccObject
* selfAccObj
= GetAccObjByXAcc(pXAcc
);
173 if(selfAccObj
==nullptr)
176 long dChildID
= selfAccObj
->GetResID();
177 HWND hAcc
= selfAccObj
->GetParentHWND();
181 case UM_EVENT_STATE_FOCUSED
:
183 UpdateAccFocus(pXAcc
);
184 selfAccObj
->UpdateDefaultAction( );
186 NotifyWinEvent( EVENT_OBJECT_FOCUS
,hAcc
, OBJID_CLIENT
,dChildID
);
189 case UM_EVENT_STATE_BUSY
:
190 NotifyWinEvent( EVENT_OBJECT_STATECHANGE
,hAcc
, OBJID_CLIENT
,dChildID
);
192 case UM_EVENT_STATE_CHECKED
:
193 NotifyWinEvent( EVENT_OBJECT_STATECHANGE
,hAcc
, OBJID_CLIENT
,dChildID
);
195 case UM_EVENT_STATE_PRESSED
:
196 NotifyWinEvent( EVENT_OBJECT_STATECHANGE
,hAcc
, OBJID_CLIENT
,dChildID
);
199 //Removed fire out selected event
200 //case UM_EVENT_STATE_SELECTED:
201 // NotifyWinEvent( EVENT_OBJECT_STATECHANGE,hAcc, OBJID_CLIENT,dChildID );
203 case UM_EVENT_STATE_ARMED
:
204 UpdateAccFocus(pXAcc
);
205 NotifyWinEvent( EVENT_OBJECT_FOCUS
,hAcc
, OBJID_CLIENT
,dChildID
);
207 case UM_EVENT_MENU_START
:
208 NotifyWinEvent( EVENT_SYSTEM_MENUSTART
,hAcc
, OBJID_CLIENT
,dChildID
);
210 case UM_EVENT_MENU_END
:
211 NotifyWinEvent( EVENT_SYSTEM_MENUEND
,hAcc
, OBJID_CLIENT
,dChildID
);
213 case UM_EVENT_MENUPOPUPSTART
:
214 NotifyWinEvent( EVENT_SYSTEM_MENUPOPUPSTART
,hAcc
, OBJID_CLIENT
,dChildID
);
216 case UM_EVENT_MENUPOPUPEND
:
217 NotifyWinEvent( EVENT_SYSTEM_MENUPOPUPEND
,hAcc
, OBJID_CLIENT
,dChildID
);
219 case UM_EVENT_SELECTION_CHANGED
:
220 NotifyWinEvent( EVENT_OBJECT_SELECTION
,hAcc
, OBJID_CLIENT
,dChildID
);
222 case UM_EVENT_SELECTION_CHANGED_ADD
:
223 NotifyWinEvent( EVENT_OBJECT_SELECTIONADD
,hAcc
, OBJID_CLIENT
,dChildID
);
225 case UM_EVENT_SELECTION_CHANGED_REMOVE
:
226 NotifyWinEvent( EVENT_OBJECT_SELECTIONREMOVE
,hAcc
, OBJID_CLIENT
,dChildID
);
228 case UM_EVENT_SELECTION_CHANGED_WITHIN
:
229 NotifyWinEvent( EVENT_OBJECT_SELECTIONWITHIN
,hAcc
, OBJID_CLIENT
,dChildID
);
231 case UM_EVENT_OBJECT_VALUECHANGE
:
233 NotifyWinEvent( EVENT_OBJECT_VALUECHANGE
,hAcc
, OBJID_CLIENT
,dChildID
);
235 case UM_EVENT_OBJECT_NAMECHANGE
:
236 NotifyWinEvent( EVENT_OBJECT_NAMECHANGE
,hAcc
, OBJID_CLIENT
,dChildID
);
238 case UM_EVENT_OBJECT_DESCRIPTIONCHANGE
:
239 NotifyWinEvent( EVENT_OBJECT_DESCRIPTIONCHANGE
,hAcc
, OBJID_CLIENT
,dChildID
);
241 case UM_EVENT_OBJECT_DEFACTIONCHANGE
:
242 NotifyWinEvent( IA2_EVENT_ACTION_CHANGED
,hAcc
, OBJID_CLIENT
,dChildID
);
244 case UM_EVENT_OBJECT_CARETCHANGE
:
245 NotifyWinEvent( IA2_EVENT_TEXT_CARET_MOVED
,hAcc
, OBJID_CLIENT
,dChildID
);
247 case UM_EVENT_OBJECT_TEXTCHANGE
:
248 NotifyWinEvent( IA2_EVENT_TEXT_CHANGED
,hAcc
, OBJID_CLIENT
,dChildID
);
250 case UM_EVENT_ACTIVE_DESCENDANT_CHANGED
:
251 UpdateAccFocus(pXAcc
);
252 NotifyWinEvent( EVENT_OBJECT_FOCUS
,hAcc
, OBJID_CLIENT
,dChildID
);
254 case UM_EVENT_BOUNDRECT_CHANGED
:
255 NotifyWinEvent( EVENT_OBJECT_LOCATIONCHANGE
,hAcc
, OBJID_CLIENT
,dChildID
);
257 case UM_EVENT_VISIBLE_DATA_CHANGED
:
258 NotifyWinEvent( IA2_EVENT_VISIBLE_DATA_CHANGED
,hAcc
, OBJID_CLIENT
,dChildID
);
261 NotifyWinEvent( EVENT_OBJECT_SHOW
,hAcc
, OBJID_CLIENT
,dChildID
);
262 NotifyWinEvent( EVENT_SYSTEM_FOREGROUND
,hAcc
, OBJID_CLIENT
,dChildID
);
264 case UM_EVENT_TABLE_CAPTION_CHANGED
:
265 NotifyWinEvent( IA2_EVENT_TABLE_CAPTION_CHANGED
,hAcc
, OBJID_CLIENT
,dChildID
);
267 case UM_EVENT_TABLE_COLUMN_DESCRIPTION_CHANGED
:
268 NotifyWinEvent( IA2_EVENT_TABLE_COLUMN_DESCRIPTION_CHANGED
,hAcc
, OBJID_CLIENT
,dChildID
);
270 case UM_EVENT_TABLE_COLUMN_HEADER_CHANGED
:
271 NotifyWinEvent( IA2_EVENT_TABLE_COLUMN_HEADER_CHANGED
,hAcc
, OBJID_CLIENT
,dChildID
);
273 case UM_EVENT_TABLE_MODEL_CHANGED
:
274 NotifyWinEvent( IA2_EVENT_TABLE_MODEL_CHANGED
,hAcc
, OBJID_CLIENT
,dChildID
);
276 case UM_EVENT_TABLE_ROW_HEADER_CHANGED
:
277 NotifyWinEvent( IA2_EVENT_TABLE_ROW_HEADER_CHANGED
,hAcc
, OBJID_CLIENT
,dChildID
);
279 case UM_EVENT_TABLE_SUMMARY_CHANGED
:
280 NotifyWinEvent( IA2_EVENT_TABLE_SUMMARY_CHANGED
,hAcc
, OBJID_CLIENT
,dChildID
);
282 case UM_EVENT_TABLE_ROW_DESCRIPTION_CHANGED
:
283 NotifyWinEvent( IA2_EVENT_TABLE_ROW_DESCRIPTION_CHANGED
,hAcc
, OBJID_CLIENT
,dChildID
);
285 case UM_EVENT_OBJECT_REORDER
:
286 NotifyWinEvent( EVENT_OBJECT_REORDER
,hAcc
, OBJID_CLIENT
,dChildID
);
288 case UM_EVENT_PAGE_CHANGED
:
289 NotifyWinEvent( IA2_EVENT_PAGE_CHANGED
,hAcc
, OBJID_CLIENT
,dChildID
);
291 case UM_EVENT_CHILD_REMOVED
:
292 NotifyWinEvent( EVENT_OBJECT_DESTROY
,hAcc
, OBJID_CLIENT
,dChildID
);
294 case UM_EVENT_CHILD_ADDED
:
295 NotifyWinEvent( EVENT_OBJECT_CREATE
,hAcc
, OBJID_CLIENT
,dChildID
);
297 case UM_EVENT_OBJECT_PAGECHANGED
:
298 NotifyWinEvent( IA2_EVENT_PAGE_CHANGED
,hAcc
, OBJID_CLIENT
,dChildID
);
300 case UM_EVENT_TEXT_SELECTION_CHANGED
:
301 NotifyWinEvent( IA2_EVENT_TEXT_SELECTION_CHANGED
,hAcc
, OBJID_CLIENT
,dChildID
);
303 case UM_EVENT_SECTION_CHANGED
:
304 NotifyWinEvent( IA2_EVENT_SECTION_CHANGED
,hAcc
, OBJID_CLIENT
,dChildID
);
306 case UM_EVENT_COLUMN_CHANGED
:
307 NotifyWinEvent( IA2_EVENT_TEXT_COLUMN_CHANGED
,hAcc
, OBJID_CLIENT
,dChildID
);
317 * Get Parent XAccessible interface by XAccessible interface.
318 * @param pXAcc XAccessible interface.
319 * @return Parent XAccessible interface.
321 XAccessible
* AccObjectWinManager::GetParentXAccessible( XAccessible
* pXAcc
)
323 AccObject
* pObj
= GetAccObjByXAcc(pXAcc
);
326 if(pObj
->GetParentObj())
328 pObj
= pObj
->GetParentObj();
329 return pObj
->GetXAccessible().get();
335 * Get Parent role by XAccessible interface.
336 * @param pXAcc XAccessible interface.
337 * @return Parent role.
339 short AccObjectWinManager::GetParentRole( XAccessible
* pXAcc
)
341 AccObject
* pObj
= GetAccObjByXAcc(pXAcc
);
344 if(pObj
->GetParentObj())
346 pObj
= pObj
->GetParentObj();
347 if(pObj
->GetXAccessible().is())
349 Reference
< XAccessibleContext
> pRContext
= pObj
->GetXAccessible()->getAccessibleContext();
351 return pRContext
->getAccessibleRole();
358 * Update focus object by new focused XAccessible interface.
359 * @param newFocus New XAccessible interface that gets focus.
362 void AccObjectWinManager::UpdateAccFocus(XAccessible
* newFocus
)
364 AccObject
* pAccObjNew
= GetAccObjByXAcc(newFocus
);
367 AccObject
* pAccObjOld
= GetAccObjByXAcc(oldFocus
);
369 pAccObjNew
->setFocus();
370 //if old == new, the pAccObjNew will be without focused state
371 if (pAccObjOld
&& pAccObjOld
!= pAccObjNew
)
372 pAccObjOld
->unsetFocus();
377 * Update selected object by new focused XAccessible interface.
378 * @param pXAcc XAccessible interface that has selected child changed.
379 * @return Selected children count.
381 int AccObjectWinManager::UpdateAccSelection(XAccessible
* pXAcc
)
383 Reference
< XAccessibleContext
> pRContext
;
385 if( pXAcc
== nullptr)
388 pRContext
= pXAcc
->getAccessibleContext();
389 if( !pRContext
.is() )
392 Reference
< XAccessibleSelection
> pRSelection(pRContext
,UNO_QUERY
);
393 if( !pRSelection
.is() )
396 AccObject
* pAccObj
= GetAccObjByXAcc(pXAcc
);
400 Reference
<XAccessible
> pRChild
;
401 AccObject
* pAccChildObj
= nullptr;
402 int selectNum
= pRSelection
->getSelectedAccessibleChildCount();
404 IAccSelectionList oldSelection
= pAccObj
->GetSelection();
406 if(selectNum
> 4)//for selected.
408 if(selectNum
== 1 && oldSelection
.size() == 0)
411 for (int i
=0;i
<selectNum
;i
++)
413 pRChild
= pRSelection
->getSelectedAccessibleChild(i
);
418 Reference
<XAccessibleContext
> pRChildContext
= pRChild
->getAccessibleContext();
419 if(!pRChildContext
.is())
423 long index
= pRChildContext
->getAccessibleIndexInParent();
424 IAccSelectionList::iterator temp
= oldSelection
.find(index
);
425 if ( temp
!= oldSelection
.end() )
427 oldSelection
.erase(index
);
431 pAccChildObj
= GetAccObjByXAcc(pRChild
.get());
434 InsertAccObj(pRChild
.get(), pXAcc
,pAccObj
->GetParentHWND());
435 pAccChildObj
= GetAccObjByXAcc(pRChild
.get());
438 pAccObj
->AddSelect(index
, pAccChildObj
);
440 if(pAccChildObj
!= nullptr)
441 NotifyWinEvent(EVENT_OBJECT_SELECTIONADD
,pAccObj
->GetParentHWND(), OBJID_CLIENT
,pAccChildObj
->GetResID());
444 for (const auto& rEntry
: oldSelection
)
446 pAccObj
->GetSelection().erase(rEntry
.first
);
447 pAccChildObj
= rEntry
.second
;
448 if(pAccChildObj
!= nullptr)
449 NotifyWinEvent(EVENT_OBJECT_SELECTIONREMOVE
,pAccObj
->GetParentHWND(), OBJID_CLIENT
,pAccChildObj
->GetResID());
456 * Delete child element from children list.
457 * @param pObj Child element that should be removed from parent child list.
460 void AccObjectWinManager::DeleteAccChildNode( AccObject
* pObj
)
462 AccObject
*parentAccObj
= pObj
->GetParentObj();
464 parentAccObj
->DeleteChild( pObj
);
468 * Delete XAccessible items in top window handle hashtable
469 * @param pXAcc XAccessible interface.
472 void AccObjectWinManager::DeleteFromHwndXAcc(XAccessible
const * pXAcc
)
474 auto iter
= std::find_if(HwndXAcc
.begin(), HwndXAcc
.end(),
475 [&pXAcc
](XHWNDToXAccHash::value_type
& rEntry
) { return rEntry
.second
== pXAcc
; });
476 if (iter
!= HwndXAcc
.end())
477 HwndXAcc
.erase(iter
);
481 * Delete all children with the tree root of XAccessible pointer
482 * @param pXAcc Tree root XAccessible interface.
485 void AccObjectWinManager::DeleteChildrenAccObj(XAccessible
* pXAcc
)
487 AccObject
* currentObj
=nullptr;
488 AccObject
* childObj
=nullptr;
490 currentObj
= GetAccObjByXAcc( pXAcc
);
493 childObj
= currentObj
->NextChild();
496 XAccessible
*const pTmpXAcc
= childObj
->GetXAccessible().get();
499 DeleteChildrenAccObj(pTmpXAcc
);
500 DeleteAccObj(pTmpXAcc
);
502 childObj
= currentObj
->NextChild();
508 * Delete Acc object self.
509 * @param pXAcc The XAccessible interface.
512 void AccObjectWinManager::DeleteAccObj( XAccessible
* pXAcc
)
514 if( pXAcc
== nullptr )
516 XIdToAccObjHash::iterator temp
= XIdAccList
.find(pXAcc
);
517 if( temp
!= XIdAccList
.end() )
519 ResIdGen
.SetSub( temp
->second
.GetResID() );
526 AccObject
& accObj
= temp
->second
;
527 DeleteAccChildNode( &accObj
);
528 DeleteAccListener( &accObj
);
529 if( accObj
.GetIMAccessible() )
531 accObj
.GetIMAccessible()->Release();
533 size_t i
= XResIdAccList
.erase(accObj
.GetResID());
535 DeleteFromHwndXAcc(pXAcc
);
536 if( accObj
.GetRole() == DOCUMENT
||
537 accObj
.GetRole() == DOCUMENT_PRESENTATION
||
538 accObj
.GetRole() == DOCUMENT_SPREADSHEET
||
539 accObj
.GetRole() == DOCUMENT_TEXT
)
541 XHWNDDocList
.erase(accObj
.GetParentHWND());
543 XIdAccList
.erase(pXAcc
); // note: this invalidates accObj so do it last!
547 * Delete listener that inspects some XAccessible object
548 * @param pAccObj Accobject pointer.
551 void AccObjectWinManager::DeleteAccListener( AccObject
* pAccObj
)
553 AccEventListener
* listener
= pAccObj
->getListener();
554 if( listener
==nullptr )
556 listener
->RemoveMeFromBroadcaster();
557 pAccObj
->SetListener(nullptr);
561 * Generate a child ID, which is used for AT
563 * @return New resource ID.
565 inline long AccObjectWinManager::ImpleGenerateResID()
567 return ResIdGen
.GenerateNewResID();
571 * Insert all children of the current acc object
572 * @param pXAcc XAccessible interface
573 * @param pWnd Top Window handle
574 * @return The calling result.
576 bool AccObjectWinManager::InsertChildrenAccObj( css::accessibility::XAccessible
* pXAcc
,
579 if(!IsContainer(pXAcc
))
582 Reference
< XAccessibleContext
> pRContext
;
584 if( pXAcc
== nullptr)
586 pRContext
= pXAcc
->getAccessibleContext();
587 if( !pRContext
.is() )
590 short role
= pRContext
->getAccessibleRole();
592 if(css::accessibility::AccessibleRole::DOCUMENT
== role
||
593 css::accessibility::AccessibleRole::DOCUMENT_PRESENTATION
== role
||
594 css::accessibility::AccessibleRole::DOCUMENT_SPREADSHEET
== role
||
595 css::accessibility::AccessibleRole::DOCUMENT_TEXT
== role
)
597 if(IsStateManageDescendant(pXAcc
))
603 int count
= pRContext
->getAccessibleChildCount();
604 for (int i
=0;i
<count
;i
++)
606 Reference
<XAccessible
> mxAccessible
607 = pRContext
->getAccessibleChild(i
);
608 XAccessible
* mpAccessible
= mxAccessible
.get();
609 if(mpAccessible
!= nullptr)
611 InsertAccObj( mpAccessible
,pXAcc
,pWnd
);
612 InsertChildrenAccObj(mpAccessible
,pWnd
);
620 * Insert child object.
621 * @param pCurObj The child object
622 * @param pParentObj The parent object
623 * @param pWnd Top window handle.
626 void AccObjectWinManager::InsertAccChildNode( AccObject
* pCurObj
, AccObject
* pParentObj
, HWND
/* pWnd */ )
632 pParentObj
->InsertChild(pCurObj
);
636 pCurObj
->UpdateValidWindow();
642 * Insert child object.
643 * @param pCurObj The child object
644 * @param pParentObj The parent object
645 * @param pWnd Top window handle.
648 bool AccObjectWinManager::InsertAccObj( XAccessible
* pXAcc
,XAccessible
* pParentXAcc
,HWND pWnd
)
650 XIdToAccObjHash::iterator itXacc
= XIdAccList
.find( pXAcc
);
651 if (itXacc
!= XIdAccList
.end() )
653 short nCurRole
=GetRole(pXAcc
);
654 if (AccessibleRole::SHAPE
== nCurRole
)
656 AccObject
&objXacc
= itXacc
->second
;
657 AccObject
*pObjParent
= objXacc
.GetParentObj();
659 pObjParent
->GetXAccessible().is() &&
660 pObjParent
->GetXAccessible().get() != pParentXAcc
)
662 XIdToAccObjHash::iterator itXaccParent
= XIdAccList
.find( pParentXAcc
);
663 if(itXaccParent
!= XIdAccList
.end())
665 objXacc
.SetParentObj(&(itXaccParent
->second
));
673 Reference
< XAccessibleContext
> pRContext
;
675 if( pXAcc
== nullptr)
678 pRContext
= pXAcc
->getAccessibleContext();
679 if( !pRContext
.is() )
682 if( pWnd
== nullptr )
686 AccObject
* pObj
= GetAccObjByXAcc(pParentXAcc
);
688 pWnd
= pObj
->GetParentHWND();
690 if( pWnd
== nullptr )
694 AccObject
pObj( pXAcc
,pAgent
);
695 if( pObj
.GetIMAccessible() == nullptr )
697 pObj
.SetResID( this->ImpleGenerateResID());
698 pObj
.SetParentHWND( pWnd
);
700 //for file name support
701 if( pObj
.GetRole() == DOCUMENT
||
702 pObj
.GetRole() == DOCUMENT_PRESENTATION
||
703 pObj
.GetRole() == DOCUMENT_SPREADSHEET
||
704 pObj
.GetRole() == DOCUMENT_TEXT
)
706 XHWNDToDocumentHash::iterator aIter
= XHWNDDocList
.find(pWnd
);
707 if ( aIter
!= XHWNDDocList
.end() )
709 XHWNDDocList
.erase( aIter
);
711 XHWNDDocList
.emplace( pWnd
, pXAcc
);
715 ::rtl::Reference
<AccEventListener
> const pListener
=
716 CreateAccEventListener(pXAcc
);
719 Reference
<XAccessibleComponent
> xComponent(pRContext
,UNO_QUERY
);
720 Reference
<XAccessibleEventBroadcaster
> broadcaster(xComponent
,UNO_QUERY
);
721 if (broadcaster
.is())
723 Reference
<XAccessibleEventListener
> const xListener(pListener
.get());
724 broadcaster
->addAccessibleEventListener(xListener
);
729 XIdAccList
.emplace(pXAcc
, pObj
);
730 XIdToAccObjHash::iterator pIndTemp
= XIdAccList
.find( pXAcc
);
731 XResIdAccList
.emplace(pObj
.GetResID(),&(pIndTemp
->second
));
733 AccObject
* pCurObj
= GetAccObjByXAcc(pXAcc
);
736 pCurObj
->SetListener(pListener
);
739 AccObject
* pParentObj
= GetAccObjByXAcc(pParentXAcc
);
740 InsertAccChildNode(pCurObj
,pParentObj
,pWnd
);
742 pCurObj
->UpdateAccessibleInfoFromUnoToMSAA();
748 * save the pair <topwindowhandle, XAccessible>
749 * @param hWnd, top window handle
750 * @param pXAcc XAccessible interface for top window
753 void AccObjectWinManager::SaveTopWindowHandle(HWND hWnd
, css::accessibility::XAccessible
* pXAcc
)
755 HwndXAcc
.emplace(hWnd
,pXAcc
);
759 /** Create the corresponding listener.
760 * @param pXAcc XAccessible interface.
762 ::rtl::Reference
<AccEventListener
>
763 AccObjectWinManager::CreateAccEventListener(XAccessible
* pXAcc
)
765 ::rtl::Reference
<AccEventListener
> pRet
;
766 Reference
<XAccessibleContext
> xContext
= pXAcc
->getAccessibleContext();
769 switch( xContext
->getAccessibleRole() )
771 case /*AccessibleRole::*/DIALOG
:
772 pRet
= new AccDialogEventListener(pXAcc
,pAgent
);
774 case /*AccessibleRole::*/FRAME
:
775 pRet
= new AccFrameEventListener(pXAcc
,pAgent
);
777 case /*AccessibleRole::*/WINDOW
:
778 pRet
= new AccWindowEventListener(pXAcc
,pAgent
);
780 case /*AccessibleRole::*/ROOT_PANE
:
781 pRet
= new AccFrameEventListener(pXAcc
,pAgent
);
784 case /*AccessibleRole::*/CANVAS
:
785 case /*AccessibleRole::*/COMBO_BOX
:
786 case /*AccessibleRole::*/DOCUMENT
:
787 case /*AccessibleRole::*/DOCUMENT_PRESENTATION
:
788 case /*AccessibleRole::*/DOCUMENT_SPREADSHEET
:
789 case /*AccessibleRole::*/DOCUMENT_TEXT
:
790 case /*AccessibleRole::*/END_NOTE
:
791 case /*AccessibleRole::*/FILLER
:
792 case /*AccessibleRole::*/FOOTNOTE
:
793 case /*AccessibleRole::*/FOOTER
:
794 case /*AccessibleRole::*/HEADER
:
795 case /*AccessibleRole::*/LAYERED_PANE
:
796 case /*AccessibleRole::*/MENU_BAR
:
797 case /*AccessibleRole::*/POPUP_MENU
:
798 case /*AccessibleRole::*/OPTION_PANE
:
799 case /*AccessibleRole::*/PAGE_TAB
:
800 case /*AccessibleRole::*/PAGE_TAB_LIST
:
801 case /*AccessibleRole::*/PANEL
:
802 case /*AccessibleRole::*/SCROLL_PANE
:
803 case /*AccessibleRole::*/SPLIT_PANE
:
804 case /*AccessibleRole::*/STATUS_BAR
:
805 case /*AccessibleRole::*/TABLE_CELL
:
806 case /*AccessibleRole::*/TOOL_BAR
:
807 case /*AccessibleRole::*/VIEW_PORT
:
808 pRet
= new AccContainerEventListener(pXAcc
,pAgent
);
810 case /*AccessibleRole::*/PARAGRAPH
:
811 case /*AccessibleRole::*/HEADING
:
812 pRet
= new AccParagraphEventListener(pXAcc
,pAgent
);
815 case /*AccessibleRole::*/CHECK_BOX
:
816 case /*AccessibleRole::*/ICON
:
817 case /*AccessibleRole::*/LABEL
:
818 case /*AccessibleRole::*/STATIC
:
819 case /*AccessibleRole::*/MENU_ITEM
:
820 case /*AccessibleRole::*/CHECK_MENU_ITEM
:
821 case /*AccessibleRole::*/RADIO_MENU_ITEM
:
822 case /*AccessibleRole::*/PUSH_BUTTON
:
823 case /*AccessibleRole::*/RADIO_BUTTON
:
824 case /*AccessibleRole::*/SCROLL_BAR
:
825 case /*AccessibleRole::*/SEPARATOR
:
826 case /*AccessibleRole::*/TOGGLE_BUTTON
:
827 case /*AccessibleRole::*/BUTTON_DROPDOWN
:
828 case /*AccessibleRole::*/TOOL_TIP
:
829 case /*AccessibleRole::*/SPIN_BOX
:
831 pRet
= new AccComponentEventListener(pXAcc
,pAgent
);
834 case /*AccessibleRole::*/TEXT
:
835 pRet
= new AccTextComponentEventListener(pXAcc
,pAgent
);
838 case /*AccessibleRole::*/MENU
:
839 pRet
= new AccMenuEventListener(pXAcc
,pAgent
);
842 case /*AccessibleRole::*/SHAPE
:
844 case /*AccessibleRole::*/EMBEDDED_OBJECT
:
845 case /*AccessibleRole::*/GRAPHIC
:
846 case /*AccessibleRole::*/TEXT_FRAME
:
847 pRet
= new AccObjectContainerEventListener(pXAcc
,pAgent
);
850 case /*AccessibleRole::*/LIST
:
851 pRet
= new AccListEventListener(pXAcc
,pAgent
);
853 case /*AccessibleRole::*/TREE
:
854 pRet
= new AccTreeEventListener(pXAcc
,pAgent
);
857 case /*AccessibleRole::*/COLUMN_HEADER
:
858 case /*AccessibleRole::*/TABLE
:
859 pRet
= new AccTableEventListener(pXAcc
,pAgent
);
862 pRet
= new AccContainerEventListener(pXAcc
,pAgent
);
870 * state is a combination integer, each bit of which represents a single state,
871 * such as focused,1 for the state on,0 for the state off. Here call COM interface
872 * to modify the state value, including DecreaseState.
873 * @param pXAcc XAccessible interface.
874 * @param pState Changed state.
877 void AccObjectWinManager::DecreaseState( XAccessible
* pXAcc
,unsigned short pState
)
879 AccObject
* pAccObj
= GetAccObjByXAcc( pXAcc
);
881 pAccObj
->DecreaseState( pState
);
885 * state is a combination integer, each bit of which represents a single state,such as focused,1 for
886 * the state on,0 for the state off. Here call COM interface to modify the state value, including
888 * @param pXAcc XAccessible interface.
889 * @param pState Changed state.
892 void AccObjectWinManager::IncreaseState( XAccessible
* pXAcc
,unsigned short pState
)
894 AccObject
* pAccObj
= GetAccObjByXAcc( pXAcc
);
896 pAccObj
->IncreaseState( pState
);
899 void AccObjectWinManager::UpdateState( css::accessibility::XAccessible
* pXAcc
)
901 AccObject
* pAccObj
= GetAccObjByXAcc( pXAcc
);
903 pAccObj
->UpdateState( );
907 * Set corresponding com object's accessible name via XAccessible interface and new
909 * @param pXAcc XAccessible interface.
912 void AccObjectWinManager::UpdateAccName( XAccessible
* pXAcc
)
914 AccObject
* pAccObj
= GetAccObjByXAcc( pXAcc
);
916 pAccObj
->UpdateName();
919 void AccObjectWinManager::UpdateAction( XAccessible
* pXAcc
)
921 AccObject
* pAccObj
= GetAccObjByXAcc( pXAcc
);
923 pAccObj
->UpdateAction();
926 void AccObjectWinManager::UpdateDescription( XAccessible
* pXAcc
)
928 AccObject
* pAccObj
= GetAccObjByXAcc( pXAcc
);
930 pAccObj
->UpdateDescription();
934 * Set corresponding com object's accessible location via XAccessible interface and new
936 * @param pXAcc XAccessible interface.
939 void AccObjectWinManager::SetLocation( XAccessible
* pXAcc
, long /*top*/, long /*left*/, long /*width*/, long /*height*/ )
941 AccObject
* pObj
= GetAccObjByXAcc( pXAcc
);
942 //get the location from XComponent.
943 Reference
< XAccessibleContext
> pRContext
= pXAcc
->getAccessibleContext();
945 pObj
->UpdateLocation();
949 * Set corresponding com object's value via XAccessible interface and new value.
950 * @param pXAcc XAccessible interface.
951 * @param pAny new value.
954 void AccObjectWinManager::SetValue( XAccessible
* pXAcc
, Any pAny
)
956 AccObject
* pAccObj
= GetAccObjByXAcc( pXAcc
);
958 pAccObj
->SetValue( pAny
);
962 * Set corresponding com object's value via XAccessible interface.
963 * @param pXAcc XAccessible interface.
966 void AccObjectWinManager::UpdateValue( XAccessible
* pXAcc
)
968 AccObject
* pAccObj
= GetAccObjByXAcc( pXAcc
);
970 pAccObj
->UpdateValue();
974 * Set corresponding com object's name via XAccessible interface and new name.
975 * @param pXAcc XAccessible interface.
976 * @param newName new name
979 void AccObjectWinManager::SetAccName( XAccessible
* pXAcc
, Any newName
)
981 AccObject
* pAccObj
= GetAccObjByXAcc( pXAcc
);
983 pAccObj
->SetName( newName
);
987 * Set corresponding com object's description via XAccessible interface and new description.
988 * @param pXAcc XAccessible interface.
989 * @param newDesc new description
992 void AccObjectWinManager::SetDescription( XAccessible
* pXAcc
, Any newDesc
)
994 AccObject
* pAccObj
= GetAccObjByXAcc( pXAcc
);
996 pAccObj
->SetDescription( newDesc
);
1000 * Set corresponding com object's role via XAccessible interface and new role.
1001 * @param pXAcc XAccessible interface.
1002 * @param Role new role
1005 void AccObjectWinManager::SetRole( XAccessible
* pXAcc
, long Role
)
1007 AccObject
* pAccObj
= GetAccObjByXAcc( pXAcc
);
1009 pAccObj
->SetRole( static_cast<short>(Role
) );
1013 * Judge if a XAccessible object is a container object.
1014 * @param pAccessible XAccessible interface.
1015 * @return If XAccessible object is container.
1017 bool AccObjectWinManager::IsContainer(XAccessible
* pAccessible
)
1023 Reference
<XAccessibleContext
> xContext
= pAccessible
->getAccessibleContext();
1026 switch( xContext
->getAccessibleRole() )
1028 case /*AccessibleRole::*/DIALOG
:
1029 case /*AccessibleRole::*/FRAME
:
1030 case /*AccessibleRole::*/WINDOW
:
1031 case /*AccessibleRole::*/ROOT_PANE
:
1032 case /*AccessibleRole::*/CANVAS
:
1033 case /*AccessibleRole::*/COMBO_BOX
:
1034 case /*AccessibleRole::*/DOCUMENT
:
1035 case /*AccessibleRole::*/DOCUMENT_PRESENTATION
:
1036 case /*AccessibleRole::*/DOCUMENT_SPREADSHEET
:
1037 case /*AccessibleRole::*/DOCUMENT_TEXT
:
1038 case /*AccessibleRole::*/EMBEDDED_OBJECT
:
1039 case /*AccessibleRole::*/END_NOTE
:
1040 case /*AccessibleRole::*/FILLER
:
1041 case /*AccessibleRole::*/FOOTNOTE
:
1042 case /*AccessibleRole::*/FOOTER
:
1043 case /*AccessibleRole::*/GRAPHIC
:
1044 case /*AccessibleRole::*/GROUP_BOX
:
1045 case /*AccessibleRole::*/HEADER
:
1046 case /*AccessibleRole::*/LAYERED_PANE
:
1047 case /*AccessibleRole::*/MENU_BAR
:
1048 case /*AccessibleRole::*/POPUP_MENU
:
1049 case /*AccessibleRole::*/OPTION_PANE
:
1050 case /*AccessibleRole::*/PAGE_TAB
:
1051 case /*AccessibleRole::*/PAGE_TAB_LIST
:
1052 case /*AccessibleRole::*/PANEL
:
1053 case /*AccessibleRole::*/SCROLL_PANE
:
1054 case /*AccessibleRole::*/SPLIT_PANE
:
1055 case /*AccessibleRole::*/STATUS_BAR
:
1056 case /*AccessibleRole::*/TABLE_CELL
:
1057 case /*AccessibleRole::*/TEXT_FRAME
:
1058 case /*AccessibleRole::*/TOOL_BAR
:
1059 case /*AccessibleRole::*/VIEW_PORT
:
1060 case /*AccessibleRole::*/SHAPE
:
1063 case /*AccessibleRole::*/COLUMN_HEADER
:
1064 case /*AccessibleRole::*/TABLE
:
1065 if(!IsStateManageDescendant(pAccessible
))
1068 case /*AccessibleRole::*/MENU
:
1085 * Judge if a XAccessible object has ManageDescendant event.
1086 * @param pAccessible XAccessible interface.
1087 * @return If XAccessible object is managedescendant.
1089 bool AccObjectWinManager::IsStateManageDescendant(XAccessible
* pAccessible
)
1093 Reference
<XAccessibleContext
> xContext
= pAccessible
->getAccessibleContext();
1096 Reference
< XAccessibleStateSet
> pRState
= xContext
->getAccessibleStateSet();
1100 Sequence
<short> pStates
= pRState
->getStates();
1101 int count
= pStates
.getLength();
1102 for( int iIndex
= 0;iIndex
< count
;iIndex
++ )
1104 if(pStates
[iIndex
] == /*AccessibleStateType::*/MANAGES_DESCENDANTS
)
1113 * Query and get IAccessible interface by XAccessible interface from list.
1114 * @param pXAcc XAccessible interface.
1115 * @return Com accobject interface.
1117 IMAccessible
* AccObjectWinManager::GetIMAccByXAcc(XAccessible
* pXAcc
)
1119 AccObject
* pAccObj
= GetAccObjByXAcc(pXAcc
);
1122 return pAccObj
->GetIMAccessible();
1131 * Query and get IAccessible interface by child id from list.
1132 * @param resID, childID.
1133 * @return Com accobject interface.
1135 IMAccessible
* AccObjectWinManager::GetIAccessibleFromResID(long resID
)
1137 XResIdToAccObjHash::iterator pIndTemp
= XResIdAccList
.find( resID
);
1138 if ( pIndTemp
== XResIdAccList
.end() )
1141 AccObject
* pObj
= pIndTemp
->second
;
1143 if(pObj
->GetIMAccessible())
1144 return pObj
->GetIMAccessible();
1148 * Notify some object will be destroyed.
1149 * @param pXAcc XAccessible interface.
1150 * @return Com accobject interface.
1152 void AccObjectWinManager::NotifyDestroy(XAccessible
* pXAcc
)
1154 AccObject
* accObj
= GetAccObjByXAcc(pXAcc
);
1157 accObj
->NotifyDestroy(true);
1162 void AccObjectWinManager::UpdateChildState(css::accessibility::XAccessible
* pAccSubMenu
)
1164 Reference
<css::accessibility::XAccessibleContext
> xContext(pAccSubMenu
,UNO_QUERY
);
1169 sal_Int32 nCount
= xContext
->getAccessibleChildCount();
1170 for (sal_Int32 i
= 0 ; i
< nCount
; ++i
)
1172 Reference
<css::accessibility::XAccessible
> xChild
= xContext
->getAccessibleChild(i
);
1175 AccObject
*pObj
= GetAccObjByXAcc(xChild
.get());
1178 pObj
->UpdateState();
1185 bool AccObjectWinManager::IsSpecialToolboItem(css::accessibility::XAccessible
* pXAcc
)
1187 if (pXAcc
&& oldFocus
!= pXAcc
)
1189 if(GetParentRole(pXAcc
) == TOOL_BAR
)
1191 Reference
< XAccessibleContext
> pRContext(pXAcc
->getAccessibleContext());
1194 if(pRContext
->getAccessibleRole() == TOGGLE_BUTTON
)
1204 short AccObjectWinManager::GetRole(css::accessibility::XAccessible
* pXAcc
)
1206 assert(pXAcc
!= nullptr);
1207 Reference
<css::accessibility::XAccessibleContext
> xContext
= pXAcc
->getAccessibleContext();
1210 return xContext
->getAccessibleRole();
1215 XAccessible
* AccObjectWinManager::GetAccDocByHWND(HWND pWnd
)
1217 XHWNDToDocumentHash::iterator aIter
;
1218 aIter
= XHWNDDocList
.find( pWnd
);
1219 if ( aIter
!= XHWNDDocList
.end() )
1221 return aIter
->second
;
1227 XAccessible
* AccObjectWinManager::GetAccDocByAccTopWin( XAccessible
* pXAcc
)
1229 AccObject
* pAccObj
= GetAccObjByXAcc( pXAcc
);
1230 HWND hWnd
= pAccObj
->GetParentHWND();
1231 return GetAccDocByHWND(hWnd
);
1234 bool AccObjectWinManager::IsTopWinAcc( css::accessibility::XAccessible
* pXAcc
)
1237 AccObject
* pAccObj
= GetAccObjByXAcc( pXAcc
);
1240 bRet
= ( pAccObj
->GetParentObj() == nullptr );
1244 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */