1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright IBM Corporation 2010. 6 * Copyright 2000, 2010 Oracle and/or its affiliates. 7 * 8 * OpenOffice.org - a multi-platform office productivity suite 9 * 10 * This file is part of OpenOffice.org. 11 * 12 * OpenOffice.org is free software: you can redistribute it and/or modify 13 * it under the terms of the GNU Lesser General Public License version 3 14 * only, as published by the Free Software Foundation. 15 * 16 * OpenOffice.org is distributed in the hope that it will be useful, 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 * GNU Lesser General Public License version 3 for more details 20 * (a copy is included in the LICENSE file that accompanied this code). 21 * 22 * You should have received a copy of the GNU Lesser General Public License 23 * version 3 along with OpenOffice.org. If not, see 24 * <http://www.openoffice.org/license.html> 25 * for a copy of the LGPLv3 License. 26 * 27 ************************************************************************/ 28 29 #include <cassert> 30 31 #include <com/sun/star/accessibility/XAccessibleEventBroadcaster.hpp> 32 #include <com/sun/star/accessibility/XAccessibleEventListener.hpp> 33 #include <com/sun/star/accessibility/XAccessibleComponent.hpp> 34 #include <com/sun/star/accessibility/AccessibleStateType.hpp> 35 36 #include <oleacc.h> 37 #ifndef _SV_AccObjectWinManager_HXX 38 #include "AccObjectWinManager.hxx" 39 #endif 40 #include "AccEventListener.hxx" 41 #include "AccComponentEventListener.hxx" 42 #include "AccContainerEventListener.hxx" 43 #include "AccDialogEventListener.hxx" 44 #include "AccWindowEventListener.hxx" 45 #include "AccFrameEventListener.hxx" 46 #include "AccMenuEventListener.hxx" 47 #include "AccObjectContainerEventListener.hxx" 48 #include "AccParagraphEventListener.hxx" 49 #include "AccTextComponentEventListener.hxx" 50 #include "AccListEventListener.hxx" 51 #include "AccTreeEventListener.hxx" 52 #include "AccTableEventListener.hxx" 53 #include "AccObject.hxx" 54 #include "AccessibleEventId.h" 55 #include "AccessibleApplication.h" 56 #include "AccessibleApplication_i.c" 57 #include "unomsaaevent.hxx" 58 #include "checkmt.hxx" 59 60 #define CHILDID_SELF 0 61 62 63 using namespace std; 64 using namespace com::sun::star::accessibility; 65 using namespace com::sun::star::uno; 66 67 AccObjectWinManager* g_acc_manager = NULL; 68 AccObjectWinManager* AccObjectWinManager::me = NULL; 69 70 /** 71 * Implementation of interface XMSAAService's method getAccObjectPtr() that return the 72 * corresponding com interface with the MS event. 73 * 74 * @param 75 * @return Com interface. 76 */ 77 long GetMSComPtr(long hWnd, long lParam, long wParam) 78 { 79 if( g_acc_manager ) 80 return (long)g_acc_manager->Get_ToATInterface(HWND((void*)hWnd),lParam,wParam ); 81 return NULL; 82 } 83 84 /** 85 * constructor 86 * @param Agent The agent kept in all listeners,it's the sole interface by which 87 * listener communicate with windows manager. 88 * pEventAccObj The present event accobject. 89 * oldFocus Last focused object. 90 * isSelectionChanged flag that identifies if there is selection changed. 91 * selectionChildObj Selected object. 92 * dChildID Chile resource ID. 93 * hAcc TopWindowHWND 94 * @return 95 */ 96 AccObjectWinManager::AccObjectWinManager( AccObjectManagerAgent* Agent ): 97 pAgent( Agent ), 98 oldFocus( NULL ) 99 { 100 m_bBridgeRegistered =IsBridgeRegisteredAcc(); 101 } 102 103 /** 104 * Public method to produce manager 105 * @param Agent The agent kept in all listeners,it's the sole interface by which 106 * listener communicate with windows manager. 107 * @return 108 */ 109 AccObjectWinManager* AccObjectWinManager::CreateAccObjectWinManagerInstance( AccObjectManagerAgent* Agent ) 110 { 111 if( me == NULL ) 112 { 113 me = new AccObjectWinManager( Agent ); 114 g_acc_manager = me; 115 return me; 116 } 117 118 return me; 119 } 120 121 122 /** 123 * Destructor,clear all resource. 124 * @param 125 * @return 126 */ 127 AccObjectWinManager::~AccObjectWinManager() 128 { 129 XIdAccList.clear(); 130 HwndXAcc.clear(); 131 XResIdAccList.clear(); 132 XHWNDDocList.clear(); 133 #ifdef ACC_DEBUG 134 135 fclose( pFile ); 136 #endif 137 } 138 139 140 /** 141 * Get valid com object interface when notifying some MSAA event 142 * @param pWND The top window handle that contains that event control. 143 * @param wParam Windows system interface. 144 * @return Com interface with event. 145 */ 146 147 long AccObjectWinManager::Get_ToATInterface( HWND hWnd, long lParam, long wParam) 148 { 149 vos::OGuard localGuard(maATInterfaceMutex);// 150 151 IMAccessible* pRetIMAcc = NULL; 152 153 if(lParam == OBJID_CLIENT ) 154 { 155 AccObject* topWindowAccObj = GetTopWindowAccObj(hWnd); 156 if(topWindowAccObj) 157 { 158 pRetIMAcc = topWindowAccObj->GetIMAccessible(); 159 if(pRetIMAcc) 160 pRetIMAcc->AddRef();//increase COM reference count 161 } 162 } 163 164 if ( pRetIMAcc && lParam == OBJID_CLIENT ) 165 { 166 IAccessible* pTemp = dynamic_cast<IAccessible*>( pRetIMAcc ); 167 HRESULT result = LresultFromObject(IID_IAccessible, wParam, pTemp); 168 pTemp->Release(); 169 return result; 170 } 171 return 0; 172 } 173 174 /** 175 * Search AccObject by XAccessible pointer from our container. 176 * @param pXAcc XAccessible interface. 177 * @return Pointer of accObject that is found. 178 */ 179 AccObject* AccObjectWinManager::GetAccObjByXAcc( XAccessible* pXAcc) 180 { 181 if( pXAcc == NULL) 182 return NULL; 183 184 XIdToAccObjHash::iterator pIndTemp = XIdAccList.find( (void*)pXAcc ); 185 if ( pIndTemp == XIdAccList.end() ) 186 return NULL; 187 188 return &(pIndTemp->second); 189 } 190 191 /** 192 * Search XAccessible by AccObject pointer from our container. 193 * @param pAccObj AccObject pointer. 194 * @return Pointer of XAccessible Interface. 195 */ 196 XAccessible* AccObjectWinManager::GetXAccByAccObj(AccObject* pAccObj) 197 { 198 XIdToAccObjHash::iterator iter = XIdAccList.begin(); 199 while(iter!=XIdAccList.end()) 200 { 201 AccObject* tmp = &(iter->second); 202 if(tmp== pAccObj) 203 return (XAccessible*)(iter->first); 204 iter++; 205 } 206 return NULL; 207 } 208 209 /** 210 * get acc object of top window by its handle 211 * @param hWnd, top window handle 212 * @return pointer to AccObject 213 */ 214 AccObject* AccObjectWinManager::GetTopWindowAccObj(HWND hWnd) 215 { 216 XHWNDToXAccHash::iterator iterResult =HwndXAcc.find(hWnd); 217 if(iterResult == HwndXAcc.end()) 218 return NULL; 219 XAccessible* pXAcc = (XAccessible*)(iterResult->second); 220 return GetAccObjByXAcc(pXAcc); 221 } 222 223 /** 224 * Simulate MSAA event via XAccessible interface and event type. 225 * @param pXAcc XAccessible interface. 226 * @param state Customize Interface 227 * @return The terminate result that identifies if the call is successful. 228 */ 229 sal_Bool AccObjectWinManager::NotifyAccEvent(XAccessible* pXAcc,short state) 230 { 231 vos::OGuard aGuard(aNotifyMutex); 232 233 if (!m_bBridgeRegistered) 234 { 235 return sal_False; 236 } 237 if (!IsInMainThread()) 238 { 239 return sal_False; 240 } 241 242 Reference< XAccessibleContext > pRContext; 243 244 if( pXAcc == NULL) 245 return sal_False; 246 247 248 pRContext = pXAcc->getAccessibleContext(); 249 if( !pRContext.is() ) 250 return sal_False; 251 252 253 AccObject* selfAccObj= GetAccObjByXAcc(pXAcc); 254 255 if(selfAccObj==NULL) 256 return sal_False; 257 258 int selectNum =0; 259 260 long dChildID = selfAccObj->GetResID(); 261 HWND hAcc = selfAccObj->GetParentHWND(); 262 263 switch(state) 264 { 265 case UM_EVENT_STATE_FOCUSED: 266 { 267 UpdateAccFocus(pXAcc); 268 if( selfAccObj ) 269 selfAccObj->UpdateDefaultAction( ); 270 UpdateValue(pXAcc); 271 NotifyWinEvent( EVENT_OBJECT_FOCUS,hAcc, OBJID_CLIENT,dChildID ); 272 break; 273 } 274 case UM_EVENT_STATE_BUSY: 275 NotifyWinEvent( EVENT_OBJECT_STATECHANGE,hAcc, OBJID_CLIENT,dChildID ); 276 break; 277 case UM_EVENT_STATE_CHECKED: 278 NotifyWinEvent( EVENT_OBJECT_STATECHANGE,hAcc, OBJID_CLIENT,dChildID ); 279 break; 280 case UM_EVENT_STATE_PRESSED: 281 NotifyWinEvent( EVENT_OBJECT_STATECHANGE,hAcc, OBJID_CLIENT,dChildID ); 282 break; 283 284 //Removed fire out selected event 285 //case UM_EVENT_STATE_SELECTED: 286 // NotifyWinEvent( EVENT_OBJECT_STATECHANGE,hAcc, OBJID_CLIENT,dChildID ); 287 // break; 288 case UM_EVENT_STATE_ARMED: 289 UpdateAccFocus(pXAcc); 290 NotifyWinEvent( EVENT_OBJECT_FOCUS,hAcc, OBJID_CLIENT,dChildID ); 291 break; 292 case UM_EVENT_MENU_START: 293 NotifyWinEvent( EVENT_SYSTEM_MENUSTART,hAcc, OBJID_CLIENT,dChildID ); 294 break; 295 case UM_EVENT_MENU_END: 296 NotifyWinEvent( EVENT_SYSTEM_MENUEND,hAcc, OBJID_CLIENT,dChildID ); 297 break; 298 case UM_EVENT_MENUPOPUPSTART: 299 NotifyWinEvent( EVENT_SYSTEM_MENUPOPUPSTART,hAcc, OBJID_CLIENT,dChildID ); 300 break; 301 case UM_EVENT_MENUPOPUPEND: 302 NotifyWinEvent( EVENT_SYSTEM_MENUPOPUPEND,hAcc, OBJID_CLIENT,dChildID ); 303 break; 304 case UM_EVENT_SELECTION_CHANGED: 305 NotifyWinEvent( EVENT_OBJECT_SELECTION,hAcc, OBJID_CLIENT,dChildID ); 306 break; 307 case UM_EVENT_SELECTION_CHANGED_ADD: 308 NotifyWinEvent( EVENT_OBJECT_SELECTIONADD,hAcc, OBJID_CLIENT,dChildID ); 309 break; 310 case UM_EVENT_SELECTION_CHANGED_REMOVE: 311 NotifyWinEvent( EVENT_OBJECT_SELECTIONREMOVE,hAcc, OBJID_CLIENT,dChildID ); 312 break; 313 case UM_EVENT_SELECTION_CHANGED_WITHIN: 314 NotifyWinEvent( EVENT_OBJECT_SELECTIONWITHIN,hAcc, OBJID_CLIENT,dChildID ); 315 break; 316 case UM_EVENT_OBJECT_VALUECHANGE: 317 UpdateValue(pXAcc); 318 NotifyWinEvent( EVENT_OBJECT_VALUECHANGE,hAcc, OBJID_CLIENT,dChildID ); 319 break; 320 case UM_EVENT_OBJECT_NAMECHANGE: 321 NotifyWinEvent( EVENT_OBJECT_NAMECHANGE,hAcc, OBJID_CLIENT,dChildID ); 322 break; 323 case UM_EVENT_OBJECT_DESCRIPTIONCHANGE: 324 NotifyWinEvent( EVENT_OBJECT_DESCRIPTIONCHANGE,hAcc, OBJID_CLIENT,dChildID ); 325 break; 326 case UM_EVENT_OBJECT_DEFACTIONCHANGE: 327 NotifyWinEvent( IA2_EVENT_ACTION_CHANGED,hAcc, OBJID_CLIENT,dChildID ); 328 break; 329 case UM_EVENT_OBJECT_CARETCHANGE: 330 NotifyWinEvent( IA2_EVENT_TEXT_CARET_MOVED,hAcc, OBJID_CLIENT,dChildID ); 331 break; 332 case UM_EVENT_OBJECT_TEXTCHANGE: 333 NotifyWinEvent( IA2_EVENT_TEXT_CHANGED,hAcc, OBJID_CLIENT,dChildID ); 334 break; 335 case UM_EVENT_ACTIVE_DESCENDANT_CHANGED: 336 UpdateAccFocus(pXAcc); 337 NotifyWinEvent( EVENT_OBJECT_FOCUS,hAcc, OBJID_CLIENT,dChildID ); 338 break; 339 case UM_EVENT_BOUNDRECT_CHANGED: 340 NotifyWinEvent( EVENT_OBJECT_LOCATIONCHANGE,hAcc, OBJID_CLIENT,dChildID ); 341 break; 342 case UM_EVENT_VISIBLE_DATA_CHANGED: 343 NotifyWinEvent( IA2_EVENT_VISIBLE_DATA_CHANGED,hAcc, OBJID_CLIENT,dChildID ); 344 break; 345 case UM_EVENT_SHOW : 346 NotifyWinEvent( EVENT_OBJECT_SHOW,hAcc, OBJID_CLIENT,dChildID ); 347 NotifyWinEvent( EVENT_SYSTEM_FOREGROUND,hAcc, OBJID_CLIENT,dChildID ); 348 break; 349 case UM_EVENT_TABLE_CAPTION_CHANGED: 350 NotifyWinEvent( IA2_EVENT_TABLE_CAPTION_CHANGED,hAcc, OBJID_CLIENT,dChildID ); 351 break; 352 case UM_EVENT_TABLE_COLUMN_DESCRIPTION_CHANGED: 353 NotifyWinEvent( IA2_EVENT_TABLE_COLUMN_DESCRIPTION_CHANGED,hAcc, OBJID_CLIENT,dChildID ); 354 break; 355 case UM_EVENT_TABLE_COLUMN_HEADER_CHANGED: 356 NotifyWinEvent( IA2_EVENT_TABLE_COLUMN_HEADER_CHANGED,hAcc, OBJID_CLIENT,dChildID ); 357 break; 358 case UM_EVENT_TABLE_MODEL_CHANGED: 359 NotifyWinEvent( IA2_EVENT_TABLE_MODEL_CHANGED,hAcc, OBJID_CLIENT,dChildID ); 360 break; 361 case UM_EVENT_TABLE_ROW_HEADER_CHANGED: 362 NotifyWinEvent( IA2_EVENT_TABLE_ROW_HEADER_CHANGED,hAcc, OBJID_CLIENT,dChildID ); 363 break; 364 case UM_EVENT_TABLE_SUMMARY_CHANGED: 365 NotifyWinEvent( IA2_EVENT_TABLE_SUMMARY_CHANGED,hAcc, OBJID_CLIENT,dChildID ); 366 break; 367 case UM_EVENT_TABLE_ROW_DESCRIPTION_CHANGED: 368 NotifyWinEvent( IA2_EVENT_TABLE_ROW_DESCRIPTION_CHANGED,hAcc, OBJID_CLIENT,dChildID ); 369 break; 370 case UM_EVENT_OBJECT_REORDER: 371 NotifyWinEvent( EVENT_OBJECT_REORDER,hAcc, OBJID_CLIENT,dChildID ); 372 break; 373 case UM_EVENT_PAGE_CHANGED: 374 NotifyWinEvent( IA2_EVENT_PAGE_CHANGED,hAcc, OBJID_CLIENT,dChildID ); 375 break; 376 case UM_EVENT_CHILD_REMOVED: 377 NotifyWinEvent( EVENT_OBJECT_DESTROY,hAcc, OBJID_CLIENT,dChildID ); 378 break; 379 case UM_EVENT_CHILD_ADDED: 380 NotifyWinEvent( EVENT_OBJECT_CREATE ,hAcc, OBJID_CLIENT,dChildID ); 381 break; 382 case UM_EVENT_OBJECT_PAGECHANGED: 383 NotifyWinEvent( IA2_EVENT_PAGE_CHANGED ,hAcc, OBJID_CLIENT,dChildID ); 384 break; 385 case UM_EVENT_TEXT_SELECTION_CHANGED: 386 NotifyWinEvent( IA2_EVENT_TEXT_SELECTION_CHANGED ,hAcc, OBJID_CLIENT,dChildID ); 387 break; 388 case UM_EVENT_SECTION_CHANGED: 389 NotifyWinEvent( IA2_EVENT_SECTION_CHANGED ,hAcc, OBJID_CLIENT,dChildID ); 390 break; 391 case UM_EVENT_COLUMN_CHANGED: 392 NotifyWinEvent( IA2_EVENT_TEXT_COLUMN_CHANGED ,hAcc, OBJID_CLIENT,dChildID ); 393 break; 394 default: 395 break; 396 } 397 398 return sal_True; 399 } 400 401 /** 402 * Get Parent XAccessible interface by XAccessible interface. 403 * @param pXAcc XAccessible interface. 404 * @return Parent XAccessible interface. 405 */ 406 XAccessible* AccObjectWinManager::GetParentXAccessible( XAccessible* pXAcc ) 407 { 408 AccObject* pObj= GetAccObjByXAcc(pXAcc); 409 if( pObj ==NULL ) 410 return NULL; 411 if(pObj->GetParentObj()) 412 { 413 pObj = pObj->GetParentObj(); 414 return pObj->GetXAccessible().get(); 415 } 416 return NULL; 417 } 418 419 /** 420 * Get Parent role by XAccessible interface. 421 * @param pXAcc XAccessible interface. 422 * @return Parent role. 423 */ 424 short AccObjectWinManager::GetParentRole( XAccessible* pXAcc ) 425 { 426 AccObject* pObj= GetAccObjByXAcc(pXAcc); 427 if( pObj ==NULL ) 428 return -1; 429 if(pObj->GetParentObj()) 430 { 431 pObj = pObj->GetParentObj(); 432 if(pObj->GetXAccessible().is()) 433 { 434 XAccessible* pXAcc = pObj->GetXAccessible().get(); 435 Reference< XAccessibleContext > pRContext = pXAcc->getAccessibleContext(); 436 if(pRContext.is()) 437 return pRContext->getAccessibleRole(); 438 } 439 } 440 return -1; 441 } 442 443 /** 444 * Update focus objcet by new focused XAccessible interface. 445 * @param newFocus New XAccessible interface that gets focus. 446 * @return 447 */ 448 void AccObjectWinManager::UpdateAccFocus(XAccessible* newFocus) 449 { 450 AccObject* pAccObjNew = GetAccObjByXAcc(newFocus); 451 if(pAccObjNew) 452 { 453 AccObject* pAccObjOld = GetAccObjByXAcc(oldFocus); 454 oldFocus = newFocus; 455 pAccObjNew->setFocus(); 456 //if old == new, the pAccObjNew will be without focused state 457 if (pAccObjOld && pAccObjOld != pAccObjNew) 458 pAccObjOld->unsetFocus(); 459 } 460 } 461 462 /** 463 * Update selected objcet by new focused XAccessible interface. 464 * @param pXAcc XAccessible interface that has selected child changed. 465 * @return Selected children count. 466 */ 467 int AccObjectWinManager::UpdateAccSelection(XAccessible* pXAcc) 468 { 469 XAccessibleSelection* pSelection = NULL; 470 Reference< XAccessibleContext > pRContext; 471 472 if( pXAcc == NULL) 473 return sal_False; 474 475 pRContext = pXAcc->getAccessibleContext(); 476 if( !pRContext.is() ) 477 return sal_False; 478 479 Reference< XAccessibleSelection > pRSelection(pRContext,UNO_QUERY); 480 if( !pRSelection.is() ) 481 return sal_False; 482 483 AccObject* pAccObj = GetAccObjByXAcc(pXAcc); 484 if(pAccObj==NULL) 485 return sal_False; 486 487 Reference<XAccessible> pRChild = NULL; 488 AccObject* pAccChildObj = NULL; 489 int selectNum= pRSelection->getSelectedAccessibleChildCount(); 490 491 IAccSelectionList oldSelection = pAccObj->GetSelection(); 492 493 if(selectNum > 4)//for selected. 494 return selectNum; 495 if(selectNum == 1 && oldSelection.size() == 0) 496 return 1; 497 498 for (int i=0;i<selectNum;i++) 499 { 500 pRChild = pRSelection->getSelectedAccessibleChild(i); 501 if(!pRChild.is()) 502 { 503 continue; 504 } 505 Reference<XAccessibleContext> pRChildContext = pRChild->getAccessibleContext(); 506 if(!pRChildContext.is()) 507 { 508 continue; 509 } 510 long index = pRChildContext->getAccessibleIndexInParent(); 511 IAccSelectionList::iterator temp = oldSelection.find(index); 512 if ( temp != oldSelection.end() ) 513 { 514 oldSelection.erase(index); 515 continue; 516 } 517 518 pAccChildObj = NULL; 519 pAccChildObj = GetAccObjByXAcc(pRChild.get()); 520 if(!pAccChildObj) 521 { 522 InsertAccObj(pRChild.get(), pXAcc,pAccObj->GetParentHWND()); 523 pAccChildObj = GetAccObjByXAcc(pRChild.get()); 524 } 525 526 pAccObj->AddSelect(index, pAccChildObj); 527 528 if(pAccChildObj != NULL) 529 NotifyWinEvent(EVENT_OBJECT_SELECTIONADD,pAccObj->GetParentHWND(), OBJID_CLIENT,pAccChildObj->GetResID()); 530 } 531 532 IAccSelectionList::iterator iter = oldSelection.begin(); 533 while(iter!=oldSelection.end()) 534 { 535 pAccObj->GetSelection().erase(iter->first); 536 pAccChildObj = (AccObject*)(iter->second); 537 if(pAccChildObj != NULL) 538 NotifyWinEvent(EVENT_OBJECT_SELECTIONREMOVE,pAccObj->GetParentHWND(), OBJID_CLIENT,pAccChildObj->GetResID()); 539 iter++; 540 } 541 return 0; 542 543 } 544 545 /** 546 * Delete child element from children list. 547 * @param pObj Child element that should be removed from parant child list. 548 * @return 549 */ 550 void AccObjectWinManager::DeleteAccChildNode( AccObject* pObj ) 551 { 552 AccObject *parentAccObj = pObj->GetParentObj(); 553 if( parentAccObj ) 554 parentAccObj->DeleteChild( pObj ); 555 } 556 557 /** 558 * Delete XAccessible items in top window handle hashtable 559 * @param pXAcc XAccessible interface. 560 * @return 561 */ 562 void AccObjectWinManager::DeleteFromHwndXAcc(XAccessible* pXAcc ) 563 { 564 XHWNDToXAccHash::iterator iter = HwndXAcc.begin(); 565 while(iter!=HwndXAcc.end()) 566 { 567 if(iter->second == pXAcc ) 568 { 569 HwndXAcc.erase(iter); 570 return; 571 } 572 iter++; 573 } 574 } 575 576 /** 577 * Delete Delete all children with the tree root of XAccessible pointer 578 * @param pXAcc Tree root XAccessible interface. 579 * @return 580 */ 581 void AccObjectWinManager::DeleteChildrenAccObj(XAccessible* pXAcc) 582 { 583 vos::OGuard aGuard( aDeleteMutex ); 584 AccObject* currentObj=NULL; 585 AccObject* childObj=NULL; 586 XAccessible* pTmpXAcc=NULL; 587 588 currentObj = GetAccObjByXAcc( pXAcc); 589 if(currentObj) 590 { 591 childObj = currentObj->NextChild(); 592 while(childObj) 593 { 594 pTmpXAcc = GetXAccByAccObj(childObj); 595 if(pTmpXAcc) 596 { 597 DeleteChildrenAccObj(pTmpXAcc); 598 DeleteAccObj(pTmpXAcc); 599 } 600 childObj = currentObj->NextChild(); 601 } 602 } 603 } 604 605 /** 606 * Delete Delete Acc object self. 607 * @param pXAcc The XAccessible interface. 608 * @return 609 */ 610 void AccObjectWinManager::DeleteAccObj( XAccessible* pXAcc ) 611 { 612 vos::OGuard aGuard( aDeleteMutex ); 613 if( pXAcc == NULL ) 614 return; 615 XIdToAccObjHash::iterator temp = XIdAccList.find(pXAcc); 616 if( temp != XIdAccList.end() ) 617 { 618 ResIdGen.SetSub( temp->second.GetResID() ); 619 } 620 else 621 { 622 return; 623 } 624 625 AccObject& accObj = temp->second; 626 DeleteAccChildNode( &accObj ); 627 DeleteAccListener( &accObj ); 628 if( accObj.GetIMAccessible() ) 629 { 630 accObj.GetIMAccessible()->Release(); 631 } 632 XIdAccList.erase( pXAcc ); 633 XResIdAccList.erase( accObj.GetResID() ); 634 DeleteFromHwndXAcc(pXAcc); 635 } 636 637 /** 638 * Delete listener that inspects some XAccessible object 639 * @param pAccObj Accobject pointer. 640 * @return 641 */ 642 void AccObjectWinManager::DeleteAccListener( AccObject* pAccObj ) 643 { 644 AccEventListener* listener = pAccObj->getListener(); 645 if( listener==NULL ) 646 return; 647 listener->removeMeFromBroadcaster(); 648 pAccObj->SetListener(NULL); 649 } 650 651 /** 652 * Generate a child ID, which is used for AT 653 * @param 654 * @return New resource ID. 655 */ 656 inline long AccObjectWinManager::ImpleGenerateResID() 657 { 658 return ResIdGen.GenerateNewResID(); 659 } 660 661 /** 662 * Insert all children of the current acc object 663 * @param pXAcc XAccessible interface 664 * @param pWnd Top Window handle 665 * @return The calling result. 666 */ 667 sal_Bool AccObjectWinManager::InsertChildrenAccObj( com::sun::star::accessibility::XAccessible* pXAcc, 668 HWND pWnd) 669 { 670 if(!IsContainer(pXAcc)) 671 return sal_False; 672 673 Reference< XAccessibleContext > pRContext; 674 675 if( pXAcc == NULL) 676 return sal_False; 677 pRContext = pXAcc->getAccessibleContext(); 678 if( !pRContext.is() ) 679 return sal_False; 680 681 short role = pRContext->getAccessibleRole(); 682 683 if(com::sun::star::accessibility::AccessibleRole::DOCUMENT == role ) 684 { 685 if(IsStateManageDescendant(pXAcc)) 686 { 687 return sal_True; 688 } 689 } 690 691 int count = pRContext->getAccessibleChildCount(); 692 for (int i=0;i<count;i++) 693 { 694 Reference<XAccessible> mxAccessible 695 = pRContext->getAccessibleChild(i); 696 XAccessible* mpAccessible = mxAccessible.get(); 697 if(mpAccessible != NULL) 698 { 699 InsertAccObj( mpAccessible,pXAcc,pWnd ); 700 InsertChildrenAccObj(mpAccessible,pWnd); 701 } 702 } 703 704 return sal_True; 705 } 706 707 /** 708 * Insert child object. 709 * @param pCurObj The child object 710 * @param pParentObj The parant object 711 * @param pWnd Top window handle. 712 * @return 713 */ 714 void AccObjectWinManager::InsertAccChildNode( AccObject* pCurObj, AccObject* pParentObj, HWND /* pWnd */ ) 715 { 716 if(pCurObj) 717 { 718 if(pParentObj) 719 { 720 pParentObj->InsertChild(pCurObj); 721 } 722 else 723 { 724 pCurObj->UpdateValidWindow(); 725 } 726 } 727 } 728 729 /** 730 * Insert child object. 731 * @param pCurObj The child object 732 * @param pParentObj The parant object 733 * @param pWnd Top window handle. 734 * @return 735 */ 736 sal_Bool AccObjectWinManager::InsertAccObj( XAccessible* pXAcc,XAccessible* pParentXAcc,HWND pWnd ) 737 { 738 if (!m_bBridgeRegistered) 739 { 740 return sal_False; 741 } 742 XIdToAccObjHash::iterator itXacc = XIdAccList.find( (void*)pXAcc ); 743 if (itXacc != XIdAccList.end() ) 744 { 745 short nCurRole =GetRole(pXAcc); 746 if (AccessibleRole::SHAPE == nCurRole) 747 { 748 AccObject &objXacc = itXacc->second; 749 AccObject *pObjParent = objXacc.GetParentObj(); 750 if (pObjParent && 751 pObjParent->GetXAccessible().is() && 752 pObjParent->GetXAccessible().get() != pParentXAcc) 753 { 754 XIdToAccObjHash::iterator itXaccParent = XIdAccList.find( (void*)pParentXAcc ); 755 if(itXaccParent != XIdAccList.end()) 756 { 757 objXacc.SetParentObj(&(itXaccParent->second)); 758 } 759 } 760 } 761 return sal_False; 762 } 763 764 765 Reference< XAccessibleContext > pRContext; 766 767 if( pXAcc == NULL) 768 return sal_False; 769 770 pRContext = pXAcc->getAccessibleContext(); 771 if( !pRContext.is() ) 772 return sal_False; 773 774 if( pWnd == NULL ) 775 { 776 if(pParentXAcc) 777 { 778 AccObject* pObj = GetAccObjByXAcc(pParentXAcc); 779 if(pObj) 780 pWnd = pObj->GetParentHWND(); 781 } 782 if( pWnd == NULL ) 783 return sal_False; 784 } 785 786 AccObject pObj( pXAcc,pAgent ); 787 if( pObj.GetIMAccessible() == NULL ) 788 return sal_False; 789 pObj.SetResID( this->ImpleGenerateResID()); 790 pObj.SetParentHWND( pWnd ); 791 792 //for file name support 793 if ( pObj.GetRole() == DOCUMENT ) 794 { 795 XHWNDToDocumentHash::iterator aIter = XHWNDDocList.find( (long)pWnd ); 796 if ( aIter != XHWNDDocList.end() ) 797 { 798 XHWNDDocList.erase( aIter ); 799 } 800 XHWNDDocList.insert( XHWNDToDocumentHash::value_type( (long)pWnd, pXAcc ) ); 801 802 } 803 //end of file name 804 805 AccEventListener* listener = createAccEventListener(pXAcc, pAgent); 806 if(listener==NULL) 807 return sal_False; 808 Reference<XAccessibleComponent> xComponent(pRContext,UNO_QUERY); 809 Reference<XAccessibleEventBroadcaster> broadcaster(xComponent,UNO_QUERY); 810 if (broadcaster.is()) 811 { 812 Reference <XAccessibleEventListener> pp ( 813 static_cast< XAccessibleEventListener* >(listener),UNO_QUERY ); 814 if(pp.is()) 815 { 816 broadcaster->addEventListener(pp); 817 } 818 else 819 { 820 delete listener; 821 return sal_False; 822 } 823 } 824 else 825 return sal_False; 826 827 XIdAccList.insert( XIdToAccObjHash::value_type( (void*)pXAcc, pObj )); 828 XIdToAccObjHash::iterator pIndTemp = XIdAccList.find( (void*)pXAcc ); 829 XResIdAccList.insert(XResIdToAccObjHash::value_type(pObj.GetResID(),&(pIndTemp->second))); 830 831 AccObject* pCurObj = GetAccObjByXAcc(pXAcc); 832 if( pCurObj ) 833 { 834 pCurObj->SetListener( listener ); 835 if(listener != NULL) 836 listener->acquire(); 837 } 838 839 AccObject* pParentObj = GetAccObjByXAcc(pParentXAcc); 840 InsertAccChildNode(pCurObj,pParentObj,pWnd); 841 if( pCurObj ) 842 pCurObj->UpdateAccessibleInfoFromUnoToMSAA(); 843 return sal_True; 844 } 845 846 847 /** 848 * save the pair <topwindowhandle, XAccessible> 849 * @param hWnd, top window handle 850 * @param pXAcc XAccessible interface for top window 851 * @return void 852 */ 853 void AccObjectWinManager::SaveTopWindowHandle(HWND hWnd, com::sun::star::accessibility::XAccessible* pXAcc) 854 { 855 HwndXAcc.insert( XHWNDToXAccHash::value_type( hWnd,(void*)pXAcc ) ); 856 } 857 858 859 /** 860 * create the corresponding listener. 861 * @param pXAcc XAccessible interface. 862 * @param Agent The agent kept in all listeners,it's the sole interface by which 863 * listener communicate with windows manager. 864 * @return 865 */ 866 AccEventListener* AccObjectWinManager::createAccEventListener(XAccessible* pXAcc, AccObjectManagerAgent* /* Agent */ ) 867 { 868 AccEventListener* listener = NULL; 869 Reference<XAccessibleContext> xContext(pXAcc->getAccessibleContext(),UNO_QUERY); 870 if(xContext.is()) 871 { 872 switch( xContext->getAccessibleRole() ) 873 { 874 case /*AccessibleRole::*/DIALOG: 875 listener = new AccDialogEventListener(pXAcc,pAgent); 876 break; 877 case /*AccessibleRole::*/FRAME: 878 listener = new AccFrameEventListener(pXAcc,pAgent); 879 break; 880 case /*AccessibleRole::*/WINDOW: 881 listener = new AccWindowEventListener(pXAcc,pAgent); 882 break; 883 case /*AccessibleRole::*/ROOT_PANE: 884 listener = new AccFrameEventListener(pXAcc,pAgent); 885 break; 886 //Container 887 case /*AccessibleRole::*/CANVAS: 888 case /*AccessibleRole::*/COMBO_BOX: 889 case /*AccessibleRole::*/DOCUMENT: 890 case /*AccessibleRole::*/END_NOTE: 891 case /*AccessibleRole::*/FILLER: 892 case /*AccessibleRole::*/FOOTNOTE: 893 case /*AccessibleRole::*/FOOTER: 894 case /*AccessibleRole::*/HEADER: 895 case /*AccessibleRole::*/LAYERED_PANE: 896 case /*AccessibleRole::*/MENU_BAR: 897 case /*AccessibleRole::*/POPUP_MENU: 898 case /*AccessibleRole::*/OPTION_PANE: 899 case /*AccessibleRole::*/PAGE_TAB: 900 case /*AccessibleRole::*/PAGE_TAB_LIST: 901 case /*AccessibleRole::*/PANEL: 902 case /*AccessibleRole::*/SCROLL_PANE: 903 case /*AccessibleRole::*/SPLIT_PANE: 904 case /*AccessibleRole::*/STATUS_BAR: 905 case /*AccessibleRole::*/TABLE_CELL: 906 case /*AccessibleRole::*/TOOL_BAR: 907 case /*AccessibleRole::*/VIEW_PORT: 908 listener = new AccContainerEventListener(pXAcc,pAgent); 909 break; 910 case /*AccessibleRole::*/PARAGRAPH: 911 case /*AccessibleRole::*/HEADING: 912 listener = new AccParagraphEventListener(pXAcc,pAgent); 913 break; 914 //Component 915 case /*AccessibleRole::*/CHECK_BOX: 916 case /*AccessibleRole::*/ICON: 917 case /*AccessibleRole::*/LABEL: 918 case /*AccessibleRole::*/MENU_ITEM: 919 case /*AccessibleRole::*/CHECK_MENU_ITEM: 920 case /*AccessibleRole::*/RADIO_MENU_ITEM: 921 case /*AccessibleRole::*/PUSH_BUTTON: 922 case /*AccessibleRole::*/RADIO_BUTTON: 923 case /*AccessibleRole::*/SCROLL_BAR: 924 case /*AccessibleRole::*/SEPARATOR: 925 case /*AccessibleRole::*/TOGGLE_BUTTON: 926 case /*AccessibleRole::*/BUTTON_DROPDOWN: 927 case /*AccessibleRole::*/TOOL_TIP: 928 case /*AccessibleRole::*/SPIN_BOX: 929 case DATE_EDITOR: 930 listener = new AccComponentEventListener(pXAcc,pAgent); 931 break; 932 //text component 933 case /*AccessibleRole::*/TEXT: 934 listener = new AccTextComponentEventListener(pXAcc,pAgent); 935 break; 936 //menu 937 case /*AccessibleRole::*/MENU: 938 listener = new AccMenuEventListener(pXAcc,pAgent); 939 break; 940 //object container 941 case /*AccessibleRole::*/SHAPE: 942 943 case /*AccessibleRole::*/EMBEDDED_OBJECT: 944 case /*AccessibleRole::*/GRAPHIC: 945 case /*AccessibleRole::*/TEXT_FRAME: 946 listener = new AccObjectContainerEventListener(pXAcc,pAgent); 947 break; 948 //descendmanager 949 case /*AccessibleRole::*/LIST: 950 listener = new AccListEventListener(pXAcc,pAgent); 951 break; 952 case /*AccessibleRole::*/TREE: 953 listener = new AccTreeEventListener(pXAcc,pAgent); 954 break; 955 //special 956 case /*AccessibleRole::*/COLUMN_HEADER: 957 case /*AccessibleRole::*/TABLE: 958 listener = new AccTableEventListener(pXAcc,pAgent); 959 break; 960 default: 961 listener = new AccContainerEventListener(pXAcc,pAgent); 962 break; 963 } 964 } 965 966 return listener; 967 } 968 969 /** 970 * state is a combination integer, each bit of which represents a single state, 971 * such as focused,1 for the state on,0 for the state off. Here call COM interface 972 * to modify the state value, including DecreaseState. 973 * @param pXAcc XAccessible interface. 974 * @param pState Changed state. 975 * @return 976 */ 977 void AccObjectWinManager::DecreaseState( XAccessible* pXAcc,unsigned short pState ) 978 { 979 AccObject* pAccObj = GetAccObjByXAcc( pXAcc ); 980 if( pAccObj ) 981 pAccObj->DecreaseState( pState ); 982 } 983 984 /** 985 * state is a combination integer, each bit of which represents a single state,such as focused,1 for 986 * the state on,0 for the state off. Here call COM interface to modify the state value, including 987 * IncreaseState. 988 * @param pXAcc XAccessible interface. 989 * @param pState Changed state. 990 * @return 991 */ 992 void AccObjectWinManager::IncreaseState( XAccessible* pXAcc,unsigned short pState ) 993 { 994 AccObject* pAccObj = GetAccObjByXAcc( pXAcc ); 995 if( pAccObj ) 996 pAccObj->IncreaseState( pState ); 997 } 998 999 void AccObjectWinManager::UpdateState( com::sun::star::accessibility::XAccessible* pXAcc ) 1000 { 1001 AccObject* pAccObj = GetAccObjByXAcc( pXAcc ); 1002 if( pAccObj ) 1003 pAccObj->UpdateState( ); 1004 } 1005 1006 /** 1007 * Set corresponding com object's accessible name via XAccessilbe interface and new 1008 * name 1009 * @param pXAcc XAccessible interface. 1010 * @return 1011 */ 1012 void AccObjectWinManager::UpdateAccName( XAccessible* pXAcc ) 1013 { 1014 AccObject* pAccObj = GetAccObjByXAcc( pXAcc ); 1015 if( pAccObj ) 1016 pAccObj->UpdateName(); 1017 } 1018 1019 void AccObjectWinManager::UpdateAction( XAccessible* pXAcc ) 1020 { 1021 AccObject* pAccObj = GetAccObjByXAcc( pXAcc ); 1022 if( pAccObj ) 1023 pAccObj->UpdateAction(); 1024 } 1025 1026 void AccObjectWinManager::UpdateDescription( XAccessible* pXAcc ) 1027 { 1028 AccObject* pAccObj = GetAccObjByXAcc( pXAcc ); 1029 if ( pAccObj ) 1030 pAccObj->UpdateDescription(); 1031 } 1032 1033 /** 1034 * Set corresponding com object's accessible location via XAccessilbe interface and new 1035 * location. 1036 * @param pXAcc XAccessible interface. 1037 * @return 1038 */ 1039 void AccObjectWinManager::SetLocation( XAccessible* pXAcc, long /*top*/, long /*left*/, long /*width*/, long /*height*/ ) 1040 { 1041 AccObject* pObj = GetAccObjByXAcc( pXAcc ); 1042 //get the location from XComponent. 1043 Reference< XAccessibleContext > pRContext = pXAcc->getAccessibleContext(); 1044 if( pObj ) 1045 pObj->UpdateLocation(); 1046 } 1047 1048 /** 1049 * Set corresponding com object's value via XAccessilbe interface and new value. 1050 * @param pXAcc XAccessible interface. 1051 * @param pAny new value. 1052 * @return 1053 */ 1054 void AccObjectWinManager::SetValue( XAccessible* pXAcc, Any pAny ) 1055 { 1056 AccObject* pAccObj = GetAccObjByXAcc( pXAcc ); 1057 if( pAccObj ) 1058 pAccObj->SetValue( pAny ); 1059 } 1060 1061 /** 1062 * Set corresponding com object's value via XAccessilbe interface. 1063 * @param pXAcc XAccessible interface. 1064 * @return 1065 */ 1066 void AccObjectWinManager::UpdateValue( XAccessible* pXAcc ) 1067 { 1068 AccObject* pAccObj = GetAccObjByXAcc( pXAcc ); 1069 if( pAccObj ) 1070 pAccObj->UpdateValue(); 1071 } 1072 1073 /** 1074 * Set corresponding com object's name via XAccessilbe interface and new name. 1075 * @param pXAcc XAccessible interface. 1076 * @param newName new name 1077 * @return 1078 */ 1079 void AccObjectWinManager::SetAccName( XAccessible* pXAcc, Any newName) 1080 { 1081 AccObject* pAccObj = GetAccObjByXAcc( pXAcc ); 1082 if( pAccObj ) 1083 pAccObj->SetName( newName ); 1084 } 1085 1086 /** 1087 * Set corresponding com object's description via XAccessilbe interface and new description. 1088 * @param pXAcc XAccessible interface. 1089 * @param newDesc new description 1090 * @return 1091 */ 1092 void AccObjectWinManager::SetDescription( XAccessible* pXAcc, Any newDesc ) 1093 { 1094 AccObject* pAccObj = GetAccObjByXAcc( pXAcc ); 1095 if( pAccObj ) 1096 pAccObj->SetDescription( newDesc ); 1097 } 1098 1099 /** 1100 * Set corresponding com object's role via XAccessilbe interface and new role. 1101 * @param pXAcc XAccessible interface. 1102 * @param Role new role 1103 * @return 1104 */ 1105 void AccObjectWinManager::SetRole( XAccessible* pXAcc, long Role ) 1106 { 1107 AccObject* pAccObj = GetAccObjByXAcc( pXAcc ); 1108 if( pAccObj ) 1109 pAccObj->SetRole( (short)Role ); 1110 } 1111 1112 /** 1113 * Judge if a XAccessible object is a container object. 1114 * @param pAccessible XAccessible interface. 1115 * @return If XAccessible object is container. 1116 */ 1117 sal_Bool AccObjectWinManager::IsContainer(XAccessible* pAccessible) 1118 { 1119 try 1120 { 1121 if(pAccessible) 1122 { 1123 Reference<XAccessibleContext> xContext(pAccessible->getAccessibleContext(),UNO_QUERY); 1124 if(xContext.is()) 1125 { 1126 switch( xContext->getAccessibleRole() ) 1127 { 1128 case /*AccessibleRole::*/DIALOG: 1129 case /*AccessibleRole::*/FRAME: 1130 case /*AccessibleRole::*/WINDOW: 1131 case /*AccessibleRole::*/ROOT_PANE: 1132 case /*AccessibleRole::*/CANVAS: 1133 case /*AccessibleRole::*/COMBO_BOX: 1134 case /*AccessibleRole::*/DOCUMENT: 1135 case /*AccessibleRole::*/EMBEDDED_OBJECT: 1136 case /*AccessibleRole::*/END_NOTE: 1137 case /*AccessibleRole::*/FILLER: 1138 case /*AccessibleRole::*/FOOTNOTE: 1139 case /*AccessibleRole::*/FOOTER: 1140 case /*AccessibleRole::*/GRAPHIC: 1141 case /*AccessibleRole::*/GROUP_BOX: 1142 case /*AccessibleRole::*/HEADER: 1143 case /*AccessibleRole::*/LAYERED_PANE: 1144 case /*AccessibleRole::*/MENU_BAR: 1145 case /*AccessibleRole::*/POPUP_MENU: 1146 case /*AccessibleRole::*/OPTION_PANE: 1147 case /*AccessibleRole::*/PAGE_TAB: 1148 case /*AccessibleRole::*/PAGE_TAB_LIST: 1149 case /*AccessibleRole::*/PANEL: 1150 case /*AccessibleRole::*/SCROLL_PANE: 1151 case /*AccessibleRole::*/SPLIT_PANE: 1152 case /*AccessibleRole::*/STATUS_BAR: 1153 case /*AccessibleRole::*/TABLE_CELL: 1154 case /*AccessibleRole::*/TEXT_FRAME: 1155 case /*AccessibleRole::*/TOOL_BAR: 1156 case /*AccessibleRole::*/VIEW_PORT: 1157 case /*AccessibleRole::*/SHAPE: 1158 return sal_True; 1159 break; 1160 case /*AccessibleRole::*/COLUMN_HEADER: 1161 case /*AccessibleRole::*/TABLE: 1162 if(!IsStateManageDescendant(pAccessible)) 1163 return sal_True; 1164 break; 1165 case /*AccessibleRole::*/MENU: 1166 return sal_True; 1167 break; 1168 default: 1169 return sal_False; 1170 } 1171 } 1172 } 1173 } 1174 catch(...) 1175 { 1176 return sal_False; 1177 } 1178 return sal_False; 1179 } 1180 1181 /** 1182 * Judge if a XAccessible object has ManageDescendant event. 1183 * @param pAccessible XAccessible interface. 1184 * @return If XAccessible object is managedescendant. 1185 */ 1186 bool AccObjectWinManager::IsStateManageDescendant(XAccessible* pAccessible) 1187 { 1188 if(pAccessible) 1189 { 1190 Reference<XAccessibleContext> xContext(pAccessible->getAccessibleContext(),UNO_QUERY); 1191 if(xContext.is()) 1192 { 1193 Reference< XAccessibleStateSet > pRState = xContext->getAccessibleStateSet(); 1194 if( !pRState.is() ) 1195 return sal_False; 1196 1197 Sequence<short> pStates = pRState->getStates(); 1198 int count = pStates.getLength(); 1199 for( int iIndex = 0;iIndex < count;iIndex++ ) 1200 { 1201 if(pStates[iIndex] == /*AccessibleStateType::*/MANAGES_DESCENDANTS) 1202 return sal_True; 1203 } 1204 } 1205 } 1206 return sal_False; 1207 } 1208 1209 /** 1210 * Query and get IAccessible interface by XAccessible interface from list. 1211 * @param pXAcc XAccessible interface. 1212 * @return Com accobject interface. 1213 */ 1214 IMAccessible* AccObjectWinManager::GetIMAccByXAcc(XAccessible* pXAcc) 1215 { 1216 AccObject* pAccObj = GetAccObjByXAcc(pXAcc); 1217 if(pAccObj) 1218 { 1219 return pAccObj->GetIMAccessible(); 1220 } 1221 else 1222 { 1223 return NULL; 1224 } 1225 } 1226 1227 /** 1228 * Query and get IAccessible interface by child id from list. 1229 * @param resID, childID. 1230 * @return Com accobject interface. 1231 */ 1232 IMAccessible * AccObjectWinManager::GetIAccessibleFromResID(long resID) 1233 { 1234 XResIdToAccObjHash::iterator pIndTemp = XResIdAccList.find( resID ); 1235 if ( pIndTemp == XResIdAccList.end() ) 1236 return NULL; 1237 1238 AccObject* pObj = pIndTemp->second; 1239 1240 if(pObj->GetIMAccessible()) 1241 return pObj->GetIMAccessible(); 1242 return NULL; 1243 } 1244 /** 1245 * Notify some object will be destroyed. 1246 * @param pXAcc XAccessible interface. 1247 * @return Com accobject interface. 1248 */ 1249 void AccObjectWinManager::NotifyDestroy(XAccessible* pXAcc) 1250 { 1251 AccObject* accObj = GetAccObjByXAcc(pXAcc); 1252 if(accObj) 1253 { 1254 accObj->NotifyDestroy(sal_True); 1255 } 1256 } 1257 1258 1259 void AccObjectWinManager::UpdateChildState(com::sun::star::accessibility::XAccessible* pAccSubMenu) 1260 { 1261 Reference<com::sun::star::accessibility::XAccessibleContext> xContext(pAccSubMenu,UNO_QUERY); 1262 if (!xContext.is()) 1263 { 1264 return; 1265 } 1266 sal_Int32 nCount = xContext->getAccessibleChildCount(); 1267 for (sal_Int32 i = 0 ; i < nCount ; ++i) 1268 { 1269 Reference<com::sun::star::accessibility::XAccessible> xChild = xContext->getAccessibleChild(i); 1270 if (xChild.is()) 1271 { 1272 AccObject *pObj = GetAccObjByXAcc(xChild.get()); 1273 if (pObj) 1274 { 1275 pObj->UpdateState(); 1276 } 1277 } 1278 } 1279 } 1280 1281 1282 bool AccObjectWinManager::IsSpecialToolboItem(com::sun::star::accessibility::XAccessible* pXAcc) 1283 { 1284 if (pXAcc && oldFocus != pXAcc) 1285 { 1286 if(GetParentRole(pXAcc) == TOOL_BAR) 1287 { 1288 Reference< XAccessibleContext > pRContext(pXAcc->getAccessibleContext()); 1289 if (pRContext.is()) 1290 { 1291 if(pRContext->getAccessibleRole() == TOGGLE_BUTTON) 1292 { 1293 return true; 1294 } 1295 } 1296 } 1297 } 1298 return false; 1299 } 1300 1301 short AccObjectWinManager::GetRole(com::sun::star::accessibility::XAccessible* pXAcc) 1302 { 1303 assert(pXAcc != NULL); 1304 Reference<com::sun::star::accessibility::XAccessibleContext> xContext(pXAcc->getAccessibleContext(),UNO_QUERY); 1305 if(xContext.is()) 1306 { 1307 return xContext->getAccessibleRole(); 1308 } 1309 return -1; 1310 } 1311 1312 XAccessible* AccObjectWinManager::GetAccDocByHWND( long pWnd ) 1313 { 1314 XHWNDToDocumentHash::iterator aIter; 1315 aIter = XHWNDDocList.find( pWnd ); 1316 if ( aIter != XHWNDDocList.end() ) 1317 { 1318 return aIter->second; 1319 } 1320 1321 return NULL; 1322 } 1323 1324 XAccessible* AccObjectWinManager::GetAccDocByAccTopWin( XAccessible* pXAcc ) 1325 { 1326 AccObject* pAccObj = GetAccObjByXAcc( pXAcc ); 1327 long pWnd = (long)( pAccObj->GetParentHWND() ); 1328 return GetAccDocByHWND( pWnd ); 1329 } 1330 1331 bool AccObjectWinManager::IsTopWinAcc( com::sun::star::accessibility::XAccessible* pXAcc ) 1332 { 1333 bool bRet = false; 1334 AccObject* pAccObj = GetAccObjByXAcc( pXAcc ); 1335 if ( pAccObj ) 1336 { 1337 bRet = ( pAccObj->GetParentObj() == NULL ); 1338 } 1339 return bRet; 1340 } 1341