LibreOffice Module winaccessibility (master) 1
AccObjectWinManager.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20#include <cassert>
21
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>
28
29#include <oleacc.h>
31#include <AccEventListener.hxx>
44#include <AccObject.hxx>
45#include <unomsaaevent.hxx>
46
47
48using namespace com::sun::star::accessibility;
49using namespace com::sun::star::uno;
50
64 oldFocus( nullptr ),
65 pAgent( Agent )
66{
67}
68
75{
76 {
77 std::scoped_lock l(m_Mutex);
78
79 XIdAccList.clear();
80 HwndXAcc.clear();
81 }
82 XResIdAccList.clear();
83 XHWNDDocList.clear();
84}
85
86
94LRESULT
95AccObjectWinManager::Get_ToATInterface(HWND hWnd, long lParam, WPARAM wParam)
96{
97 IMAccessible* pRetIMAcc = nullptr;
98
99 if(lParam == OBJID_CLIENT )
100 {
101 pRetIMAcc = GetTopWindowIMAccessible(hWnd);
102 }
103
104 if ( pRetIMAcc && lParam == OBJID_CLIENT )
105 {
106 LRESULT result = LresultFromObject(IID_IAccessible, wParam, pRetIMAcc);
107 pRetIMAcc->Release();
108 return result;
109 }
110 return 0;
111}
112
119{
120 if( pXAcc == nullptr)
121 return nullptr;
122
123 std::scoped_lock l(m_Mutex);
124
125 XIdToAccObjHash::iterator pIndTemp = XIdAccList.find( pXAcc );
126 if ( pIndTemp == XIdAccList.end() )
127 return nullptr;
128
129 return &(pIndTemp->second);
130}
131
138{
139 std::scoped_lock l(m_Mutex); // tdf#155794 for HwndXAcc and XIdAccList
140
141 XHWNDToXAccHash::iterator iterResult =HwndXAcc.find(hWnd);
142 if(iterResult == HwndXAcc.end())
143 return nullptr;
144 XAccessible* pXAcc = iterResult->second;
145 AccObject *const pAccObject(GetAccObjByXAcc(pXAcc));
146 if (!pAccObject)
147 {
148 return nullptr;
149 }
150 IMAccessible *const pRet(pAccObject->GetIMAccessible());
151 if (!pRet)
152 {
153 return nullptr;
154 }
155 pRet->AddRef();
156 return pRet;
157}
158
165bool AccObjectWinManager::NotifyAccEvent(XAccessible* pXAcc, UnoMSAAEvent eEvent)
166{
168
169 if( pXAcc == nullptr)
170 return false;
171
172
173 pRContext = pXAcc->getAccessibleContext();
174 if( !pRContext.is() )
175 return false;
176
177
178 AccObject* selfAccObj= GetAccObjByXAcc(pXAcc);
179
180 if(selfAccObj==nullptr)
181 return false;
182
183 long dChildID = selfAccObj->GetResID();
184 HWND hAcc = selfAccObj->GetParentHWND();
185
186 switch(eEvent)
187 {
189 {
190 UpdateAccFocus(pXAcc);
191 selfAccObj->UpdateDefaultAction( );
192 UpdateValue(pXAcc);
193 NotifyWinEvent( EVENT_OBJECT_FOCUS,hAcc, OBJID_CLIENT,dChildID );
194 break;
195 }
197 NotifyWinEvent( EVENT_OBJECT_STATECHANGE,hAcc, OBJID_CLIENT,dChildID );
198 break;
200 NotifyWinEvent( EVENT_OBJECT_STATECHANGE,hAcc, OBJID_CLIENT,dChildID );
201 break;
203 NotifyWinEvent( EVENT_OBJECT_STATECHANGE,hAcc, OBJID_CLIENT,dChildID );
204 break;
205
206 //Removed fire out selected event
207 //case UnoMSAAEvent::STATE_SELECTED:
208 // NotifyWinEvent( EVENT_OBJECT_STATECHANGE,hAcc, OBJID_CLIENT,dChildID );
209 // break;
211 UpdateAccFocus(pXAcc);
212 NotifyWinEvent( EVENT_OBJECT_FOCUS,hAcc, OBJID_CLIENT,dChildID );
213 break;
215 // send EVENT_SYSTEM_ALERT when notification gets shown
216 if (pRContext->getAccessibleRole() == AccessibleRole::NOTIFICATION)
217 NotifyWinEvent(EVENT_SYSTEM_ALERT, hAcc, OBJID_CLIENT, dChildID);
218 break;
220 NotifyWinEvent( EVENT_SYSTEM_MENUSTART,hAcc, OBJID_CLIENT,dChildID );
221 break;
223 NotifyWinEvent( EVENT_SYSTEM_MENUEND,hAcc, OBJID_CLIENT,dChildID );
224 break;
226 NotifyWinEvent( EVENT_SYSTEM_MENUPOPUPSTART,hAcc, OBJID_CLIENT,dChildID );
227 break;
229 NotifyWinEvent( EVENT_SYSTEM_MENUPOPUPEND,hAcc, OBJID_CLIENT,dChildID );
230 break;
232 NotifyWinEvent( EVENT_OBJECT_SELECTION,hAcc, OBJID_CLIENT,dChildID );
233 break;
235 NotifyWinEvent( EVENT_OBJECT_SELECTIONADD,hAcc, OBJID_CLIENT,dChildID );
236 break;
238 NotifyWinEvent( EVENT_OBJECT_SELECTIONREMOVE,hAcc, OBJID_CLIENT,dChildID );
239 break;
241 NotifyWinEvent( EVENT_OBJECT_SELECTIONWITHIN,hAcc, OBJID_CLIENT,dChildID );
242 break;
244 UpdateValue(pXAcc);
245 NotifyWinEvent( EVENT_OBJECT_VALUECHANGE,hAcc, OBJID_CLIENT,dChildID );
246 break;
248 NotifyWinEvent( EVENT_OBJECT_NAMECHANGE,hAcc, OBJID_CLIENT,dChildID );
249 break;
251 NotifyWinEvent( EVENT_OBJECT_DESCRIPTIONCHANGE,hAcc, OBJID_CLIENT,dChildID );
252 break;
254 NotifyWinEvent( IA2_EVENT_ACTION_CHANGED,hAcc, OBJID_CLIENT,dChildID );
255 break;
257 NotifyWinEvent( IA2_EVENT_TEXT_CARET_MOVED,hAcc, OBJID_CLIENT,dChildID );
258 break;
260 NotifyWinEvent( IA2_EVENT_TEXT_CHANGED,hAcc, OBJID_CLIENT,dChildID );
261 break;
263 UpdateAccFocus(pXAcc);
264 NotifyWinEvent( EVENT_OBJECT_FOCUS,hAcc, OBJID_CLIENT,dChildID );
265 break;
267 NotifyWinEvent( EVENT_OBJECT_LOCATIONCHANGE,hAcc, OBJID_CLIENT,dChildID );
268 break;
270 NotifyWinEvent( IA2_EVENT_VISIBLE_DATA_CHANGED,hAcc, OBJID_CLIENT,dChildID );
271 break;
272 case UnoMSAAEvent::SHOW :
273 NotifyWinEvent( EVENT_OBJECT_SHOW,hAcc, OBJID_CLIENT,dChildID );
274 NotifyWinEvent( EVENT_SYSTEM_FOREGROUND,hAcc, OBJID_CLIENT,dChildID );
275 break;
277 NotifyWinEvent( IA2_EVENT_TABLE_CAPTION_CHANGED,hAcc, OBJID_CLIENT,dChildID );
278 break;
280 NotifyWinEvent( IA2_EVENT_TABLE_COLUMN_DESCRIPTION_CHANGED,hAcc, OBJID_CLIENT,dChildID );
281 break;
283 NotifyWinEvent( IA2_EVENT_TABLE_COLUMN_HEADER_CHANGED,hAcc, OBJID_CLIENT,dChildID );
284 break;
286 NotifyWinEvent( IA2_EVENT_TABLE_MODEL_CHANGED,hAcc, OBJID_CLIENT,dChildID );
287 break;
289 NotifyWinEvent( IA2_EVENT_TABLE_ROW_HEADER_CHANGED,hAcc, OBJID_CLIENT,dChildID );
290 break;
292 NotifyWinEvent( IA2_EVENT_TABLE_SUMMARY_CHANGED,hAcc, OBJID_CLIENT,dChildID );
293 break;
295 NotifyWinEvent( IA2_EVENT_TABLE_ROW_DESCRIPTION_CHANGED,hAcc, OBJID_CLIENT,dChildID );
296 break;
298 NotifyWinEvent( EVENT_OBJECT_REORDER,hAcc, OBJID_CLIENT,dChildID );
299 break;
301 NotifyWinEvent( IA2_EVENT_PAGE_CHANGED,hAcc, OBJID_CLIENT,dChildID );
302 break;
304 NotifyWinEvent( EVENT_OBJECT_DESTROY,hAcc, OBJID_CLIENT,dChildID );
305 break;
307 NotifyWinEvent( EVENT_OBJECT_CREATE ,hAcc, OBJID_CLIENT,dChildID );
308 break;
310 NotifyWinEvent( IA2_EVENT_PAGE_CHANGED ,hAcc, OBJID_CLIENT,dChildID );
311 break;
313 NotifyWinEvent( IA2_EVENT_TEXT_SELECTION_CHANGED ,hAcc, OBJID_CLIENT,dChildID );
314 break;
316 NotifyWinEvent( IA2_EVENT_SECTION_CHANGED ,hAcc, OBJID_CLIENT,dChildID );
317 break;
319 NotifyWinEvent( IA2_EVENT_TEXT_COLUMN_CHANGED ,hAcc, OBJID_CLIENT,dChildID );
320 break;
321 default:
322 break;
323 }
324
325 return true;
326}
327
333XAccessible* AccObjectWinManager::GetParentXAccessible( XAccessible* pXAcc )
334{
335 AccObject* pObj= GetAccObjByXAcc(pXAcc);
336 if( pObj ==nullptr )
337 return nullptr;
338 if(pObj->GetParentObj())
339 {
340 pObj = pObj->GetParentObj();
341 return pObj->GetXAccessible().get();
342 }
343 return nullptr;
344}
345
351short AccObjectWinManager::GetParentRole( XAccessible* pXAcc )
352{
353 AccObject* pObj= GetAccObjByXAcc(pXAcc);
354 if( pObj ==nullptr )
355 return -1;
356 if(pObj->GetParentObj())
357 {
358 pObj = pObj->GetParentObj();
359 if(pObj->GetXAccessible().is())
360 {
361 Reference< XAccessibleContext > pRContext = pObj->GetXAccessible()->getAccessibleContext();
362 if(pRContext.is())
363 return pRContext->getAccessibleRole();
364 }
365 }
366 return -1;
367}
368
374void AccObjectWinManager::UpdateAccFocus(XAccessible* newFocus)
375{
376 AccObject* pAccObjNew = GetAccObjByXAcc(newFocus);
377 if(pAccObjNew)
378 {
379 AccObject* pAccObjOld = GetAccObjByXAcc(oldFocus);
380 oldFocus = newFocus;
381 pAccObjNew->setFocus();
382 //if old == new, the pAccObjNew will be without focused state
383 if (pAccObjOld && pAccObjOld != pAccObjNew)
384 pAccObjOld->unsetFocus();
385 }
386}
387
394{
395 AccObject *parentAccObj = pObj->GetParentObj();
396 if( parentAccObj )
397 parentAccObj->DeleteChild( pObj );
398}
399
405void AccObjectWinManager::DeleteFromHwndXAcc(XAccessible const * pXAcc )
406{
407 std::scoped_lock l(m_Mutex);
408
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);
413}
414
421{
422 AccObject* currentObj=nullptr;
423 AccObject* childObj=nullptr;
424
425 currentObj = GetAccObjByXAcc( pXAcc);
426 if(currentObj)
427 {
428 childObj = currentObj->NextChild();
429 while(childObj)
430 {
431 XAccessible *const pTmpXAcc = childObj->GetXAccessible().get();
432 if(pTmpXAcc)
433 {
434 DeleteChildrenAccObj(pTmpXAcc);
435 DeleteAccObj(pTmpXAcc);
436 }
437 childObj = currentObj->NextChild();
438 }
439 }
440}
441
447void AccObjectWinManager::DeleteAccObj( XAccessible* pXAcc )
448{
449 if( pXAcc == nullptr )
450 return;
451
453
454 {
455 std::scoped_lock l(m_Mutex);
456
457 XIdToAccObjHash::iterator temp = XIdAccList.find(pXAcc);
458 if( temp != XIdAccList.end() )
459 {
460 ResIdGen.SetSub( temp->second.GetResID() );
461 }
462 else
463 {
464 return;
465 }
466
467 AccObject& accObj = temp->second;
468 DeleteAccChildNode( &accObj );
469 pListener = DeleteAccListener(&accObj);
470 accObj.NotifyDestroy();
471 if( accObj.GetIMAccessible() )
472 {
473 accObj.GetIMAccessible()->Release();
474 }
475 size_t i = XResIdAccList.erase(accObj.GetResID());
476 assert(i != 0);
477 (void) i;
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)
483 {
484 XHWNDDocList.erase(accObj.GetParentHWND());
485 }
486 XIdAccList.erase(pXAcc); // note: this invalidates accObj so do it last!
487 }
488 if (pListener)
489 {
490 pListener->RemoveMeFromBroadcaster(false);
491 }
492}
493
500{
501 return pAccObj->SetListener(nullptr);
502}
503
510{
511 return ResIdGen.GenerateNewResID();
512}
513
520bool AccObjectWinManager::InsertChildrenAccObj( css::accessibility::XAccessible* pXAcc,
521 HWND pWnd)
522{
523 if(!IsContainer(pXAcc))
524 return false;
525
527
528 if( pXAcc == nullptr)
529 return false;
530 pRContext = pXAcc->getAccessibleContext();
531 if( !pRContext.is() )
532 return false;
533
534 short role = pRContext->getAccessibleRole();
535
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)
540 {
541 if(IsStateManageDescendant(pXAcc))
542 {
543 return true;
544 }
545 }
546
547 const sal_Int64 nCount = pRContext->getAccessibleChildCount();
548 for (sal_Int64 i = 0; i < nCount; i++)
549 {
550 Reference<XAccessible> mxAccessible
551 = pRContext->getAccessibleChild(i);
552 XAccessible* mpAccessible = mxAccessible.get();
553 if(mpAccessible != nullptr)
554 {
555 InsertAccObj( mpAccessible,pXAcc,pWnd );
556 InsertChildrenAccObj(mpAccessible,pWnd);
557 }
558 }
559
560 return true;
561}
562
570void AccObjectWinManager::InsertAccChildNode( AccObject* pCurObj, AccObject* pParentObj, HWND /* pWnd */ )
571{
572 if(pCurObj)
573 {
574 if(pParentObj)
575 {
576 pParentObj->InsertChild(pCurObj);
577 }
578 else
579 {
580 pCurObj->UpdateValidWindow();
581 }
582 }
583}
584
592bool AccObjectWinManager::InsertAccObj( XAccessible* pXAcc,XAccessible* pParentXAcc,HWND pWnd )
593{
595
596 if( pXAcc == nullptr)
597 return false;
598
599 pRContext = pXAcc->getAccessibleContext();
600 if( !pRContext.is() )
601 return false;
602
603 {
604 short nCurRole = GetRole(pXAcc);
605
606 std::scoped_lock l(m_Mutex);
607
608 XIdToAccObjHash::iterator itXacc = XIdAccList.find( pXAcc );
609 if (itXacc != XIdAccList.end() )
610 {
611 if (AccessibleRole::SHAPE == nCurRole)
612 {
613 AccObject &objXacc = itXacc->second;
614 AccObject *pObjParent = objXacc.GetParentObj();
615 if (pObjParent &&
616 pObjParent->GetXAccessible().is() &&
617 pObjParent->GetXAccessible().get() != pParentXAcc)
618 {
619 XIdToAccObjHash::iterator itXaccParent = XIdAccList.find( pParentXAcc );
620 if(itXaccParent != XIdAccList.end())
621 {
622 objXacc.SetParentObj(&(itXaccParent->second));
623 }
624 }
625 }
626 return false;
627 }
628 }
629
630 if( pWnd == nullptr )
631 {
632 if(pParentXAcc)
633 {
634 AccObject* pObj = GetAccObjByXAcc(pParentXAcc);
635 if(pObj)
636 pWnd = pObj->GetParentHWND();
637 }
638 if( pWnd == nullptr )
639 return false;
640 }
641
642 AccObject pObj( pXAcc,pAgent );
643 if( pObj.GetIMAccessible() == nullptr )
644 return false;
645 pObj.SetResID( this->ImpleGenerateResID());
646 pObj.SetParentHWND( pWnd );
647
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)
653 {
654 XHWNDToDocumentHash::iterator aIter = XHWNDDocList.find(pWnd);
655 if ( aIter != XHWNDDocList.end() )
656 {
657 XHWNDDocList.erase( aIter );
658 }
659 XHWNDDocList.emplace( pWnd, pXAcc );
660 }
661 //end of file name
662
663 ::rtl::Reference<AccEventListener> const pListener =
665 if (!pListener.is())
666 return false;
667 Reference<XAccessibleComponent> xComponent(pRContext,UNO_QUERY);
668 Reference<XAccessibleEventBroadcaster> broadcaster(xComponent,UNO_QUERY);
669 if (broadcaster.is())
670 {
671 Reference<XAccessibleEventListener> const xListener(pListener);
672 broadcaster->addAccessibleEventListener(xListener);
673 }
674 else
675 return false;
676
677 {
678 std::scoped_lock l(m_Mutex);
679
680 XIdAccList.emplace(pXAcc, pObj);
681 XIdToAccObjHash::iterator pIndTemp = XIdAccList.find( pXAcc );
682 XResIdAccList.emplace(pObj.GetResID(),&(pIndTemp->second));
683 }
684
685 AccObject* pCurObj = GetAccObjByXAcc(pXAcc);
686 if( pCurObj )
687 {
688 pCurObj->SetListener(pListener);
689 }
690
691 AccObject* pParentObj = GetAccObjByXAcc(pParentXAcc);
692 InsertAccChildNode(pCurObj,pParentObj,pWnd);
693 if( pCurObj )
695 return true;
696}
697
698
705void AccObjectWinManager::SaveTopWindowHandle(HWND hWnd, css::accessibility::XAccessible* pXAcc)
706{
707 std::scoped_lock l(m_Mutex);
708
709 HwndXAcc.emplace(hWnd,pXAcc);
710}
711
712
718{
720 Reference<XAccessibleContext> xContext = pXAcc->getAccessibleContext();
721 if(xContext.is())
722 {
723 switch( xContext->getAccessibleRole() )
724 {
725 case AccessibleRole::DIALOG:
726 pRet = new AccDialogEventListener(pXAcc,pAgent);
727 break;
728 case AccessibleRole::FRAME:
729 pRet = new AccFrameEventListener(pXAcc,pAgent);
730 break;
731 case AccessibleRole::WINDOW:
732 pRet = new AccWindowEventListener(pXAcc,pAgent);
733 break;
734 case AccessibleRole::ROOT_PANE:
735 pRet = new AccFrameEventListener(pXAcc,pAgent);
736 break;
737 //Container
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);
763 break;
764 case AccessibleRole::PARAGRAPH:
765 case AccessibleRole::HEADING:
766 pRet = new AccParagraphEventListener(pXAcc,pAgent);
767 break;
768 //Component
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);
787 break;
788 //text component
789 case AccessibleRole::TEXT:
790 pRet = new AccTextComponentEventListener(pXAcc,pAgent);
791 break;
792 //menu
793 case AccessibleRole::MENU:
794 pRet = new AccMenuEventListener(pXAcc,pAgent);
795 break;
796 //object container
797 case AccessibleRole::SHAPE:
798
799 case AccessibleRole::EMBEDDED_OBJECT:
800 case AccessibleRole::GRAPHIC:
801 case AccessibleRole::TEXT_FRAME:
802 pRet = new AccObjectContainerEventListener(pXAcc,pAgent);
803 break;
804 //descendmanager
805 case AccessibleRole::LIST:
806 pRet = new AccListEventListener(pXAcc,pAgent);
807 break;
808 case AccessibleRole::TREE:
809 pRet = new AccTreeEventListener(pXAcc,pAgent);
810 break;
811 //special
812 case AccessibleRole::COLUMN_HEADER:
813 case AccessibleRole::TABLE:
814 pRet = new AccTableEventListener(pXAcc,pAgent);
815 break;
816 default:
817 pRet = new AccContainerEventListener(pXAcc,pAgent);
818 break;
819 }
820 }
821 return pRet;
822}
823
832void AccObjectWinManager::DecreaseState(XAccessible* pXAcc, sal_Int64 nState)
833{
834 AccObject* pAccObj = GetAccObjByXAcc( pXAcc );
835 if( pAccObj )
836 pAccObj->DecreaseState(nState);
837}
838
847void AccObjectWinManager::IncreaseState(XAccessible* pXAcc, sal_Int64 nState)
848{
849 AccObject* pAccObj = GetAccObjByXAcc( pXAcc );
850 if( pAccObj )
851 pAccObj->IncreaseState(nState);
852}
853
854void AccObjectWinManager::UpdateState( css::accessibility::XAccessible* pXAcc )
855{
856 AccObject* pAccObj = GetAccObjByXAcc( pXAcc );
857 if( pAccObj )
858 pAccObj->UpdateState( );
859}
860
867void AccObjectWinManager::UpdateAccName( XAccessible* pXAcc )
868{
869 AccObject* pAccObj = GetAccObjByXAcc( pXAcc );
870 if( pAccObj )
871 pAccObj->UpdateName();
872}
873
874void AccObjectWinManager::UpdateAction( XAccessible* pXAcc )
875{
876 AccObject* pAccObj = GetAccObjByXAcc( pXAcc );
877 if( pAccObj )
878 pAccObj->UpdateAction();
879}
880
887void AccObjectWinManager::SetValue( XAccessible* pXAcc, Any pAny )
888{
889 AccObject* pAccObj = GetAccObjByXAcc( pXAcc );
890 if( pAccObj )
891 pAccObj->SetValue( pAny );
892}
893
899void AccObjectWinManager::UpdateValue( XAccessible* pXAcc )
900{
901 AccObject* pAccObj = GetAccObjByXAcc( pXAcc );
902 if( pAccObj )
903 pAccObj->UpdateValue();
904}
905
912void AccObjectWinManager::SetAccName( XAccessible* pXAcc, Any newName)
913{
914 AccObject* pAccObj = GetAccObjByXAcc( pXAcc );
915 if( pAccObj )
916 pAccObj->SetName( newName );
917}
918
924bool AccObjectWinManager::IsContainer(XAccessible* pAccessible)
925{
926 try
927 {
928 if(pAccessible)
929 {
930 Reference<XAccessibleContext> xContext = pAccessible->getAccessibleContext();
931 if(xContext.is())
932 {
933 switch( xContext->getAccessibleRole() )
934 {
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:
968 return true;
969 case AccessibleRole::COLUMN_HEADER:
970 case AccessibleRole::TABLE:
971 if(!IsStateManageDescendant(pAccessible))
972 return true;
973 break;
974 case AccessibleRole::MENU:
975 return true;
976 default:
977 return false;
978 }
979 }
980 }
981 }
982 catch(...)
983 {
984 return false;
985 }
986 return false;
987}
988
995{
996 if(pAccessible)
997 {
998 Reference<XAccessibleContext> xContext = pAccessible->getAccessibleContext();
999 if(xContext.is())
1000 {
1001 sal_Int64 nRState = xContext->getAccessibleStateSet();
1002 return nRState & AccessibleStateType::MANAGES_DESCENDANTS;
1003 }
1004 }
1005 return false;
1006}
1007
1014{
1015 AccObject* pAccObj = GetAccObjByXAcc(pXAcc);
1016 if(pAccObj)
1017 {
1018 return pAccObj->GetIMAccessible();
1019 }
1020 else
1021 {
1022 return nullptr;
1023 }
1024}
1025
1032{
1033 XResIdToAccObjHash::iterator pIndTemp = XResIdAccList.find( resID );
1034 if ( pIndTemp == XResIdAccList.end() )
1035 return nullptr;
1036
1037 AccObject* pObj = pIndTemp->second;
1038
1039 if(pObj->GetIMAccessible())
1040 return pObj->GetIMAccessible();
1041 return nullptr;
1042}
1049{
1050 AccObject* accObj = GetAccObjByXAcc(pXAcc);
1051 if(accObj)
1052 {
1053 accObj->NotifyDestroy();
1054 }
1055}
1056
1057
1058void AccObjectWinManager::UpdateChildState(css::accessibility::XAccessible* pAccSubMenu)
1059{
1060 Reference<css::accessibility::XAccessibleContext> xContext(pAccSubMenu,UNO_QUERY);
1061 if (!xContext.is())
1062 {
1063 return;
1064 }
1065 const sal_Int64 nCount = xContext->getAccessibleChildCount();
1066 for (sal_Int64 i = 0 ; i < nCount; ++i)
1067 {
1068 Reference<css::accessibility::XAccessible> xChild = xContext->getAccessibleChild(i);
1069 if (xChild.is())
1070 {
1071 AccObject *pObj = GetAccObjByXAcc(xChild.get());
1072 if (pObj)
1073 {
1074 pObj->UpdateState();
1075 }
1076 }
1077 }
1078}
1079
1080
1081bool AccObjectWinManager::IsSpecialToolbarItem(css::accessibility::XAccessible* pXAcc)
1082{
1083 if (pXAcc && oldFocus != pXAcc)
1084 {
1085 if (GetParentRole(pXAcc) == AccessibleRole::TOOL_BAR)
1086 {
1087 Reference< XAccessibleContext > pRContext(pXAcc->getAccessibleContext());
1088 if (pRContext.is())
1089 {
1090 if (pRContext->getAccessibleRole() == AccessibleRole::TOGGLE_BUTTON)
1091 {
1092 return true;
1093 }
1094 }
1095 }
1096 }
1097 return false;
1098}
1099
1100short AccObjectWinManager::GetRole(css::accessibility::XAccessible* pXAcc)
1101{
1102 assert(pXAcc != nullptr);
1103 Reference<css::accessibility::XAccessibleContext> xContext = pXAcc->getAccessibleContext();
1104 if(xContext.is())
1105 {
1106 return xContext->getAccessibleRole();
1107 }
1108 return -1;
1109}
1110
1112{
1113 XHWNDToDocumentHash::iterator aIter;
1114 aIter = XHWNDDocList.find( pWnd );
1115 if ( aIter != XHWNDDocList.end() )
1116 {
1117 return aIter->second;
1118 }
1119
1120 return nullptr;
1121}
1122
1123XAccessible* AccObjectWinManager::GetAccDocByAccTopWin( XAccessible* pXAcc )
1124{
1125 AccObject* pAccObj = GetAccObjByXAcc( pXAcc );
1126 HWND hWnd = pAccObj->GetParentHWND();
1127 return GetAccDocByHWND(hWnd);
1128}
1129
1130bool AccObjectWinManager::IsTopWinAcc( css::accessibility::XAccessible* pXAcc )
1131{
1132 bool bRet = false;
1133 AccObject* pAccObj = GetAccObjByXAcc( pXAcc );
1134 if ( pAccObj )
1135 {
1136 bRet = ( pAccObj->GetParentObj() == nullptr );
1137 }
1138 return bRet;
1139}
1140/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
AccComponentEventListener is inherited from AccEventListener.
AccContainerEventListener is inherited from AccEventListener.
AccDialogEventListener is inherited from AccEventListener.
AccFrameEventListener is inherited from AccEventListener.
AccListEventListener is inherited from AccDescendantManagerEventListener.
AccMenuEventListener is inherited from AccComponentEventListener.
AccObjectContainerEventListener is inherited from AccContainerEventListener.
XResIdToAccObjHash XResIdAccList
bool IsSpecialToolbarItem(css::accessibility::XAccessible *pXAcc)
static short GetRole(css::accessibility::XAccessible *pXAcc)
void UpdateValue(css::accessibility::XAccessible *pXAcc)
Set corresponding com object's value via XAccessible interface.
void DecreaseState(css::accessibility::XAccessible *pXAcc, sal_Int64 nState)
state is a combination integer, each bit of which represents a single state, such as focused,...
XIdToAccObjHash XIdAccList
void NotifyDestroy(css::accessibility::XAccessible *pXAcc)
Notify some object will be destroyed.
void SetAccName(css::accessibility::XAccessible *pXAcc, css::uno::Any newName)
Set corresponding com object's name via XAccessible interface and new name.
static bool IsStateManageDescendant(css::accessibility::XAccessible *pAccessible)
Judge if a XAccessible object has ManageDescendant event.
::rtl::Reference< AccEventListener > CreateAccEventListener(css::accessibility::XAccessible *pXAcc)
Create the corresponding listener.
void UpdateAccFocus(css::accessibility::XAccessible *newFocus)
Update focus object by new focused XAccessible interface.
AccObjectWinManager(AccObjectManagerAgent *Agent=nullptr)
constructor
IMAccessible * GetIMAccByXAcc(css::accessibility::XAccessible *pXAcc)
Query and get IAccessible interface by XAccessible interface from list.
short GetParentRole(css::accessibility::XAccessible *pXAcc)
Get Parent role by XAccessible interface.
static void DeleteAccChildNode(AccObject *pChild)
Delete child element from children list.
void DeleteFromHwndXAcc(css::accessibility::XAccessible const *pXAcc)
Delete XAccessible items in top window handle hashtable.
static void InsertAccChildNode(AccObject *pCurObj, AccObject *pParentObj, HWND pWnd)
Insert child object.
void IncreaseState(css::accessibility::XAccessible *pXAcc, sal_Int64 nState)
state is a combination integer, each bit of which represents a single state,such as focused,...
css::accessibility::XAccessible * oldFocus
css::accessibility::XAccessible * GetParentXAccessible(css::accessibility::XAccessible *pXAcc)
Get Parent XAccessible interface by XAccessible interface.
std::recursive_mutex m_Mutex
void SetValue(css::accessibility::XAccessible *pXAcc, css::uno::Any pAny)
Set corresponding com object's value via XAccessible interface and new value.
virtual ~AccObjectWinManager()
Destructor,clear all resource.
css::accessibility::XAccessible * GetAccDocByAccTopWin(css::accessibility::XAccessible *pXAcc)
XHWNDToDocumentHash XHWNDDocList
AccObjectManagerAgent * pAgent
long ImpleGenerateResID()
Generate a child ID, which is used for AT.
bool InsertAccObj(css::accessibility::XAccessible *pXAcc, css::accessibility::XAccessible *pParentXAcc, HWND pWnd)
Insert child object.
bool IsTopWinAcc(css::accessibility::XAccessible *pXAcc)
static rtl::Reference< AccEventListener > DeleteAccListener(AccObject *pAccObj)
Delete listener that inspects some XAccessible object.
void DeleteChildrenAccObj(css::accessibility::XAccessible *pAccObj)
Delete all children with the tree root of XAccessible pointer.
css::accessibility::XAccessible * GetAccDocByHWND(HWND hWnd)
IMAccessible * GetTopWindowIMAccessible(HWND hWnd)
get acc object of top window by its handle
void DeleteAccObj(css::accessibility::XAccessible *pXAcc)
Delete Acc object self.
LRESULT Get_ToATInterface(HWND hWnd, long lParam, WPARAM wParam)
Get valid com object interface when notifying some MSAA event.
void UpdateState(css::accessibility::XAccessible *pXAcc)
void UpdateChildState(css::accessibility::XAccessible *pXAcc)
void SaveTopWindowHandle(HWND hWnd, css::accessibility::XAccessible *pXAcc)
save the pair <topwindowhandle, XAccessible>
IMAccessible * GetIAccessibleFromResID(long resID)
Query and get IAccessible interface by child id from list.
void UpdateAccName(css::accessibility::XAccessible *pXAcc)
Set corresponding com object's accessible name via XAccessible interface and new name.
static bool IsContainer(css::accessibility::XAccessible *pAccessible)
Judge if a XAccessible object is a container object.
AccObject * GetAccObjByXAcc(css::accessibility::XAccessible *pXAcc)
Search AccObject by XAccessible pointer from our container.
bool InsertChildrenAccObj(css::accessibility::XAccessible *pXAcc, HWND pWnd=nullptr)
Insert all children of the current acc object.
bool NotifyAccEvent(css::accessibility::XAccessible *pXAcc, UnoMSAAEvent eEvent)
Simulate MSAA event via XAccessible interface and event type.
void UpdateAction(css::accessibility::XAccessible *pXAcc)
HWND GetParentHWND()
Definition: AccObject.cxx:1065
void UpdateName()
Update name property to com object.
Definition: AccObject.cxx:266
void unsetFocus()
Unset self from focus object in parent child list.
Definition: AccObject.cxx:977
void DecreaseState(sal_Int64 xState)
Decrease state of com object.
Definition: AccObject.cxx:615
void NotifyDestroy()
Definition: AccObject.cxx:1003
void UpdateAction()
Update default action property to com object.
Definition: AccObject.cxx:292
void IncreaseState(sal_Int64 xState)
Increase state of com object.
Definition: AccObject.cxx:658
void DeleteChild(AccObject *pChild)
Delete a child element.
Definition: AccObject.cxx:227
void UpdateDefaultAction()
Set special default action description string via UNO role.
Definition: AccObject.cxx:335
void SetParentObj(AccObject *pParentAccObj)
Definition: AccObject.cxx:1009
void UpdateState()
update state information from uno to com
Definition: AccObject.cxx:759
void SetParentHWND(HWND hWnd)
Definition: AccObject.cxx:1043
void UpdateValue()
Update value property to com object.
Definition: AccObject.cxx:312
short GetRole() const
Get role property via pAny.
Definition: AccObject.cxx:485
void setFocus()
Set self to focus object in parent child list.
Definition: AccObject.cxx:961
bool UpdateAccessibleInfoFromUnoToMSAA()
Public method to mapping information between MSAA and UNO.
Definition: AccObject.cxx:934
long GetResID()
Definition: AccObject.cxx:1060
void InsertChild(AccObject *pChild, short pos=LAST_CHILD)
Insert a child element.
Definition: AccObject.cxx:201
void SetValue(css::uno::Any pAny)
Set value property via pAny.
Definition: AccObject.cxx:362
AccObject * GetParentObj()
Definition: AccObject.cxx:1070
css::uno::Reference< css::accessibility::XAccessible > const & GetXAccessible()
Definition: AccObject.cxx:1038
::rtl::Reference< AccEventListener > SetListener(::rtl::Reference< AccEventListener > const &pListener)
Definition: AccObject.cxx:1048
void SetName(css::uno::Any newName)
Set name property via pAny.
Definition: AccObject.cxx:471
IMAccessible * GetIMAccessible()
Definition: AccObject.cxx:1033
AccObject * NextChild()
Get next child element.
Definition: AccObject.cxx:687
void SetResID(long id)
Definition: AccObject.cxx:1026
void UpdateValidWindow()
In order to windows API WindowFromAccessibleObject, we sometimes to set a pure top window accessible ...
Definition: AccObject.cxx:245
AccParagraphEventListener is inherited from AccContainerEventListener.
AccTableEventListener is inherited from AccDescendantManagerEventListener.
AccTextComponentEventListener is inherited from AccComponentEventListener.
AccTreeEventListener is inherited from AccDescendantManagerEventListener.
AccWindowEventListener is inherited from AccEventListener.
long GenerateNewResID()
SubList stores those IDs that were ever generated and deleted, the method return the ID from subList ...
void SetSub(long number)
int nCount
sal_Int32 nState
@ IA2_EVENT_TEXT_CARET_MOVED
The caret has moved to a new position.
@ IA2_EVENT_TEXT_COLUMN_CHANGED
The caret moved from one column to the next.
@ IA2_EVENT_PAGE_CHANGED
A slide changed in a presentation document or a page boundary was crossed in a word processing docume...
@ IA2_EVENT_TEXT_SELECTION_CHANGED
The text selection changed.
@ IA2_EVENT_TABLE_ROW_DESCRIPTION_CHANGED
A table's row description changed.
@ IA2_EVENT_SECTION_CHANGED
The caret moved from one section to the next.
@ IA2_EVENT_ACTION_CHANGED
The change of the number or attributes of actions of an accessible object is signaled by events of th...
@ IA2_EVENT_TABLE_COLUMN_DESCRIPTION_CHANGED
A table's column description changed.
@ IA2_EVENT_VISIBLE_DATA_CHANGED
A visible data event indicates the change of the visual appearance of an accessible object.
@ IA2_EVENT_TABLE_COLUMN_HEADER_CHANGED
A table's column header changed.
@ IA2_EVENT_TABLE_ROW_HEADER_CHANGED
A table's row header changed.
@ IA2_EVENT_TABLE_MODEL_CHANGED
A table's data changed.
@ IA2_EVENT_TABLE_CAPTION_CHANGED
A table caption changed.
@ IA2_EVENT_TEXT_CHANGED
Deprecated.
@ IA2_EVENT_TABLE_SUMMARY_CHANGED
A table's summary changed.
OUString newName(std::u16string_view aNewPrefix, std::u16string_view aOldPrefix, std::u16string_view old_Name)
int i
Any result
UnoMSAAEvent
@ SELECTION_CHANGED_REMOVE
@ TABLE_ROW_DESCRIPTION_CHANGED
@ TABLE_ROW_HEADER_CHANGED
@ OBJECT_DESCRIPTIONCHANGE
@ TABLE_COLUMN_DESCRIPTION_CHANGED
@ SELECTION_CHANGED_WITHIN
@ TEXT_SELECTION_CHANGED
@ OBJECT_DEFACTIONCHANGE
@ TABLE_COLUMN_HEADER_CHANGED
@ ACTIVE_DESCENDANT_CHANGED