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 <com/sun/star/uno/Sequence.h> 30 #include <com/sun/star/accessibility/AccessibleStateType.hpp> 31 #include <com/sun/star/accessibility/AccessibleRole.hpp> 32 #include <com/sun/star/accessibility/XAccessibleValue.hpp> 33 #include <com/sun/star/accessibility/XAccessibleComponent.hpp> 34 #include <com/sun/star/accessibility/XAccessibleText.hpp> 35 36 #include <stdlib.h> 37 #include <memory.h> 38 #include <stdio.h> 39 #include <memory.h> 40 #include <algorithm> 41 #include <assert.h> 42 43 #include "AccObject.hxx" 44 #include "AccEventListener.hxx" 45 #include "UAccCOM_i.c" 46 #include "AccResource.hxx" 47 #include "AccessibleRole.h" 48 49 50 51 52 using namespace std; 53 using namespace com::sun::star::uno; 54 using namespace com::sun::star::accessibility; 55 using namespace com::sun::star::accessibility::AccessibleRole; 56 using namespace com::sun::star::accessibility::AccessibleStateType; 57 58 59 /** 60 * Constructor. 61 * @param pXAcc Uno XAccessible interface of control. 62 * @param Agent The agent kept in all listeners,it's the sole interface by which 63 * listener communicate with windows manager. 64 * @param listener listener that registers in UNO system. 65 * @return. 66 */ 67 AccObject::AccObject(XAccessible* pAcc,AccObjectManagerAgent* pAgent ,AccEventListener* listener) : 68 m_pIMAcc (NULL), 69 m_resID (NULL), 70 m_pParantID (NULL), 71 m_pParentObj(NULL), 72 m_accListener (listener), 73 m_bShouldDestroy(sal_False), 74 m_xAccRef( pAcc ) 75 { 76 sal_Bool bRet = ImplInitilizeCreateObj(); 77 78 m_xAccContextRef = m_xAccRef->getAccessibleContext(); 79 m_xAccActionRef = Reference< XAccessibleAction > (m_xAccContextRef,UNO_QUERY); 80 m_accRole = m_xAccContextRef -> getAccessibleRole(); 81 if( m_pIMAcc ) 82 { 83 m_pIMAcc->SetXAccessible((long) m_xAccRef.get()); 84 m_pIMAcc->Put_XAccAgent((long)pAgent); 85 m_pIMAcc->SetDefaultAction((long)m_xAccActionRef.get()); 86 } 87 } 88 /** 89 * Destructor. 90 * @param 91 * @return 92 */ 93 AccObject::~AccObject() 94 { 95 m_pIMAcc = NULL; 96 m_xAccRef = NULL; 97 m_xAccActionRef = NULL; 98 m_xAccContextRef = NULL; 99 } 100 101 102 103 /** 104 * Insert a child element. 105 * @param pChild Child element that should be inserted into child list. 106 * @param pos Insert postion. 107 * @return 108 */ 109 void AccObject::InsertChild( AccObject* pChild,short pos ) 110 { 111 112 std::vector<AccObject*>::iterator iter; 113 iter = std::find(m_childrenList.begin(),m_childrenList.end(),pChild); 114 if(iter!=m_childrenList.end()) 115 return; 116 if(LAST_CHILD==pos) 117 { 118 m_childrenList.push_back(pChild); 119 } 120 else 121 { 122 std::vector<AccObject*>::iterator iter=m_childrenList.begin()+pos; 123 m_childrenList.insert(iter,pChild); 124 } 125 126 pChild->SetParentObj(this); 127 } 128 129 /** 130 * Delete a child element 131 * @param pChild Child element that should be inserted into child list. 132 * @param pos Insert postion. 133 * @return 134 */ 135 void AccObject::DeleteChild( AccObject* pChild ) 136 { 137 std::vector<AccObject*>::iterator iter; 138 iter = std::find(m_childrenList.begin(),m_childrenList.end(),pChild); 139 if(iter!=m_childrenList.end()) 140 { 141 m_childrenList.erase(iter); 142 if(m_pIMAcc) 143 pChild->SetParentObj(NULL); 144 } 145 } 146 147 /** 148 * In order to windows API WindowFromAccessibleObject,we sometimes to set a pure 149 * top window accessible object created by windows system as top ancestor. 150 * @param. 151 * @return 152 */ 153 void AccObject::UpdateValidWindow() 154 { 155 if(m_pIMAcc) 156 m_pIMAcc->Put_XAccWindowHandle(m_pParantID); 157 } 158 159 /** 160 * Translate all UNO basic information into MSAA com information. 161 * @param 162 * @return If the method is correctly processed. 163 */ 164 sal_Bool AccObject::ImplInitilizeCreateObj() 165 { 166 167 if ( S_OK != CoCreateInstance( CLSID_MAccessible, NULL, CLSCTX_ALL , 168 IID_IMAccessible, 169 (void **)&m_pIMAcc 170 ) 171 ) 172 { 173 return sal_False; 174 } 175 176 return sal_True; 177 } 178 179 /** 180 * Update name property to com object. 181 * @param 182 * @return 183 */ 184 void AccObject::UpdateName( ) 185 { 186 if (!m_pIMAcc) 187 { 188 return; 189 } 190 191 if( ( TEXT_FRAME == m_accRole ) && ( m_pParentObj !=NULL )&& ( SCROLL_PANE == m_pParentObj -> m_accRole ) ) 192 m_pIMAcc->Put_XAccName( m_pParentObj->m_xAccContextRef->getAccessibleName().getStr() ); 193 //IAccessibility2 Implementation 2009----- 194 if ( PARAGRAPH == m_accRole) 195 { 196 ::rtl::OUString emptyStr = ::rtl::OUString::createFromAscii(""); 197 m_pIMAcc->Put_XAccName(emptyStr.getStr()); 198 } 199 //-----IAccessibility2 Implementation 2009 200 else 201 m_pIMAcc->Put_XAccName(m_xAccContextRef->getAccessibleName().getStr()); 202 203 return ; 204 } 205 /** 206 * Update description property to com object. 207 * no content for update description 208 * @param 209 * @return 210 */ 211 void AccObject::UpdateDescription() 212 { 213 if (!m_pIMAcc) 214 { 215 return; 216 } 217 218 m_pIMAcc->Put_XAccDescription(m_xAccContextRef->getAccessibleDescription().getStr()); 219 return ; 220 } 221 222 /** 223 * Update default action property to com object. 224 * @param 225 * @return 226 */ 227 void AccObject::UpdateAction() 228 { 229 m_xAccActionRef = Reference< XAccessibleAction > (m_xAccContextRef,UNO_QUERY); 230 231 if( m_xAccActionRef.is() && m_pIMAcc ) 232 { 233 if( m_xAccActionRef->getAccessibleActionCount() > 0 ) 234 { 235 UpdateDefaultAction( ); 236 m_pIMAcc->SetDefaultAction((long)m_xAccActionRef.get()); 237 } 238 } 239 } 240 241 /** 242 * Update value property to com object. 243 * @param 244 * @return 245 */ 246 void AccObject::UpdateValue() 247 { 248 if( NULL == m_pIMAcc || !m_xAccContextRef.is() ) 249 { 250 assert(false); 251 return ; 252 } 253 254 Reference< XAccessibleValue > pRValue(m_xAccContextRef.get(),UNO_QUERY); 255 Any pAny; 256 if( pRValue.is() ) 257 { 258 pAny = pRValue->getCurrentValue(); 259 } 260 261 SetValue( pAny ); 262 } 263 264 /** 265 * Set special default action description string via UNO role. 266 * @param Role UNO role 267 * @return 268 */ 269 void AccObject::UpdateDefaultAction( ) 270 { 271 if(!m_xAccActionRef.is()) 272 return ; 273 274 switch(m_accRole) 275 { 276 case PUSH_BUTTON: 277 case TOGGLE_BUTTON: 278 case RADIO_BUTTON: 279 case MENU_ITEM: 280 case RADIO_MENU_ITEM: 281 case CHECK_MENU_ITEM: 282 case LIST_ITEM: 283 case CHECK_BOX: 284 case TREE_ITEM: 285 case BUTTON_DROPDOWN: 286 m_pIMAcc->Put_ActionDescription( m_xAccActionRef->getAccessibleActionDescription((sal_Int32)0).getStr() ); 287 return; 288 } 289 } 290 291 /** 292 * Set value property via pAny. 293 * @param pAny New value. 294 * @return 295 */ 296 void AccObject::SetValue( Any pAny ) 297 { 298 unsigned short pUNumberString[100]; 299 memset( pUNumberString, 0 , sizeof( pUNumberString) ); 300 301 if( NULL == m_pIMAcc || !m_xAccContextRef.is() ) 302 { 303 assert(false); 304 return ; 305 } 306 Reference< XAccessibleText > pRText(m_xAccContextRef,UNO_QUERY); 307 ::rtl::OUString val; 308 int index = 0 ; 309 switch(m_accRole) 310 { 311 case SPIN_BOX: 312 // 3. date editor's msaa value should be the same as spinbox 313 case DATE_EDITOR: 314 case TEXT: 315 case PARAGRAPH: 316 case HEADING: 317 318 if(pRText.get()) 319 { 320 val = pRText->getText(); 321 } 322 m_pIMAcc->Put_XAccValue( val.getStr() ); 323 break; 324 case TREE_ITEM: 325 //IAccessibility2 Implementation 2009----- 326 //case CHECK_BOX: //Commented by Li Xing to disable the value for general checkbox 327 case COMBO_BOX: 328 case TABLE_CELL: 329 case NOTE: 330 case SCROLL_BAR: 331 m_pIMAcc->Put_XAccValue( GetMAccessibleValueFromAny(pAny).getStr() ); 332 break ; 333 // Added by Li Xing, only the checkbox in tree should have the value. 334 case CHECK_BOX: 335 if( ( m_pParentObj !=NULL ) && (TREE == m_pParentObj->m_accRole || TREE_ITEM == m_pParentObj->m_accRole )) 336 m_pIMAcc->Put_XAccValue( GetMAccessibleValueFromAny(pAny).getStr() ); 337 //-----IAccessibility2 Implementation 2009 338 break; 339 default: 340 break; 341 } 342 343 return; 344 345 346 } 347 ::rtl::OUString AccObject::GetMAccessibleValueFromAny(Any pAny) 348 { 349 ::rtl::OUString strValue; 350 351 if(NULL == m_pIMAcc) 352 return strValue; 353 354 if(pAny.getValueType() == getCppuType( (sal_uInt16 *)0 ) ) 355 { 356 sal_uInt16 val; 357 if (pAny >>= val) 358 { 359 strValue=::rtl::OUString::valueOf((sal_Int32)val); 360 361 } 362 } 363 else if(pAny.getValueType() == getCppuType( (::rtl::OUString *)0 ) ) 364 { 365 366 pAny >>= strValue ; 367 368 } 369 else if(pAny.getValueType() == getCppuType( (Sequence< ::rtl::OUString > *)0 ) ) 370 { 371 Sequence< ::rtl::OUString > val; 372 if (pAny >>= val) 373 { 374 375 int count = val.getLength(); 376 377 for( int iIndex = 0;iIndex < count;iIndex++ ) 378 { 379 strValue += val[iIndex]; 380 } 381 382 } 383 } 384 else if(pAny.getValueType() == getCppuType( (double *)0 ) ) 385 { 386 double val; 387 if (pAny >>= val) 388 { 389 strValue=::rtl::OUString::valueOf(val); 390 } 391 } 392 else if(pAny.getValueType() == getCppuType( (sal_Int32 *)0 ) ) 393 { 394 sal_Int32 val; 395 if (pAny >>= val) 396 { 397 strValue=::rtl::OUString::valueOf(val); 398 } 399 } 400 else if (pAny.getValueType() == getCppuType( (com::sun::star::accessibility::TextSegment *)0 ) ) 401 { 402 com::sun::star::accessibility::TextSegment val; 403 if (pAny >>= val) 404 { 405 ::rtl::OUString realVal(val.SegmentText); 406 strValue = realVal; 407 408 } 409 } 410 411 return strValue; 412 } 413 /** 414 * Set name property via pAny. 415 * @param pAny New accessible name. 416 * @return 417 */ 418 void AccObject::SetName( Any pAny) 419 { 420 if( NULL == m_pIMAcc ) 421 return ; 422 423 m_pIMAcc->Put_XAccName( GetMAccessibleValueFromAny(pAny).getStr() ); 424 425 } 426 427 /** 428 * Set description property via pAny. 429 * @param pAny New accessible description. 430 * @return 431 */ 432 void AccObject::SetDescription( Any pAny ) 433 { 434 if( NULL == m_pIMAcc ) 435 return ; 436 m_pIMAcc->Put_XAccDescription( GetMAccessibleValueFromAny(pAny).getStr() ); 437 } 438 439 /** 440 * Set role property via pAny 441 * @param Role New accessible role. 442 * @return 443 */ 444 void AccObject::SetRole( short Role ) 445 { 446 if( NULL == m_pIMAcc ) 447 return ; 448 m_pIMAcc->Put_XAccRole( Role ); 449 } 450 451 /** 452 * Get role property via pAny 453 * @param 454 * @return accessible role 455 */ 456 short AccObject::GetRole() const 457 { 458 return m_accRole; 459 } 460 461 /** 462 * Get MSAA state from UNO state 463 * @Role xState UNO state. 464 * @return 465 */ 466 DWORD AccObject::GetMSAAStateFromUNO(short xState) 467 { 468 DWORD IState = UNO_MSAA_UNMAPPING; 469 470 if( !m_xAccContextRef.is() ) 471 { 472 assert(false); 473 return IState; 474 } 475 short Role = m_accRole; 476 477 switch( xState ) 478 { 479 case BUSY: 480 IState = STATE_SYSTEM_BUSY; 481 break; 482 case CHECKED: 483 if( Role == PUSH_BUTTON || Role == TOGGLE_BUTTON ) 484 { 485 IState = STATE_SYSTEM_PRESSED; 486 } 487 else 488 IState = STATE_SYSTEM_CHECKED; 489 break; 490 case DEFUNC: 491 IState = STATE_SYSTEM_UNAVAILABLE; 492 break; 493 case EXPANDED: 494 IState = STATE_SYSTEM_EXPANDED; 495 break; 496 case FOCUSABLE: 497 IState = STATE_SYSTEM_FOCUSABLE; 498 break; 499 case FOCUSED: 500 IState = STATE_SYSTEM_FOCUSED; 501 break; 502 case INDETERMINATE: 503 IState = STATE_SYSTEM_MIXED; 504 break; 505 case MULTI_SELECTABLE: 506 IState = STATE_SYSTEM_MULTISELECTABLE; 507 break; 508 case PRESSED: 509 IState = STATE_SYSTEM_PRESSED; 510 break; 511 case RESIZABLE: 512 IState = STATE_SYSTEM_SIZEABLE; 513 break; 514 case SELECTABLE: 515 if( m_accRole == MENU || m_accRole == MENU_ITEM) 516 { 517 IState = UNO_MSAA_UNMAPPING; 518 } 519 else 520 { 521 IState = STATE_SYSTEM_SELECTABLE; 522 } 523 break; 524 case SELECTED: 525 if( m_accRole == MENU || m_accRole == MENU_ITEM ) 526 { 527 IState = UNO_MSAA_UNMAPPING; 528 } 529 else 530 { 531 IState = STATE_SYSTEM_SELECTED; 532 } 533 break; 534 case ARMED: 535 IState = STATE_SYSTEM_FOCUSED; 536 break; 537 case EXPANDABLE: 538 { 539 sal_Bool isExpanded = sal_True; 540 sal_Bool isExpandable = sal_True; 541 if( Role == PUSH_BUTTON || Role == TOGGLE_BUTTON || BUTTON_DROPDOWN == Role ) 542 { 543 IState = STATE_SYSTEM_HASPOPUP; 544 } 545 else 546 { 547 GetExpandedState(&isExpandable,&isExpanded); 548 if(!isExpanded) 549 IState = STATE_SYSTEM_COLLAPSED; 550 } 551 } 552 break; 553 //Remove the SENSITIVE state mapping. There is no corresponding MSAA state. 554 //case SENSITIVE: 555 // IState = STATE_SYSTEM_PROTECTED; 556 case EDITABLE: 557 if( m_pIMAcc ) 558 { 559 m_pIMAcc->DecreaseState( STATE_SYSTEM_READONLY ); 560 } 561 break; 562 case OFFSCREEN: 563 IState = STATE_SYSTEM_OFFSCREEN; 564 break; 565 case MOVEABLE: 566 IState = STATE_SYSTEM_MOVEABLE; 567 break; 568 case COLLAPSE: 569 IState = STATE_SYSTEM_COLLAPSED; 570 break; 571 case DEFAULT: 572 IState = STATE_SYSTEM_DEFAULT; 573 break; 574 default: 575 break; 576 } 577 578 return IState; 579 } 580 581 /** 582 * Decrease state of com object 583 * @param xState The lost state. 584 * @return 585 */ 586 void AccObject::DecreaseState( short xState ) 587 { 588 if( NULL == m_pIMAcc ) 589 { 590 return; 591 } 592 593 if( xState == FOCUSABLE) 594 { 595 short Role = m_accRole ; 596 if(Role == MENU_ITEM 597 || Role == RADIO_MENU_ITEM 598 || Role == CHECK_MENU_ITEM) 599 return; 600 else 601 { 602 if (Role == TOGGLE_BUTTON || Role == PUSH_BUTTON || BUTTON_DROPDOWN == Role) 603 { 604 if( ( m_pParentObj !=NULL ) && (TOOL_BAR == m_pParentObj->m_accRole ) ) 605 return; 606 } 607 } 608 } 609 610 else if( xState == AccessibleStateType::VISIBLE ) 611 { 612 m_pIMAcc->IncreaseState( STATE_SYSTEM_INVISIBLE ); 613 } 614 else if( xState == AccessibleStateType::SHOWING ) 615 { 616 m_pIMAcc->IncreaseState( STATE_SYSTEM_OFFSCREEN ); 617 } 618 619 DWORD msState = GetMSAAStateFromUNO(xState); 620 if(msState!=UNO_MSAA_UNMAPPING) 621 m_pIMAcc->DecreaseState(msState); 622 } 623 624 /** 625 * Increase state of com object 626 * @param xState The new state. 627 * @return 628 */ 629 void AccObject::IncreaseState( short xState ) 630 { 631 if( NULL == m_pIMAcc ) 632 { 633 assert(false); 634 return; 635 } 636 637 638 if( xState == AccessibleStateType::VISIBLE ) 639 { 640 m_pIMAcc->DecreaseState( STATE_SYSTEM_INVISIBLE ); 641 } 642 else if( xState == AccessibleStateType::SHOWING ) 643 { 644 m_pIMAcc->DecreaseState( STATE_SYSTEM_OFFSCREEN ); 645 } 646 647 648 DWORD msState = GetMSAAStateFromUNO(xState); 649 if(msState!=UNO_MSAA_UNMAPPING) 650 m_pIMAcc->IncreaseState( msState ); 651 } 652 653 /** 654 * Get next child element 655 * @param 656 * @return AccObject Object interface. 657 */ 658 AccObject* AccObject::NextChild() 659 { 660 IAccChildList::iterator pInd = m_childrenList.begin(); 661 if( pInd != m_childrenList.end() ) 662 return *pInd; 663 return NULL; 664 } 665 /** 666 * update action desciption desc 667 * @param 668 * @return 669 */ 670 void AccObject::UpdateActionDesc() 671 { 672 if (!m_pIMAcc) 673 { 674 return; 675 } 676 677 ::rtl::OUString pXString = m_xAccContextRef->getAccessibleDescription(); 678 m_pIMAcc->Put_XAccDescription(pXString.getStr()); 679 long Role = m_accRole; 680 681 if( Role == PUSH_BUTTON || Role == RADIO_BUTTON || Role == MENU_ITEM || 682 Role == LIST_ITEM || Role == CHECK_BOX || Role == TREE_ITEM || 683 Role == CHECK_MENU_ITEM || Role == RADIO_MENU_ITEM ) 684 { 685 UpdateDefaultAction( ); 686 } 687 else 688 { 689 690 if( m_xAccActionRef.is() ) 691 { 692 if( m_xAccActionRef->getAccessibleActionCount() > 0 ) 693 { 694 if (!(Role == SPIN_BOX || Role == COMBO_BOX || Role == DATE_EDITOR || 695 Role == EDIT_BAR || Role == PASSWORD_TEXT || Role == TEXT)) 696 { 697 pXString = m_xAccActionRef->getAccessibleActionDescription( 0 ); 698 //Solution:If string length is more than zero,action will will be set. 699 if( pXString.getLength() > 0) 700 m_pIMAcc->Put_ActionDescription( pXString.getStr() ); 701 } 702 } 703 } 704 } 705 706 } 707 /** 708 * update role information from uno to com 709 * @param 710 * @return 711 */ 712 void AccObject::UpdateRole() 713 { 714 if (!m_pIMAcc) 715 { 716 return; 717 } 718 719 XAccessibleContext* pContext = m_xAccContextRef.get(); 720 m_pIMAcc->Put_XAccRole( ROLE_SYSTEM_WINDOW ); 721 short iRoleIndex = pContext->getAccessibleRole(); 722 if (( 0 <= iRoleIndex) && ( iRoleIndex <= (sizeof(ROLE_TABLE)/(sizeof(short)*2)))) 723 { 724 short iIA2Role = ROLE_TABLE[iRoleIndex][1] ; 725 m_pIMAcc->Put_XAccRole( iIA2Role ); 726 } 727 728 } 729 /** 730 * update state information from uno to com 731 * @param 732 * @return 733 */ 734 void AccObject::UpdateState() 735 { 736 if (!m_pIMAcc) 737 { 738 return; 739 } 740 741 XAccessibleContext* pContext = m_xAccContextRef.get(); 742 Reference< XAccessibleStateSet > pRState = pContext->getAccessibleStateSet(); 743 if( !pRState.is() ) 744 { 745 assert(false); 746 return ; 747 } 748 749 m_pIMAcc->SetState(0L); 750 751 if ( m_accRole == POPUP_MENU ) 752 { 753 return; 754 } 755 756 Sequence<short> pStates = pRState->getStates(); 757 int count = pStates.getLength(); 758 759 sal_Bool isEnable = sal_False; 760 sal_Bool isShowing = sal_False; 761 sal_Bool isEditable = sal_False; 762 sal_Bool isVisible = sal_False; 763 sal_Bool isFocusable = sal_False; 764 765 for( int iIndex = 0;iIndex < count;iIndex++ ) 766 { 767 if( pStates[iIndex] == ENABLED ) 768 isEnable = sal_True; 769 else if( pStates[iIndex] == SHOWING) 770 isShowing = sal_True; 771 else if( pStates[iIndex] == VISIBLE) 772 isVisible = sal_True; 773 else if( pStates[iIndex] == EDITABLE ) 774 isEditable = sal_True; 775 else if (pStates[iIndex] == FOCUSABLE) 776 isFocusable = sal_True; 777 IncreaseState( pStates[iIndex]); 778 } 779 sal_Bool bIsMenuItem = m_accRole == MENU_ITEM || m_accRole == RADIO_MENU_ITEM || m_accRole == CHECK_MENU_ITEM; 780 781 if(bIsMenuItem) 782 { 783 if(!(isShowing && isVisible) ) 784 { 785 m_pIMAcc->IncreaseState( STATE_SYSTEM_INVISIBLE ); 786 m_pIMAcc->DecreaseState( STATE_SYSTEM_FOCUSABLE ); 787 } 788 } 789 else 790 { 791 if(!(isShowing || isVisible) ) 792 m_pIMAcc->IncreaseState( STATE_SYSTEM_INVISIBLE ); 793 } 794 795 short Role = m_accRole; 796 797 if( m_pIMAcc ) 798 { 799 switch(m_accRole) 800 { 801 case LABEL: 802 m_pIMAcc->IncreaseState( STATE_SYSTEM_READONLY ); 803 break; 804 case TEXT: 805 // 2. editable combobox -> readonly ------ bridge 806 case EMBEDDED_OBJECT: 807 case END_NOTE: 808 case FOOTER: 809 case FOOTNOTE: 810 case GRAPHIC: 811 case HEADER: 812 case HEADING: 813 814 //Image Map 815 case PARAGRAPH: 816 case PASSWORD_TEXT: 817 case SHAPE: 818 case SPIN_BOX: 819 case TABLE: 820 case TABLE_CELL: 821 case TEXT_FRAME: 822 case DATE_EDITOR: 823 case DOCUMENT: 824 case COLUMN_HEADER: 825 { 826 if(!isEditable) 827 m_pIMAcc->IncreaseState( STATE_SYSTEM_READONLY ); 828 } 829 break; 830 default: 831 break; 832 } 833 } 834 835 if( isEnable ) 836 { 837 838 if(!(Role == FILLER || Role == END_NOTE || Role == FOOTER || Role == FOOTNOTE || Role == GROUP_BOX || Role == RULER 839 || Role == HEADER || Role == ICON || Role == INTERNAL_FRAME || Role == LABEL || Role == LAYERED_PANE 840 || Role == SCROLL_BAR || Role == SCROLL_PANE || Role == SPLIT_PANE || Role == STATUS_BAR || Role == TOOL_TIP)) 841 { 842 if( SEPARATOR == Role ) 843 { 844 if( ( m_pParentObj != NULL ) && ( MENU == m_pParentObj->m_accRole || POPUP_MENU == m_pParentObj->m_accRole )) 845 IncreaseState( FOCUSABLE ); 846 } 847 848 else if (TABLE_CELL == Role || TABLE == Role || PANEL == Role || OPTION_PANE == Role || 849 COLUMN_HEADER == Role) 850 { 851 if (isFocusable) 852 IncreaseState( FOCUSABLE ); 853 } 854 else 855 { 856 if(bIsMenuItem) 857 { 858 if ( isShowing && isVisible) 859 { 860 IncreaseState( FOCUSABLE ); 861 } 862 } 863 else 864 { 865 IncreaseState( FOCUSABLE ); 866 } 867 } 868 } 869 } 870 else 871 { 872 m_pIMAcc->IncreaseState( STATE_SYSTEM_UNAVAILABLE ); 873 sal_Bool isDecreaseFocusable = sal_False; 874 if( !((Role == MENU_ITEM) || 875 (Role == RADIO_MENU_ITEM) || 876 (Role == CHECK_MENU_ITEM)) ) 877 { 878 if ( Role == TOGGLE_BUTTON || Role == PUSH_BUTTON || BUTTON_DROPDOWN == Role) 879 { 880 if(( m_pParentObj != NULL )&& (TOOL_BAR == m_pParentObj->m_accRole ) ) 881 IncreaseState( FOCUSABLE ); 882 else 883 DecreaseState( FOCUSABLE ); 884 } 885 else 886 DecreaseState( FOCUSABLE ); 887 } 888 else if( isShowing || isVisible ) 889 { 890 IncreaseState( FOCUSABLE ); 891 } 892 } 893 894 if( m_pIMAcc ) 895 { 896 switch(m_accRole) 897 { 898 case POPUP_MENU: 899 case MENU: 900 if( pContext->getAccessibleChildCount() > 0 ) 901 m_pIMAcc->IncreaseState( STATE_SYSTEM_HASPOPUP ); 902 break; 903 case PASSWORD_TEXT: 904 m_pIMAcc->IncreaseState( STATE_SYSTEM_PROTECTED ); 905 break; 906 default: 907 break; 908 } 909 } 910 911 } 912 /** 913 * update location information from uno to com 914 * @param 915 * @return 916 */ 917 void AccObject::UpdateLocation() 918 { 919 if (!m_pIMAcc) 920 { 921 return; 922 } 923 XAccessibleContext* pContext = m_xAccContextRef.get(); 924 925 Reference< XAccessibleComponent > pRComponent(pContext,UNO_QUERY); 926 if( pRComponent.is() ) 927 { 928 ::com::sun::star::awt::Point pCPoint = pRComponent->getLocationOnScreen(); 929 ::com::sun::star::awt::Size pCSize = pRComponent->getSize(); 930 Location tempLocation; 931 tempLocation.m_dLeft = pCPoint.X; 932 tempLocation.m_dTop = pCPoint.Y; 933 tempLocation.m_dWidth = pCSize.Width; 934 tempLocation.m_dHeight = pCSize.Height; 935 m_pIMAcc->Put_XAccLocation( tempLocation ); 936 } 937 938 } 939 940 941 /** 942 * Public method to mapping information between MSAA and UNO. 943 * @param 944 * @return If the method is correctly processed. 945 */ 946 sal_Bool AccObject:: UpdateAccessibleInfoFromUnoToMSAA ( ) 947 { 948 if( NULL == m_pIMAcc || !m_xAccContextRef.is() ) 949 { 950 assert(false); 951 return sal_False; 952 } 953 954 UpdateName(); 955 956 UpdateValue(); 957 958 UpdateActionDesc(); 959 960 UpdateRole(); 961 962 UpdateLocation(); 963 964 UpdateState(); 965 966 return sal_True; 967 } 968 969 /* 970 * Add a child selected element. 971 * @param pAccObj Child object pointer. 972 * @return 973 */ 974 void AccObject::AddSelect( long index, AccObject* accObj) 975 { 976 m_selectionList.insert(IAccSelectionList::value_type(index,accObj)); 977 } 978 979 IAccSelectionList& AccObject::GetSelection() 980 { 981 return m_selectionList; 982 } 983 984 985 /** 986 * Set self to focus object in parant child list 987 * @param 988 * @return 989 */ 990 void AccObject::setFocus() 991 { 992 if(m_pIMAcc) 993 { 994 IncreaseState(FOCUSED); 995 m_pIMAcc->Put_XAccFocus(CHILDID_SELF); 996 997 UpdateRole(); 998 } 999 } 1000 1001 /** 1002 * Unset self from focus object in parant child list. 1003 * @param 1004 * @return 1005 */ 1006 void AccObject::unsetFocus() 1007 { 1008 if(m_pIMAcc) 1009 { 1010 DecreaseState( FOCUSED ); 1011 m_pIMAcc->Put_XAccFocus(UACC_NO_FOCUS); 1012 } 1013 } 1014 1015 void AccObject::GetExpandedState( sal_Bool* isExpandable, sal_Bool* isExpanded) 1016 { 1017 *isExpanded = sal_False; 1018 *isExpandable = sal_False; 1019 1020 if( !m_xAccContextRef.is() ) 1021 { 1022 return; 1023 } 1024 Reference< XAccessibleStateSet > pRState = m_xAccContextRef->getAccessibleStateSet(); 1025 if( !pRState.is() ) 1026 { 1027 return; 1028 } 1029 1030 Sequence<short> pStates = pRState->getStates(); 1031 int count = pStates.getLength(); 1032 1033 for( int iIndex = 0;iIndex < count;iIndex++ ) 1034 { 1035 if( EXPANDED == pStates[iIndex] ) 1036 { 1037 *isExpanded = sal_True; 1038 } 1039 else if( EXPANDABLE == pStates[iIndex] ) 1040 { 1041 *isExpandable = sal_True; 1042 } 1043 } 1044 } 1045 1046 void AccObject::NotifyDestroy(sal_Bool ifDelete) 1047 { 1048 m_bShouldDestroy=ifDelete; 1049 if(m_pIMAcc) 1050 m_pIMAcc->NotifyDestroy(m_bShouldDestroy); 1051 } 1052 1053 void AccObject::SetParentObj(AccObject* pParentAccObj) 1054 { 1055 m_pParentObj = pParentAccObj; 1056 1057 if(m_pIMAcc) 1058 { 1059 if(m_pParentObj) 1060 { 1061 m_pIMAcc->Put_XAccParent(m_pParentObj->GetIMAccessible()); 1062 } 1063 else 1064 { 1065 m_pIMAcc->Put_XAccParent(NULL); 1066 } 1067 } 1068 } 1069 //ResID means ChildID in MSAA 1070 void AccObject::SetResID(long id) 1071 { 1072 m_resID = id; 1073 if(m_pIMAcc) 1074 m_pIMAcc->Put_XAccChildID(m_resID); 1075 } 1076 //return COM interface in acc object 1077 IMAccessible* AccObject::GetIMAccessible() 1078 { 1079 return m_pIMAcc; 1080 } 1081 1082 Reference < XAccessible > AccObject::GetXAccessible() 1083 { 1084 return m_xAccRef; 1085 } 1086 1087 void AccObject::SetParentHWND(HWND hWnd) 1088 { 1089 m_pParantID = hWnd; 1090 } 1091 void AccObject::SetListener( AccEventListener* Listener ) 1092 { 1093 m_accListener = Listener; 1094 } 1095 AccEventListener* AccObject::getListener() 1096 { 1097 return m_accListener; 1098 } 1099 1100 long AccObject::GetResID() 1101 { 1102 return m_resID; 1103 } 1104 1105 HWND AccObject::GetParentHWND() 1106 { 1107 return m_pParantID; 1108 } 1109 1110 AccObject* AccObject::GetParentObj() 1111 { 1112 return m_pParentObj; 1113 } 1114 sal_Bool AccObject::ifShouldDestroy() 1115 { 1116 return m_bShouldDestroy; 1117 } 1118