fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / winaccessibility / source / service / AccObjectWinManager.cxx
blobe05f25f2b2878cbe61b21e72f91bf3c7db73ae4a
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 .
20 #include <cassert>
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>
28 #include <oleacc.h>
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"
47 using namespace std;
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;
53 /**
54 * constructor
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.
62 * hAcc TopWindowHWND
63 * @return
65 AccObjectWinManager::AccObjectWinManager( AccObjectManagerAgent* Agent ):
66 pAgent( Agent ),
67 oldFocus( NULL )
71 /**
72 * Destructor,clear all resource.
73 * @param
74 * @return
76 AccObjectWinManager::~AccObjectWinManager()
78 XIdAccList.clear();
79 HwndXAcc.clear();
80 XResIdAccList.clear();
81 XHWNDDocList.clear();
82 #ifdef ACC_DEBUG
84 fclose( pFile );
85 #endif
89 /**
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.
96 LRESULT
97 AccObjectWinManager::Get_ToATInterface(HWND hWnd, long lParam, WPARAM wParam)
99 IMAccessible* pRetIMAcc = NULL;
101 if(lParam == OBJID_CLIENT )
103 AccObject* topWindowAccObj = GetTopWindowAccObj(hWnd);
104 if(topWindowAccObj)
106 pRetIMAcc = topWindowAccObj->GetIMAccessible();
107 if(pRetIMAcc)
108 pRetIMAcc->AddRef();//increase COM reference count
112 if ( pRetIMAcc && lParam == OBJID_CLIENT )
114 IAccessible* pTemp = dynamic_cast<IAccessible*>( pRetIMAcc );
115 LRESULT result = LresultFromObject(IID_IAccessible, wParam, pTemp);
116 pTemp->Release();
117 return result;
119 return 0;
123 * Search AccObject by XAccessible pointer from our container.
124 * @param pXAcc XAccessible interface.
125 * @return Pointer of accObject that is found.
127 AccObject* AccObjectWinManager::GetAccObjByXAcc( XAccessible* pXAcc)
129 if( pXAcc == NULL)
130 return NULL;
132 XIdToAccObjHash::iterator pIndTemp = XIdAccList.find( (void*)pXAcc );
133 if ( pIndTemp == XIdAccList.end() )
134 return NULL;
136 return &(pIndTemp->second);
140 * get acc object of top window by its handle
141 * @param hWnd, top window handle
142 * @return pointer to AccObject
144 AccObject* AccObjectWinManager::GetTopWindowAccObj(HWND hWnd)
146 XHWNDToXAccHash::iterator iterResult =HwndXAcc.find(hWnd);
147 if(iterResult == HwndXAcc.end())
148 return NULL;
149 XAccessible* pXAcc = (XAccessible*)(iterResult->second);
150 return GetAccObjByXAcc(pXAcc);
154 * Simulate MSAA event via XAccessible interface and event type.
155 * @param pXAcc XAccessible interface.
156 * @param state Customize Interface
157 * @return The terminate result that identifies if the call is successful.
159 sal_Bool AccObjectWinManager::NotifyAccEvent(XAccessible* pXAcc,short state)
161 Reference< XAccessibleContext > pRContext;
163 if( pXAcc == NULL)
164 return sal_False;
167 pRContext = pXAcc->getAccessibleContext();
168 if( !pRContext.is() )
169 return sal_False;
172 AccObject* selfAccObj= GetAccObjByXAcc(pXAcc);
174 if(selfAccObj==NULL)
175 return sal_False;
177 long dChildID = selfAccObj->GetResID();
178 HWND hAcc = selfAccObj->GetParentHWND();
180 switch(state)
182 case UM_EVENT_STATE_FOCUSED:
184 UpdateAccFocus(pXAcc);
185 if( selfAccObj )
186 selfAccObj->UpdateDefaultAction( );
187 UpdateValue(pXAcc);
188 NotifyWinEvent( EVENT_OBJECT_FOCUS,hAcc, OBJID_CLIENT,dChildID );
189 break;
191 case UM_EVENT_STATE_BUSY:
192 NotifyWinEvent( EVENT_OBJECT_STATECHANGE,hAcc, OBJID_CLIENT,dChildID );
193 break;
194 case UM_EVENT_STATE_CHECKED:
195 NotifyWinEvent( EVENT_OBJECT_STATECHANGE,hAcc, OBJID_CLIENT,dChildID );
196 break;
197 case UM_EVENT_STATE_PRESSED:
198 NotifyWinEvent( EVENT_OBJECT_STATECHANGE,hAcc, OBJID_CLIENT,dChildID );
199 break;
201 //Removed fire out selected event
202 //case UM_EVENT_STATE_SELECTED:
203 // NotifyWinEvent( EVENT_OBJECT_STATECHANGE,hAcc, OBJID_CLIENT,dChildID );
204 // break;
205 case UM_EVENT_STATE_ARMED:
206 UpdateAccFocus(pXAcc);
207 NotifyWinEvent( EVENT_OBJECT_FOCUS,hAcc, OBJID_CLIENT,dChildID );
208 break;
209 case UM_EVENT_MENU_START:
210 NotifyWinEvent( EVENT_SYSTEM_MENUSTART,hAcc, OBJID_CLIENT,dChildID );
211 break;
212 case UM_EVENT_MENU_END:
213 NotifyWinEvent( EVENT_SYSTEM_MENUEND,hAcc, OBJID_CLIENT,dChildID );
214 break;
215 case UM_EVENT_MENUPOPUPSTART:
216 NotifyWinEvent( EVENT_SYSTEM_MENUPOPUPSTART,hAcc, OBJID_CLIENT,dChildID );
217 break;
218 case UM_EVENT_MENUPOPUPEND:
219 NotifyWinEvent( EVENT_SYSTEM_MENUPOPUPEND,hAcc, OBJID_CLIENT,dChildID );
220 break;
221 case UM_EVENT_SELECTION_CHANGED:
222 NotifyWinEvent( EVENT_OBJECT_SELECTION,hAcc, OBJID_CLIENT,dChildID );
223 break;
224 case UM_EVENT_SELECTION_CHANGED_ADD:
225 NotifyWinEvent( EVENT_OBJECT_SELECTIONADD,hAcc, OBJID_CLIENT,dChildID );
226 break;
227 case UM_EVENT_SELECTION_CHANGED_REMOVE:
228 NotifyWinEvent( EVENT_OBJECT_SELECTIONREMOVE,hAcc, OBJID_CLIENT,dChildID );
229 break;
230 case UM_EVENT_SELECTION_CHANGED_WITHIN:
231 NotifyWinEvent( EVENT_OBJECT_SELECTIONWITHIN,hAcc, OBJID_CLIENT,dChildID );
232 break;
233 case UM_EVENT_OBJECT_VALUECHANGE:
234 UpdateValue(pXAcc);
235 NotifyWinEvent( EVENT_OBJECT_VALUECHANGE,hAcc, OBJID_CLIENT,dChildID );
236 break;
237 case UM_EVENT_OBJECT_NAMECHANGE:
238 NotifyWinEvent( EVENT_OBJECT_NAMECHANGE,hAcc, OBJID_CLIENT,dChildID );
239 break;
240 case UM_EVENT_OBJECT_DESCRIPTIONCHANGE:
241 NotifyWinEvent( EVENT_OBJECT_DESCRIPTIONCHANGE,hAcc, OBJID_CLIENT,dChildID );
242 break;
243 case UM_EVENT_OBJECT_DEFACTIONCHANGE:
244 NotifyWinEvent( IA2_EVENT_ACTION_CHANGED,hAcc, OBJID_CLIENT,dChildID );
245 break;
246 case UM_EVENT_OBJECT_CARETCHANGE:
247 NotifyWinEvent( IA2_EVENT_TEXT_CARET_MOVED,hAcc, OBJID_CLIENT,dChildID );
248 break;
249 case UM_EVENT_OBJECT_TEXTCHANGE:
250 NotifyWinEvent( IA2_EVENT_TEXT_CHANGED,hAcc, OBJID_CLIENT,dChildID );
251 break;
252 case UM_EVENT_ACTIVE_DESCENDANT_CHANGED:
253 UpdateAccFocus(pXAcc);
254 NotifyWinEvent( EVENT_OBJECT_FOCUS,hAcc, OBJID_CLIENT,dChildID );
255 break;
256 case UM_EVENT_BOUNDRECT_CHANGED:
257 NotifyWinEvent( EVENT_OBJECT_LOCATIONCHANGE,hAcc, OBJID_CLIENT,dChildID );
258 break;
259 case UM_EVENT_VISIBLE_DATA_CHANGED:
260 NotifyWinEvent( IA2_EVENT_VISIBLE_DATA_CHANGED,hAcc, OBJID_CLIENT,dChildID );
261 break;
262 case UM_EVENT_SHOW :
263 NotifyWinEvent( EVENT_OBJECT_SHOW,hAcc, OBJID_CLIENT,dChildID );
264 NotifyWinEvent( EVENT_SYSTEM_FOREGROUND,hAcc, OBJID_CLIENT,dChildID );
265 break;
266 case UM_EVENT_TABLE_CAPTION_CHANGED:
267 NotifyWinEvent( IA2_EVENT_TABLE_CAPTION_CHANGED,hAcc, OBJID_CLIENT,dChildID );
268 break;
269 case UM_EVENT_TABLE_COLUMN_DESCRIPTION_CHANGED:
270 NotifyWinEvent( IA2_EVENT_TABLE_COLUMN_DESCRIPTION_CHANGED,hAcc, OBJID_CLIENT,dChildID );
271 break;
272 case UM_EVENT_TABLE_COLUMN_HEADER_CHANGED:
273 NotifyWinEvent( IA2_EVENT_TABLE_COLUMN_HEADER_CHANGED,hAcc, OBJID_CLIENT,dChildID );
274 break;
275 case UM_EVENT_TABLE_MODEL_CHANGED:
276 NotifyWinEvent( IA2_EVENT_TABLE_MODEL_CHANGED,hAcc, OBJID_CLIENT,dChildID );
277 break;
278 case UM_EVENT_TABLE_ROW_HEADER_CHANGED:
279 NotifyWinEvent( IA2_EVENT_TABLE_ROW_HEADER_CHANGED,hAcc, OBJID_CLIENT,dChildID );
280 break;
281 case UM_EVENT_TABLE_SUMMARY_CHANGED:
282 NotifyWinEvent( IA2_EVENT_TABLE_SUMMARY_CHANGED,hAcc, OBJID_CLIENT,dChildID );
283 break;
284 case UM_EVENT_TABLE_ROW_DESCRIPTION_CHANGED:
285 NotifyWinEvent( IA2_EVENT_TABLE_ROW_DESCRIPTION_CHANGED,hAcc, OBJID_CLIENT,dChildID );
286 break;
287 case UM_EVENT_OBJECT_REORDER:
288 NotifyWinEvent( EVENT_OBJECT_REORDER,hAcc, OBJID_CLIENT,dChildID );
289 break;
290 case UM_EVENT_PAGE_CHANGED:
291 NotifyWinEvent( IA2_EVENT_PAGE_CHANGED,hAcc, OBJID_CLIENT,dChildID );
292 break;
293 case UM_EVENT_CHILD_REMOVED:
294 NotifyWinEvent( EVENT_OBJECT_DESTROY,hAcc, OBJID_CLIENT,dChildID );
295 break;
296 case UM_EVENT_CHILD_ADDED:
297 NotifyWinEvent( EVENT_OBJECT_CREATE ,hAcc, OBJID_CLIENT,dChildID );
298 break;
299 case UM_EVENT_OBJECT_PAGECHANGED:
300 NotifyWinEvent( IA2_EVENT_PAGE_CHANGED ,hAcc, OBJID_CLIENT,dChildID );
301 break;
302 case UM_EVENT_TEXT_SELECTION_CHANGED:
303 NotifyWinEvent( IA2_EVENT_TEXT_SELECTION_CHANGED ,hAcc, OBJID_CLIENT,dChildID );
304 break;
305 case UM_EVENT_SECTION_CHANGED:
306 NotifyWinEvent( IA2_EVENT_SECTION_CHANGED ,hAcc, OBJID_CLIENT,dChildID );
307 break;
308 case UM_EVENT_COLUMN_CHANGED:
309 NotifyWinEvent( IA2_EVENT_TEXT_COLUMN_CHANGED ,hAcc, OBJID_CLIENT,dChildID );
310 break;
311 default:
312 break;
315 return sal_True;
319 * Get Parent XAccessible interface by XAccessible interface.
320 * @param pXAcc XAccessible interface.
321 * @return Parent XAccessible interface.
323 XAccessible* AccObjectWinManager::GetParentXAccessible( XAccessible* pXAcc )
325 AccObject* pObj= GetAccObjByXAcc(pXAcc);
326 if( pObj ==NULL )
327 return NULL;
328 if(pObj->GetParentObj())
330 pObj = pObj->GetParentObj();
331 return pObj->GetXAccessible().get();
333 return NULL;
337 * Get Parent role by XAccessible interface.
338 * @param pXAcc XAccessible interface.
339 * @return Parent role.
341 short AccObjectWinManager::GetParentRole( XAccessible* pXAcc )
343 AccObject* pObj= GetAccObjByXAcc(pXAcc);
344 if( pObj ==NULL )
345 return -1;
346 if(pObj->GetParentObj())
348 pObj = pObj->GetParentObj();
349 if(pObj->GetXAccessible().is())
351 XAccessible* pXAcc = pObj->GetXAccessible().get();
352 Reference< XAccessibleContext > pRContext = pXAcc->getAccessibleContext();
353 if(pRContext.is())
354 return pRContext->getAccessibleRole();
357 return -1;
361 * Update focus objcet by new focused XAccessible interface.
362 * @param newFocus New XAccessible interface that gets focus.
363 * @return
365 void AccObjectWinManager::UpdateAccFocus(XAccessible* newFocus)
367 AccObject* pAccObjNew = GetAccObjByXAcc(newFocus);
368 if(pAccObjNew)
370 AccObject* pAccObjOld = GetAccObjByXAcc(oldFocus);
371 oldFocus = newFocus;
372 pAccObjNew->setFocus();
373 //if old == new, the pAccObjNew will be without focused state
374 if (pAccObjOld && pAccObjOld != pAccObjNew)
375 pAccObjOld->unsetFocus();
380 * Update selected objcet by new focused XAccessible interface.
381 * @param pXAcc XAccessible interface that has selected child changed.
382 * @return Selected children count.
384 int AccObjectWinManager::UpdateAccSelection(XAccessible* pXAcc)
386 Reference< XAccessibleContext > pRContext;
388 if( pXAcc == NULL)
389 return sal_False;
391 pRContext = pXAcc->getAccessibleContext();
392 if( !pRContext.is() )
393 return sal_False;
395 Reference< XAccessibleSelection > pRSelection(pRContext,UNO_QUERY);
396 if( !pRSelection.is() )
397 return sal_False;
399 AccObject* pAccObj = GetAccObjByXAcc(pXAcc);
400 if(pAccObj==NULL)
401 return sal_False;
403 Reference<XAccessible> pRChild = NULL;
404 AccObject* pAccChildObj = NULL;
405 int selectNum= pRSelection->getSelectedAccessibleChildCount();
407 IAccSelectionList oldSelection = pAccObj->GetSelection();
409 if(selectNum > 4)//for selected.
410 return selectNum;
411 if(selectNum == 1 && oldSelection.size() == 0)
412 return 1;
414 for (int i=0;i<selectNum;i++)
416 pRChild = pRSelection->getSelectedAccessibleChild(i);
417 if(!pRChild.is())
419 continue;
421 Reference<XAccessibleContext> pRChildContext = pRChild->getAccessibleContext();
422 if(!pRChildContext.is())
424 continue;
426 long index = pRChildContext->getAccessibleIndexInParent();
427 IAccSelectionList::iterator temp = oldSelection.find(index);
428 if ( temp != oldSelection.end() )
430 oldSelection.erase(index);
431 continue;
434 pAccChildObj = NULL;
435 pAccChildObj = GetAccObjByXAcc(pRChild.get());
436 if(!pAccChildObj)
438 InsertAccObj(pRChild.get(), pXAcc,pAccObj->GetParentHWND());
439 pAccChildObj = GetAccObjByXAcc(pRChild.get());
442 pAccObj->AddSelect(index, pAccChildObj);
444 if(pAccChildObj != NULL)
445 NotifyWinEvent(EVENT_OBJECT_SELECTIONADD,pAccObj->GetParentHWND(), OBJID_CLIENT,pAccChildObj->GetResID());
448 IAccSelectionList::iterator iter = oldSelection.begin();
449 while(iter!=oldSelection.end())
451 pAccObj->GetSelection().erase(iter->first);
452 pAccChildObj = (AccObject*)(iter->second);
453 if(pAccChildObj != NULL)
454 NotifyWinEvent(EVENT_OBJECT_SELECTIONREMOVE,pAccObj->GetParentHWND(), OBJID_CLIENT,pAccChildObj->GetResID());
455 ++iter;
457 return 0;
462 * Delete child element from children list.
463 * @param pObj Child element that should be removed from parant child list.
464 * @return
466 void AccObjectWinManager::DeleteAccChildNode( AccObject* pObj )
468 AccObject *parentAccObj = pObj->GetParentObj();
469 if( parentAccObj )
470 parentAccObj->DeleteChild( pObj );
474 * Delete XAccessible items in top window handle hashtable
475 * @param pXAcc XAccessible interface.
476 * @return
478 void AccObjectWinManager::DeleteFromHwndXAcc(XAccessible* pXAcc )
480 XHWNDToXAccHash::iterator iter = HwndXAcc.begin();
481 while(iter!=HwndXAcc.end())
483 if(iter->second == pXAcc )
485 HwndXAcc.erase(iter);
486 return;
488 ++iter;
493 * Delete all children with the tree root of XAccessible pointer
494 * @param pXAcc Tree root XAccessible interface.
495 * @return
497 void AccObjectWinManager::DeleteChildrenAccObj(XAccessible* pXAcc)
499 AccObject* currentObj=NULL;
500 AccObject* childObj=NULL;
502 currentObj = GetAccObjByXAcc( pXAcc);
503 if(currentObj)
505 childObj = currentObj->NextChild();
506 while(childObj)
508 XAccessible *const pTmpXAcc = childObj->GetXAccessible().get();
509 if(pTmpXAcc)
511 DeleteChildrenAccObj(pTmpXAcc);
512 DeleteAccObj(pTmpXAcc);
514 childObj = currentObj->NextChild();
520 * Delete Acc object self.
521 * @param pXAcc The XAccessible interface.
522 * @return
524 void AccObjectWinManager::DeleteAccObj( XAccessible* pXAcc )
526 if( pXAcc == NULL )
527 return;
528 XIdToAccObjHash::iterator temp = XIdAccList.find(pXAcc);
529 if( temp != XIdAccList.end() )
531 ResIdGen.SetSub( temp->second.GetResID() );
533 else
535 return;
538 AccObject& accObj = temp->second;
539 DeleteAccChildNode( &accObj );
540 DeleteAccListener( &accObj );
541 if( accObj.GetIMAccessible() )
543 accObj.GetIMAccessible()->Release();
545 size_t i = XResIdAccList.erase(accObj.GetResID());
546 assert(i != 0);
547 DeleteFromHwndXAcc(pXAcc);
548 if( accObj.GetRole() == DOCUMENT ||
549 accObj.GetRole() == DOCUMENT_PRESENTATION ||
550 accObj.GetRole() == DOCUMENT_SPREADSHEET ||
551 accObj.GetRole() == DOCUMENT_TEXT )
553 XHWNDDocList.erase(accObj.GetParentHWND());
555 XIdAccList.erase(pXAcc); // note: this invalidates accObj so do it last!
559 * Delete listener that inspects some XAccessible object
560 * @param pAccObj Accobject pointer.
561 * @return
563 void AccObjectWinManager::DeleteAccListener( AccObject* pAccObj )
565 AccEventListener* listener = pAccObj->getListener();
566 if( listener==NULL )
567 return;
568 listener->RemoveMeFromBroadcaster();
569 pAccObj->SetListener(NULL);
573 * Generate a child ID, which is used for AT
574 * @param
575 * @return New resource ID.
577 inline long AccObjectWinManager::ImpleGenerateResID()
579 return ResIdGen.GenerateNewResID();
583 * Insert all children of the current acc object
584 * @param pXAcc XAccessible interface
585 * @param pWnd Top Window handle
586 * @return The calling result.
588 sal_Bool AccObjectWinManager::InsertChildrenAccObj( com::sun::star::accessibility::XAccessible* pXAcc,
589 HWND pWnd)
591 if(!IsContainer(pXAcc))
592 return sal_False;
594 Reference< XAccessibleContext > pRContext;
596 if( pXAcc == NULL)
597 return sal_False;
598 pRContext = pXAcc->getAccessibleContext();
599 if( !pRContext.is() )
600 return sal_False;
602 short role = pRContext->getAccessibleRole();
604 if(com::sun::star::accessibility::AccessibleRole::DOCUMENT == role ||
605 com::sun::star::accessibility::AccessibleRole::DOCUMENT_PRESENTATION == role ||
606 com::sun::star::accessibility::AccessibleRole::DOCUMENT_SPREADSHEET == role ||
607 com::sun::star::accessibility::AccessibleRole::DOCUMENT_TEXT == role)
609 if(IsStateManageDescendant(pXAcc))
611 return sal_True;
615 int count = pRContext->getAccessibleChildCount();
616 for (int i=0;i<count;i++)
618 Reference<XAccessible> mxAccessible
619 = pRContext->getAccessibleChild(i);
620 XAccessible* mpAccessible = mxAccessible.get();
621 if(mpAccessible != NULL)
623 InsertAccObj( mpAccessible,pXAcc,pWnd );
624 InsertChildrenAccObj(mpAccessible,pWnd);
628 return sal_True;
632 * Insert child object.
633 * @param pCurObj The child object
634 * @param pParentObj The parant object
635 * @param pWnd Top window handle.
636 * @return
638 void AccObjectWinManager::InsertAccChildNode( AccObject* pCurObj, AccObject* pParentObj, HWND /* pWnd */ )
640 if(pCurObj)
642 if(pParentObj)
644 pParentObj->InsertChild(pCurObj);
646 else
648 pCurObj->UpdateValidWindow();
654 * Insert child object.
655 * @param pCurObj The child object
656 * @param pParentObj The parant object
657 * @param pWnd Top window handle.
658 * @return
660 sal_Bool AccObjectWinManager::InsertAccObj( XAccessible* pXAcc,XAccessible* pParentXAcc,HWND pWnd )
662 XIdToAccObjHash::iterator itXacc = XIdAccList.find( (void*)pXAcc );
663 if (itXacc != XIdAccList.end() )
665 short nCurRole =GetRole(pXAcc);
666 if (AccessibleRole::SHAPE == nCurRole)
668 AccObject &objXacc = itXacc->second;
669 AccObject *pObjParent = objXacc.GetParentObj();
670 if (pObjParent &&
671 pObjParent->GetXAccessible().is() &&
672 pObjParent->GetXAccessible().get() != pParentXAcc)
674 XIdToAccObjHash::iterator itXaccParent = XIdAccList.find( (void*)pParentXAcc );
675 if(itXaccParent != XIdAccList.end())
677 objXacc.SetParentObj(&(itXaccParent->second));
681 return sal_False;
685 Reference< XAccessibleContext > pRContext;
687 if( pXAcc == NULL)
688 return sal_False;
690 pRContext = pXAcc->getAccessibleContext();
691 if( !pRContext.is() )
692 return sal_False;
694 if( pWnd == NULL )
696 if(pParentXAcc)
698 AccObject* pObj = GetAccObjByXAcc(pParentXAcc);
699 if(pObj)
700 pWnd = pObj->GetParentHWND();
702 if( pWnd == NULL )
703 return sal_False;
706 AccObject pObj( pXAcc,pAgent );
707 if( pObj.GetIMAccessible() == NULL )
708 return sal_False;
709 pObj.SetResID( this->ImpleGenerateResID());
710 pObj.SetParentHWND( pWnd );
712 //for file name support
713 if( pObj.GetRole() == DOCUMENT ||
714 pObj.GetRole() == DOCUMENT_PRESENTATION ||
715 pObj.GetRole() == DOCUMENT_SPREADSHEET ||
716 pObj.GetRole() == DOCUMENT_TEXT )
718 XHWNDToDocumentHash::iterator aIter = XHWNDDocList.find(pWnd);
719 if ( aIter != XHWNDDocList.end() )
721 XHWNDDocList.erase( aIter );
723 XHWNDDocList.insert( XHWNDToDocumentHash::value_type(pWnd, pXAcc) );
725 //end of file name
727 ::rtl::Reference<AccEventListener> const pListener =
728 CreateAccEventListener(pXAcc);
729 if (!pListener.is())
730 return sal_False;
731 Reference<XAccessibleComponent> xComponent(pRContext,UNO_QUERY);
732 Reference<XAccessibleEventBroadcaster> broadcaster(xComponent,UNO_QUERY);
733 if (broadcaster.is())
735 Reference<XAccessibleEventListener> const xListener(pListener.get());
736 broadcaster->addAccessibleEventListener(xListener);
738 else
739 return sal_False;
741 XIdAccList.insert( XIdToAccObjHash::value_type( (void*)pXAcc, pObj ));
742 XIdToAccObjHash::iterator pIndTemp = XIdAccList.find( (void*)pXAcc );
743 XResIdAccList.insert(XResIdToAccObjHash::value_type(pObj.GetResID(),&(pIndTemp->second)));
745 AccObject* pCurObj = GetAccObjByXAcc(pXAcc);
746 if( pCurObj )
748 pCurObj->SetListener(pListener);
751 AccObject* pParentObj = GetAccObjByXAcc(pParentXAcc);
752 InsertAccChildNode(pCurObj,pParentObj,pWnd);
753 if( pCurObj )
754 pCurObj->UpdateAccessibleInfoFromUnoToMSAA();
755 return sal_True;
760 * save the pair <topwindowhandle, XAccessible>
761 * @param hWnd, top window handle
762 * @param pXAcc XAccessible interface for top window
763 * @return void
765 void AccObjectWinManager::SaveTopWindowHandle(HWND hWnd, com::sun::star::accessibility::XAccessible* pXAcc)
767 HwndXAcc.insert( XHWNDToXAccHash::value_type( hWnd,(void*)pXAcc ) );
771 /** Create the corresponding listener.
772 * @param pXAcc XAccessible interface.
774 ::rtl::Reference<AccEventListener>
775 AccObjectWinManager::CreateAccEventListener(XAccessible* pXAcc)
777 ::rtl::Reference<AccEventListener> pRet;
778 Reference<XAccessibleContext> xContext(pXAcc->getAccessibleContext(),UNO_QUERY);
779 if(xContext.is())
781 switch( xContext->getAccessibleRole() )
783 case /*AccessibleRole::*/DIALOG:
784 pRet = new AccDialogEventListener(pXAcc,pAgent);
785 break;
786 case /*AccessibleRole::*/FRAME:
787 pRet = new AccFrameEventListener(pXAcc,pAgent);
788 break;
789 case /*AccessibleRole::*/WINDOW:
790 pRet = new AccWindowEventListener(pXAcc,pAgent);
791 break;
792 case /*AccessibleRole::*/ROOT_PANE:
793 pRet = new AccFrameEventListener(pXAcc,pAgent);
794 break;
795 //Container
796 case /*AccessibleRole::*/CANVAS:
797 case /*AccessibleRole::*/COMBO_BOX:
798 case /*AccessibleRole::*/DOCUMENT:
799 case /*AccessibleRole::*/DOCUMENT_PRESENTATION:
800 case /*AccessibleRole::*/DOCUMENT_SPREADSHEET:
801 case /*AccessibleRole::*/DOCUMENT_TEXT:
802 case /*AccessibleRole::*/END_NOTE:
803 case /*AccessibleRole::*/FILLER:
804 case /*AccessibleRole::*/FOOTNOTE:
805 case /*AccessibleRole::*/FOOTER:
806 case /*AccessibleRole::*/HEADER:
807 case /*AccessibleRole::*/LAYERED_PANE:
808 case /*AccessibleRole::*/MENU_BAR:
809 case /*AccessibleRole::*/POPUP_MENU:
810 case /*AccessibleRole::*/OPTION_PANE:
811 case /*AccessibleRole::*/PAGE_TAB:
812 case /*AccessibleRole::*/PAGE_TAB_LIST:
813 case /*AccessibleRole::*/PANEL:
814 case /*AccessibleRole::*/SCROLL_PANE:
815 case /*AccessibleRole::*/SPLIT_PANE:
816 case /*AccessibleRole::*/STATUS_BAR:
817 case /*AccessibleRole::*/TABLE_CELL:
818 case /*AccessibleRole::*/TOOL_BAR:
819 case /*AccessibleRole::*/VIEW_PORT:
820 pRet = new AccContainerEventListener(pXAcc,pAgent);
821 break;
822 case /*AccessibleRole::*/PARAGRAPH:
823 case /*AccessibleRole::*/HEADING:
824 pRet = new AccParagraphEventListener(pXAcc,pAgent);
825 break;
826 //Component
827 case /*AccessibleRole::*/CHECK_BOX:
828 case /*AccessibleRole::*/ICON:
829 case /*AccessibleRole::*/LABEL:
830 case /*AccessibleRole::*/MENU_ITEM:
831 case /*AccessibleRole::*/CHECK_MENU_ITEM:
832 case /*AccessibleRole::*/RADIO_MENU_ITEM:
833 case /*AccessibleRole::*/PUSH_BUTTON:
834 case /*AccessibleRole::*/RADIO_BUTTON:
835 case /*AccessibleRole::*/SCROLL_BAR:
836 case /*AccessibleRole::*/SEPARATOR:
837 case /*AccessibleRole::*/TOGGLE_BUTTON:
838 case /*AccessibleRole::*/BUTTON_DROPDOWN:
839 case /*AccessibleRole::*/TOOL_TIP:
840 case /*AccessibleRole::*/SPIN_BOX:
841 case DATE_EDITOR:
842 pRet = new AccComponentEventListener(pXAcc,pAgent);
843 break;
844 //text component
845 case /*AccessibleRole::*/TEXT:
846 pRet = new AccTextComponentEventListener(pXAcc,pAgent);
847 break;
848 //menu
849 case /*AccessibleRole::*/MENU:
850 pRet = new AccMenuEventListener(pXAcc,pAgent);
851 break;
852 //object container
853 case /*AccessibleRole::*/SHAPE:
855 case /*AccessibleRole::*/EMBEDDED_OBJECT:
856 case /*AccessibleRole::*/GRAPHIC:
857 case /*AccessibleRole::*/TEXT_FRAME:
858 pRet = new AccObjectContainerEventListener(pXAcc,pAgent);
859 break;
860 //descendmanager
861 case /*AccessibleRole::*/LIST:
862 pRet = new AccListEventListener(pXAcc,pAgent);
863 break;
864 case /*AccessibleRole::*/TREE:
865 pRet = new AccTreeEventListener(pXAcc,pAgent);
866 break;
867 //special
868 case /*AccessibleRole::*/COLUMN_HEADER:
869 case /*AccessibleRole::*/TABLE:
870 pRet = new AccTableEventListener(pXAcc,pAgent);
871 break;
872 default:
873 pRet = new AccContainerEventListener(pXAcc,pAgent);
874 break;
877 return pRet;
881 * state is a combination integer, each bit of which represents a single state,
882 * such as focused,1 for the state on,0 for the state off. Here call COM interface
883 * to modify the state value, including DecreaseState.
884 * @param pXAcc XAccessible interface.
885 * @param pState Changed state.
886 * @return
888 void AccObjectWinManager::DecreaseState( XAccessible* pXAcc,unsigned short pState )
890 AccObject* pAccObj = GetAccObjByXAcc( pXAcc );
891 if( pAccObj )
892 pAccObj->DecreaseState( pState );
896 * state is a combination integer, each bit of which represents a single state,such as focused,1 for
897 * the state on,0 for the state off. Here call COM interface to modify the state value, including
898 * IncreaseState.
899 * @param pXAcc XAccessible interface.
900 * @param pState Changed state.
901 * @return
903 void AccObjectWinManager::IncreaseState( XAccessible* pXAcc,unsigned short pState )
905 AccObject* pAccObj = GetAccObjByXAcc( pXAcc );
906 if( pAccObj )
907 pAccObj->IncreaseState( pState );
910 void AccObjectWinManager::UpdateState( com::sun::star::accessibility::XAccessible* pXAcc )
912 AccObject* pAccObj = GetAccObjByXAcc( pXAcc );
913 if( pAccObj )
914 pAccObj->UpdateState( );
918 * Set corresponding com object's accessible name via XAccessilbe interface and new
919 * name
920 * @param pXAcc XAccessible interface.
921 * @return
923 void AccObjectWinManager::UpdateAccName( XAccessible* pXAcc )
925 AccObject* pAccObj = GetAccObjByXAcc( pXAcc );
926 if( pAccObj )
927 pAccObj->UpdateName();
930 void AccObjectWinManager::UpdateAction( XAccessible* pXAcc )
932 AccObject* pAccObj = GetAccObjByXAcc( pXAcc );
933 if( pAccObj )
934 pAccObj->UpdateAction();
937 void AccObjectWinManager::UpdateDescription( XAccessible* pXAcc )
939 AccObject* pAccObj = GetAccObjByXAcc( pXAcc );
940 if ( pAccObj )
941 pAccObj->UpdateDescription();
945 * Set corresponding com object's accessible location via XAccessilbe interface and new
946 * location.
947 * @param pXAcc XAccessible interface.
948 * @return
950 void AccObjectWinManager::SetLocation( XAccessible* pXAcc, long /*top*/, long /*left*/, long /*width*/, long /*height*/ )
952 AccObject* pObj = GetAccObjByXAcc( pXAcc );
953 //get the location from XComponent.
954 Reference< XAccessibleContext > pRContext = pXAcc->getAccessibleContext();
955 if( pObj )
956 pObj->UpdateLocation();
960 * Set corresponding com object's value via XAccessilbe interface and new value.
961 * @param pXAcc XAccessible interface.
962 * @param pAny new value.
963 * @return
965 void AccObjectWinManager::SetValue( XAccessible* pXAcc, Any pAny )
967 AccObject* pAccObj = GetAccObjByXAcc( pXAcc );
968 if( pAccObj )
969 pAccObj->SetValue( pAny );
973 * Set corresponding com object's value via XAccessilbe interface.
974 * @param pXAcc XAccessible interface.
975 * @return
977 void AccObjectWinManager::UpdateValue( XAccessible* pXAcc )
979 AccObject* pAccObj = GetAccObjByXAcc( pXAcc );
980 if( pAccObj )
981 pAccObj->UpdateValue();
985 * Set corresponding com object's name via XAccessilbe interface and new name.
986 * @param pXAcc XAccessible interface.
987 * @param newName new name
988 * @return
990 void AccObjectWinManager::SetAccName( XAccessible* pXAcc, Any newName)
992 AccObject* pAccObj = GetAccObjByXAcc( pXAcc );
993 if( pAccObj )
994 pAccObj->SetName( newName );
998 * Set corresponding com object's description via XAccessilbe interface and new description.
999 * @param pXAcc XAccessible interface.
1000 * @param newDesc new description
1001 * @return
1003 void AccObjectWinManager::SetDescription( XAccessible* pXAcc, Any newDesc )
1005 AccObject* pAccObj = GetAccObjByXAcc( pXAcc );
1006 if( pAccObj )
1007 pAccObj->SetDescription( newDesc );
1011 * Set corresponding com object's role via XAccessilbe interface and new role.
1012 * @param pXAcc XAccessible interface.
1013 * @param Role new role
1014 * @return
1016 void AccObjectWinManager::SetRole( XAccessible* pXAcc, long Role )
1018 AccObject* pAccObj = GetAccObjByXAcc( pXAcc );
1019 if( pAccObj )
1020 pAccObj->SetRole( (short)Role );
1024 * Judge if a XAccessible object is a container object.
1025 * @param pAccessible XAccessible interface.
1026 * @return If XAccessible object is container.
1028 sal_Bool AccObjectWinManager::IsContainer(XAccessible* pAccessible)
1032 if(pAccessible)
1034 Reference<XAccessibleContext> xContext(pAccessible->getAccessibleContext(),UNO_QUERY);
1035 if(xContext.is())
1037 switch( xContext->getAccessibleRole() )
1039 case /*AccessibleRole::*/DIALOG:
1040 case /*AccessibleRole::*/FRAME:
1041 case /*AccessibleRole::*/WINDOW:
1042 case /*AccessibleRole::*/ROOT_PANE:
1043 case /*AccessibleRole::*/CANVAS:
1044 case /*AccessibleRole::*/COMBO_BOX:
1045 case /*AccessibleRole::*/DOCUMENT:
1046 case /*AccessibleRole::*/DOCUMENT_PRESENTATION:
1047 case /*AccessibleRole::*/DOCUMENT_SPREADSHEET:
1048 case /*AccessibleRole::*/DOCUMENT_TEXT:
1049 case /*AccessibleRole::*/EMBEDDED_OBJECT:
1050 case /*AccessibleRole::*/END_NOTE:
1051 case /*AccessibleRole::*/FILLER:
1052 case /*AccessibleRole::*/FOOTNOTE:
1053 case /*AccessibleRole::*/FOOTER:
1054 case /*AccessibleRole::*/GRAPHIC:
1055 case /*AccessibleRole::*/GROUP_BOX:
1056 case /*AccessibleRole::*/HEADER:
1057 case /*AccessibleRole::*/LAYERED_PANE:
1058 case /*AccessibleRole::*/MENU_BAR:
1059 case /*AccessibleRole::*/POPUP_MENU:
1060 case /*AccessibleRole::*/OPTION_PANE:
1061 case /*AccessibleRole::*/PAGE_TAB:
1062 case /*AccessibleRole::*/PAGE_TAB_LIST:
1063 case /*AccessibleRole::*/PANEL:
1064 case /*AccessibleRole::*/SCROLL_PANE:
1065 case /*AccessibleRole::*/SPLIT_PANE:
1066 case /*AccessibleRole::*/STATUS_BAR:
1067 case /*AccessibleRole::*/TABLE_CELL:
1068 case /*AccessibleRole::*/TEXT_FRAME:
1069 case /*AccessibleRole::*/TOOL_BAR:
1070 case /*AccessibleRole::*/VIEW_PORT:
1071 case /*AccessibleRole::*/SHAPE:
1072 return sal_True;
1073 break;
1074 case /*AccessibleRole::*/COLUMN_HEADER:
1075 case /*AccessibleRole::*/TABLE:
1076 if(!IsStateManageDescendant(pAccessible))
1077 return sal_True;
1078 break;
1079 case /*AccessibleRole::*/MENU:
1080 return sal_True;
1081 break;
1082 default:
1083 return sal_False;
1088 catch(...)
1090 return sal_False;
1092 return sal_False;
1096 * Judge if a XAccessible object has ManageDescendant event.
1097 * @param pAccessible XAccessible interface.
1098 * @return If XAccessible object is managedescendant.
1100 bool AccObjectWinManager::IsStateManageDescendant(XAccessible* pAccessible)
1102 if(pAccessible)
1104 Reference<XAccessibleContext> xContext(pAccessible->getAccessibleContext(),UNO_QUERY);
1105 if(xContext.is())
1107 Reference< XAccessibleStateSet > pRState = xContext->getAccessibleStateSet();
1108 if( !pRState.is() )
1109 return sal_False;
1111 Sequence<short> pStates = pRState->getStates();
1112 int count = pStates.getLength();
1113 for( int iIndex = 0;iIndex < count;iIndex++ )
1115 if(pStates[iIndex] == /*AccessibleStateType::*/MANAGES_DESCENDANTS)
1116 return sal_True;
1120 return sal_False;
1124 * Query and get IAccessible interface by XAccessible interface from list.
1125 * @param pXAcc XAccessible interface.
1126 * @return Com accobject interface.
1128 IMAccessible* AccObjectWinManager::GetIMAccByXAcc(XAccessible* pXAcc)
1130 AccObject* pAccObj = GetAccObjByXAcc(pXAcc);
1131 if(pAccObj)
1133 return pAccObj->GetIMAccessible();
1135 else
1137 return NULL;
1142 * Query and get IAccessible interface by child id from list.
1143 * @param resID, childID.
1144 * @return Com accobject interface.
1146 IMAccessible * AccObjectWinManager::GetIAccessibleFromResID(long resID)
1148 XResIdToAccObjHash::iterator pIndTemp = XResIdAccList.find( resID );
1149 if ( pIndTemp == XResIdAccList.end() )
1150 return NULL;
1152 AccObject* pObj = pIndTemp->second;
1154 if(pObj->GetIMAccessible())
1155 return pObj->GetIMAccessible();
1156 return NULL;
1159 * Notify some object will be destroyed.
1160 * @param pXAcc XAccessible interface.
1161 * @return Com accobject interface.
1163 void AccObjectWinManager::NotifyDestroy(XAccessible* pXAcc)
1165 AccObject* accObj = GetAccObjByXAcc(pXAcc);
1166 if(accObj)
1168 accObj->NotifyDestroy(sal_True);
1173 void AccObjectWinManager::UpdateChildState(com::sun::star::accessibility::XAccessible* pAccSubMenu)
1175 Reference<com::sun::star::accessibility::XAccessibleContext> xContext(pAccSubMenu,UNO_QUERY);
1176 if (!xContext.is())
1178 return;
1180 sal_Int32 nCount = xContext->getAccessibleChildCount();
1181 for (sal_Int32 i = 0 ; i < nCount ; ++i)
1183 Reference<com::sun::star::accessibility::XAccessible> xChild = xContext->getAccessibleChild(i);
1184 if (xChild.is())
1186 AccObject *pObj = GetAccObjByXAcc(xChild.get());
1187 if (pObj)
1189 pObj->UpdateState();
1196 bool AccObjectWinManager::IsSpecialToolboItem(com::sun::star::accessibility::XAccessible* pXAcc)
1198 if (pXAcc && oldFocus != pXAcc)
1200 if(GetParentRole(pXAcc) == TOOL_BAR)
1202 Reference< XAccessibleContext > pRContext(pXAcc->getAccessibleContext());
1203 if (pRContext.is())
1205 if(pRContext->getAccessibleRole() == TOGGLE_BUTTON)
1207 return true;
1212 return false;
1215 short AccObjectWinManager::GetRole(com::sun::star::accessibility::XAccessible* pXAcc)
1217 assert(pXAcc != NULL);
1218 Reference<com::sun::star::accessibility::XAccessibleContext> xContext(pXAcc->getAccessibleContext(),UNO_QUERY);
1219 if(xContext.is())
1221 return xContext->getAccessibleRole();
1223 return -1;
1226 XAccessible* AccObjectWinManager::GetAccDocByHWND(HWND pWnd)
1228 XHWNDToDocumentHash::iterator aIter;
1229 aIter = XHWNDDocList.find( pWnd );
1230 if ( aIter != XHWNDDocList.end() )
1232 return aIter->second;
1235 return NULL;
1238 XAccessible* AccObjectWinManager::GetAccDocByAccTopWin( XAccessible* pXAcc )
1240 AccObject* pAccObj = GetAccObjByXAcc( pXAcc );
1241 HWND hWnd = pAccObj->GetParentHWND();
1242 return GetAccDocByHWND(hWnd);
1245 bool AccObjectWinManager::IsTopWinAcc( com::sun::star::accessibility::XAccessible* pXAcc )
1247 bool bRet = false;
1248 AccObject* pAccObj = GetAccObjByXAcc( pXAcc );
1249 if ( pAccObj )
1251 bRet = ( pAccObj->GetParentObj() == NULL );
1253 return bRet;
1255 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */