1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 #include "stdafx.h" 23 #include "UAccCOM2.h" 24 #include "MAccessible.h" 25 26 #include <algorithm> 27 #include "AccAction.h" 28 29 #include <com/sun/star/accessibility/XAccessibleText.hpp> 30 #include <com/sun/star/accessibility/XAccessibleEditableText.hpp> 31 #include <com/sun/star/accessibility/XAccessibleImage.hpp> 32 #include <com/sun/star/accessibility/XAccessibleTable.hpp> 33 #include <com/sun/star/accessibility/XAccessibleExtendedComponent.hpp> 34 #include <com/sun/star/accessibility/XAccessibleAction.hpp> 35 #include <com/sun/star/accessibility/XAccessibleKeyBinding.hpp> 36 #include <com/sun/star/accessibility/XAccessibleHyperText.hpp> 37 #include <com/sun/star/accessibility/XAccessibleHyperlink.hpp> 38 #include <com/sun/star/accessibility/XAccessibleRelationSet.hpp> 39 #include <com/sun/star/accessibility/AccessibleStateType.hpp> 40 #include <com/sun/star/accessibility/AccessibleRole.hpp> 41 #include <com/sun/star/accessibility/XAccessibleGroupPosition.hpp> 42 #include <com/sun/star/accessibility/XAccessibleValue.hpp> 43 #include <com/sun/star/accessibility/XAccessibleExtendedAttributes.hpp> 44 #include <com/sun/star/style/LineSpacing.hpp> 45 #include <com/sun/star/style/TabStop.hpp> 46 #include <com/sun/star/container/XIndexReplace.hpp> 47 48 #include "AccessibleRole.h" 49 50 51 using namespace com::sun::star::accessibility::AccessibleStateType; 52 53 // IA2 states mapping, and name 54 // maintenance the consistency, change one array, change the three all 55 long IA2_STATES[] = 56 { 57 IA2_STATE_ACTIVE, // = 0x1; 58 IA2_STATE_ARMED, // = 0x2; 59 IA2_STATE_DEFUNCT, // = 0x4; 60 IA2_STATE_EDITABLE, // = 0x8; 61 IA2_STATE_HORIZONTAL, // = 0x10; 62 IA2_STATE_ICONIFIED, // = 0x20; 63 IA2_STATE_INVALID_ENTRY, // = 0x80; 64 IA2_STATE_MANAGES_DESCENDANTS, // = 0x100; 65 IA2_STATE_MODAL, // = 0x200; 66 IA2_STATE_MULTI_LINE, // = 0x400; 67 IA2_STATE_OPAQUE, // = 0x800; 68 IA2_STATE_REQUIRED, // = 0x2000; 69 IA2_STATE_SELECTABLE_TEXT, // = 0x3000; 70 IA2_STATE_SINGLE_LINE, // = 0x4000; 71 IA2_STATE_STALE, // = 0x8000; 72 IA2_STATE_SUPPORTS_AUTOCOMPLETION, // = 0x10000; 73 IA2_STATE_TRANSIENT, //= 0x20000; 74 IA2_STATE_VERTICAL // = 0x40000; 75 }; 76 /* 77 78 <=== map ===> 79 80 */ 81 short UNO_STATES[] = 82 { 83 ACTIVE, // = (sal_Int16)1; 84 ARMED, // = (sal_Int16)2; 85 DEFUNC, // = (sal_Int16)5; 86 EDITABLE, // = (sal_Int16)6; 87 HORIZONTAL, // = (sal_Int16)12; 88 ICONIFIED, // = (sal_Int16)13; 89 -1, //IA2_STATE_INVALID_ENTRY 90 MANAGES_DESCENDANTS, // = (sal_Int16)15; 91 MODAL, // = (sal_Int16)16; 92 MULTI_LINE, // = (sal_Int16)17; 93 OPAQUE, // = (sal_Int16)19; 94 -1, //IA2_STATE_REQUIRED 95 -1, //IA2_STATE_SELECTABLE_TEXT 96 SINGLE_LINE, // = (sal_Int16)26; 97 STALE, // = (sal_Int16)27; 98 -1, //IA2_STATE_SUPPORTS_AUTOCOMPLETION 99 TRANSIENT, //IA2_STATE_TRANSIENT 100 VERTICAL // = (sal_Int16)29; 101 }; 102 103 // <=== map ===> 104 105 BSTR IA2_STATES_NAME[] = 106 { 107 _T("Active"), 108 _T("Armed"), 109 _T("Defunct"), 110 _T("Editable"), 111 _T("Horizontal"), 112 _T("Iconified"), 113 _T("Invalid Entry"), 114 _T("Manages Decendents"), 115 _T("Modal"), 116 _T("Multi Line"), 117 _T("Opaque"), 118 _T("Required"), 119 _T("Selectable Text"), 120 _T("Single Line"), 121 _T("Stale"), 122 _T("Supports Autocompletion"), 123 _T("Transient"), 124 _T("Vertical") 125 }; 126 127 // IA2 states mapping, and name 128 // maintenance the consistency. change one, change them all 129 130 BSTR UNO_ALL_STATES[] = 131 { 132 _T("INVALID"), // INVALID ( 0 ) 133 _T("ACTIVE"), // ACTIVE ( 1 ) 134 _T("ARMED"), // ARMED ( 2 ) 135 _T("BUSY"), // BUSY ( 3 ) 136 _T("CHECKED"), // CHECKED ( 4 ) 137 _T("DEFUNC"), // DEFUNC ( 5 ) 138 _T("EDITABLE"), // EDITABLE ( 6 ) 139 _T("ENABLED"), // ENABLED ( 7 ) 140 _T("EXPANDABLE"), // EXPANDABLE ( 8 ) 141 _T("EXPANDED"), // EXPANDED ( 9 ) 142 _T("FOCUSABLE"), // FOCUSABLE ( 10 ) 143 _T("FOCUSED"), // FOCUSED ( 11 ) 144 _T("HORIZONTAL"), // HORIZONTAL ( 12 ) 145 _T("ICONIFIED"), // ICONIFIED ( 13 ) 146 _T("INDETERMINATE"), // INDETERMINATE ( 14 ) 147 _T("MANAGES_DESCENDANTS"),// MANAGES_DESCENDANTS ( 15 ) 148 _T("MODAL"), // MODAL ( 16 ) 149 _T("MULTI_LINE"), // MULTI_LINE ( 17 ) 150 _T("MULTI_SELECTABLE"), // MULTI_SELECTABLE ( 18 ) 151 _T("OPAQUE"), // OPAQUE ( 19 ) 152 _T("PRESSED"), // PRESSED ( 20 ) 153 _T("RESIZABLE"), // RESIZABLE ( 21 ) 154 _T("SELECTABLE"), // SELECTABLE ( 22 ) 155 _T("SELECTED"), // SELECTED ( 23 ) 156 _T("SENSITIVE"), // SENSITIVE ( 24 ) 157 _T("SHOWING"), // SHOWING ( 25 ) 158 _T("SINGLE_LINE"), // SINGLE_LINE ( 26 ) 159 _T("STALE"), // STALE ( 27 ) 160 _T("TRANSIENT"), // TRANSIENT ( 28 ) 161 _T("VERTICAL"), // VERTICAL ( 29 ) 162 _T("VISIBLE"), // VISIBLE ( 30 ) 163 _T("MOVEABLE"), // MOVEABLE ( 31 ) 164 _T("OFFSCREEN"), // OFFSCREEN ( 32 ) 165 _T("COLLAPSE"), // COLLAPSE ( 33 ) 166 _T("DEFAULT") // DEFAULT ( 34 ) 167 }; 168 169 170 using namespace com::sun::star::accessibility::AccessibleRole; 171 172 173 174 #define QUERYXINTERFACE(ainterface) \ 175 { \ 176 if(pXAcc == NULL) \ 177 return FALSE; \ 178 pRContext = pXAcc->getAccessibleContext(); \ 179 if( !pRContext.is() ) \ 180 { \ 181 return FALSE; \ 182 } \ 183 Reference<X##ainterface> pRXI(pRContext,UNO_QUERY);\ 184 if( !pRXI.is() ) \ 185 { \ 186 return FALSE; \ 187 } \ 188 *ppXI = (XInterface*)pRXI.get(); \ 189 return TRUE; \ 190 } 191 192 #define ISDESTROY() \ 193 if(m_isDestroy) \ 194 return S_FALSE; 195 196 197 AccObjectManagerAgent* CMAccessible::g_pAgent = NULL; 198 199 CMAccessible::CMAccessible(): 200 m_iRole(0x00), 201 m_dState(0x00), 202 m_dChildID(0x00), 203 m_dFocusChildID(UACC_NO_FOCUS), 204 m_hwnd(NULL), 205 m_pIParent(NULL), 206 m_pszName(NULL), 207 m_pszValue(NULL), 208 m_pszDescription(NULL), 209 m_isDestroy(FALSE), 210 m_pszActionDescription(NULL), 211 m_pXAction(NULL), 212 m_bRequiresSave(FALSE), 213 pUNOInterface(NULL) 214 { 215 m_sLocation.m_dLeft=0; 216 m_sLocation.m_dTop = 0; 217 m_sLocation.m_dWidth=0; 218 m_sLocation.m_dHeight=0; 219 CEnumVariant::Create(&m_pEnumVar); 220 } 221 222 CMAccessible::~CMAccessible() 223 { 224 if(m_pszName!=NULL) 225 { 226 SAFE_SYSFREESTRING(m_pszName); 227 m_pszName=NULL; 228 } 229 if(m_pszValue!=NULL) 230 { 231 SAFE_SYSFREESTRING(m_pszValue); 232 m_pszValue=NULL; 233 } 234 if(m_pszDescription!=NULL) 235 { 236 SAFE_SYSFREESTRING(m_pszDescription); 237 m_pszDescription=NULL; 238 } 239 240 if(m_pszActionDescription!=NULL) 241 { 242 SAFE_SYSFREESTRING(m_pszActionDescription); 243 m_pszActionDescription=NULL; 244 } 245 246 if(m_pIParent) 247 { 248 m_pIParent->Release(); 249 m_pIParent=NULL; 250 } 251 pRef = NULL; 252 m_pEnumVar->Release(); 253 m_containedObjects.clear(); 254 pRContext = NULL; 255 } 256 257 /** 258 * Returns the Parent IAccessible interface pointer to AT. 259 * It should add reference, and the client should release the component. 260 * It should return E_FAIL when the parent point is null. 261 * @param ppdispParent [in,out] used to return the parent interface point. 262 * when the point is null, should return null. 263 * @return S_OK if successful and E_FAIL if the m_pIParent is NULL. 264 */ 265 STDMETHODIMP CMAccessible::get_accParent(IDispatch **ppdispParent) 266 { 267 268 CHECK_ENABLE_INF 269 ENTER_PROTECTED_BLOCK 270 ISDESTROY() 271 // #CHECK# 272 if(ppdispParent == NULL) 273 { 274 return E_INVALIDARG; 275 } 276 277 if(m_pIParent) 278 { 279 *ppdispParent = m_pIParent; 280 (*ppdispParent)->AddRef(); 281 return S_OK; 282 } 283 else if(m_hwnd) 284 { 285 HRESULT hr = AccessibleObjectFromWindow(m_hwnd, OBJID_WINDOW, IID_IAccessible, (void**)ppdispParent); 286 if( ! SUCCEEDED( hr ) || ! ppdispParent ) 287 { 288 return S_FALSE; 289 } 290 return S_OK; 291 } 292 return S_FALSE; 293 294 LEAVE_PROTECTED_BLOCK 295 } 296 297 /** 298 * Returns child count of current COM object. 299 * @param pcountChildren [in,out] used to return the children count. 300 * @return S_OK if successful. 301 */ 302 STDMETHODIMP CMAccessible::get_accChildCount(long *pcountChildren) 303 { 304 305 CHECK_ENABLE_INF 306 ENTER_PROTECTED_BLOCK 307 ISDESTROY() 308 // #CHECK# 309 if(pcountChildren == NULL) 310 { 311 return E_INVALIDARG; 312 } 313 314 if(!pUNOInterface) 315 return S_FALSE; 316 317 Reference< XAccessibleContext > pRContext = pUNOInterface->getAccessibleContext(); 318 if( pRContext.is() ) 319 { 320 *pcountChildren = pRContext->getAccessibleChildCount(); 321 } 322 323 return S_OK; 324 325 LEAVE_PROTECTED_BLOCK 326 } 327 328 /** 329 * Returns child interface pointer for AT according to input child ID. 330 * @param varChild, vt member of varChild must be VT_I4,and lVal member stores the child ID, 331 * the child ID specify child index from 0 to children count, 0 stands for object self. 332 * @param ppdispChild, [in,out] use to return the child interface point. 333 * @return S_OK if successful and S_FALSE if failure. 334 */ 335 STDMETHODIMP CMAccessible::get_accChild(VARIANT varChild, IDispatch **ppdispChild) 336 { 337 338 CHECK_ENABLE_INF 339 ENTER_PROTECTED_BLOCK 340 ISDESTROY() 341 // #CHECK# 342 if(ppdispChild == NULL) 343 { 344 return E_INVALIDARG; 345 } 346 if(varChild.vt==VT_I4) 347 { 348 //get child interface pointer due to child ID 349 if(varChild.lVal==CHILDID_SELF) 350 { 351 AddRef(); 352 *ppdispChild = this; 353 return S_OK; 354 } 355 *ppdispChild = GetChildInterface(varChild.lVal); 356 (*ppdispChild)->AddRef(); 357 return (*ppdispChild)?S_OK:S_FALSE; 358 } 359 return S_FALSE; 360 361 LEAVE_PROTECTED_BLOCK 362 } 363 364 /** 365 * Returns the accessible name of the current COM object self or its one child to AT. 366 * @param varChild, vt member of varChild must be VT_I4,and lVal member stores the child ID, 367 * the child ID specify child index from 0 to children count, 0 stands for object self. 368 * @param pszName, [in,out] use to return the name of the proper object. 369 * @return S_OK if successful and S_FALSE if failure. 370 */ 371 STDMETHODIMP CMAccessible::get_accName(VARIANT varChild, BSTR *pszName) 372 { 373 374 CHECK_ENABLE_INF 375 ENTER_PROTECTED_BLOCK 376 ISDESTROY() 377 // #CHECK# 378 if(pszName == NULL) 379 { 380 return E_INVALIDARG; 381 } 382 if(varChild.vt==VT_I4) 383 { 384 if(varChild.lVal==CHILDID_SELF) 385 { 386 SAFE_SYSFREESTRING(*pszName); 387 *pszName = SysAllocString(m_pszName); 388 return S_OK; 389 } 390 391 long lVal = varChild.lVal; 392 varChild.lVal = CHILDID_SELF; 393 IMAccessible *pChild = this->GetChildInterface(lVal); 394 if(!pChild) 395 return E_FAIL; 396 return pChild->get_accName(varChild,pszName); 397 } 398 return S_FALSE; 399 400 LEAVE_PROTECTED_BLOCK 401 } 402 403 /** 404 * Returns the accessible value of the current COM object self or its one child to AT. 405 * @param varChild, vt member of varChild must be VT_I4,and lVal member stores the child ID, 406 * the child ID specify child index from 0 to children count, 0 stands for object self. 407 * @param pszValue, [in,out] use to return the value of the proper object. 408 * @return S_OK if successful and S_FALSE if failure. 409 */ 410 STDMETHODIMP CMAccessible::get_accValue(VARIANT varChild, BSTR *pszValue) 411 { 412 413 CHECK_ENABLE_INF 414 ENTER_PROTECTED_BLOCK 415 ISDESTROY() 416 // #CHECK# 417 if( pszValue == NULL ) 418 { 419 return E_INVALIDARG; 420 } 421 if( varChild.vt==VT_I4 ) 422 { 423 if(varChild.lVal==CHILDID_SELF) 424 { 425 if(m_dState & STATE_SYSTEM_PROTECTED) 426 return E_ACCESSDENIED; 427 428 if ( m_pszValue !=NULL && wcslen(m_pszValue) == 0 ) 429 return S_OK; 430 431 SAFE_SYSFREESTRING(*pszValue); 432 *pszValue = SysAllocString(m_pszValue); 433 return S_OK; 434 } 435 436 long lVal = varChild.lVal; 437 varChild.lVal = CHILDID_SELF; 438 IMAccessible *pChild = this->GetChildInterface(lVal); 439 if(!pChild) 440 return E_FAIL; 441 return pChild->get_accValue(varChild,pszValue); 442 } 443 return S_FALSE; 444 445 LEAVE_PROTECTED_BLOCK 446 } 447 448 /** 449 * Returns the accessible description of the current COM object self or its one child to AT. 450 * @param varChild, vt member of varChild must be VT_I4,and lVal member stores the child ID, 451 * the child ID specify child index from 0 to children count, 0 stands for object self. 452 * @param pszDescription, [in,out] use to return the description of the proper object. 453 * @return S_OK if successful and E_FAIL if failure. 454 */ 455 STDMETHODIMP CMAccessible::get_accDescription(VARIANT varChild, BSTR *pszDescription) 456 { 457 458 CHECK_ENABLE_INF 459 ENTER_PROTECTED_BLOCK 460 ISDESTROY() 461 // #CHECK# 462 if(pszDescription == NULL) 463 { 464 return E_INVALIDARG; 465 } 466 if(varChild.vt==VT_I4) 467 { 468 if(varChild.lVal==CHILDID_SELF) 469 { 470 SAFE_SYSFREESTRING(*pszDescription); 471 *pszDescription = SysAllocString(m_pszDescription); 472 return S_OK; 473 } 474 475 long lVal = varChild.lVal; 476 varChild.lVal = CHILDID_SELF; 477 IMAccessible *pChild = this->GetChildInterface(lVal); 478 if(!pChild) 479 return E_FAIL; 480 return pChild->get_accDescription(varChild,pszDescription); 481 } 482 return S_FALSE; 483 484 LEAVE_PROTECTED_BLOCK 485 } 486 487 /** 488 * Returns the accessible role of the current COM object self or its one child to AT. 489 * @param varChild, vt member of varChild must be VT_I4,and lVal member stores the child ID, 490 * the child ID specify child index from 0 to children count, 0 stands for object self. 491 * @param pvarRole, [in,out] use to return the role of the proper object. 492 * @return S_OK if successful and S_FALSE if failure. 493 */ 494 STDMETHODIMP CMAccessible::get_accRole(VARIANT varChild, VARIANT *pvarRole) 495 { 496 497 CHECK_ENABLE_INF 498 ENTER_PROTECTED_BLOCK 499 ISDESTROY() 500 // #CHECK# 501 if(pvarRole == NULL) 502 { 503 return E_INVALIDARG; 504 } 505 if(varChild.vt == VT_I4) 506 { 507 508 if(varChild.lVal == CHILDID_SELF) 509 { 510 if( m_iRole < IA2_ROLE_CAPTION ) 511 { 512 VariantInit(pvarRole); 513 pvarRole->vt = VT_I4; 514 pvarRole->lVal = m_iRole; 515 } 516 else 517 { 518 VariantInit(pvarRole); 519 pvarRole->vt = VT_I4; 520 pvarRole->lVal = ROLE_SYSTEM_CLIENT; 521 } 522 return S_OK; 523 } 524 525 526 long lVal = varChild.lVal; 527 varChild.lVal = CHILDID_SELF; 528 IMAccessible *pChild = this->GetChildInterface(lVal); 529 if(!pChild) 530 return E_FAIL; 531 return pChild->get_accRole(varChild,pvarRole); 532 } 533 return S_FALSE; 534 535 LEAVE_PROTECTED_BLOCK 536 } 537 538 /** 539 * Returns the accessible state of the current COM object self or its one child to AT. 540 * @param varChild, vt member of varChild must be VT_I4,and lVal member stores the child ID, 541 * the child ID specify child index from 0 to children count, 0 stands for object self. 542 * @param pvarState, [in,out] use to return the state of the proper object. 543 * @return S_OK if successful and S_FALSE if failure. 544 */ 545 STDMETHODIMP CMAccessible::get_accState(VARIANT varChild, VARIANT *pvarState) 546 { 547 548 CHECK_ENABLE_INF 549 ENTER_PROTECTED_BLOCK 550 ISDESTROY() 551 // #CHECK# 552 if(pvarState == NULL) 553 { 554 return E_INVALIDARG; 555 } 556 if(varChild.vt==VT_I4) 557 { 558 if(varChild.lVal == CHILDID_SELF) 559 { 560 if(pUNOInterface) 561 { 562 Reference< XAccessibleContext > pContext = pUNOInterface->getAccessibleContext(); 563 if(pContext.is()) 564 { 565 // add the STATE_SYSTEM_LINKED state 566 Reference< XAccessibleHypertext > pRHypertext(pContext,UNO_QUERY); 567 if(pRHypertext.is()) 568 { 569 if( pRHypertext->getHyperLinkCount() > 0 ) 570 m_dState |= STATE_SYSTEM_LINKED; 571 else 572 m_dState &= ~STATE_SYSTEM_LINKED; 573 } 574 else 575 m_dState &= ~STATE_SYSTEM_LINKED; 576 } 577 } 578 579 VariantInit(pvarState); 580 pvarState->vt = VT_I4; 581 pvarState->lVal = m_dState; 582 return S_OK; 583 } 584 585 long lVal = varChild.lVal; 586 varChild.lVal = CHILDID_SELF; 587 IMAccessible *pChild = this->GetChildInterface(lVal); 588 if(!pChild) 589 return E_FAIL; 590 return pChild->get_accState(varChild,pvarState); 591 } 592 return S_FALSE; 593 594 LEAVE_PROTECTED_BLOCK 595 } 596 597 /** 598 * Returns the accessible helpString of the current COM object self or its one child to AT. 599 * @param varChild, vt member of varChild must be VT_I4,and lVal member stores the child ID, 600 * the child ID specify child index from 0 to children count, 0 stands for object self. 601 * @param pszHelp, [in,out] use to return the helpString of the proper object. 602 * @return S_OK if successful and E_FAIL if failure. 603 */ 604 STDMETHODIMP CMAccessible::get_accHelp(VARIANT, BSTR *) 605 { 606 return E_NOTIMPL; 607 } 608 609 /** 610 * Returns the accessible HelpTopic of the current COM object self or its one child to AT. 611 * @param varChild, vt member of varChild must be VT_I4,and lVal member stores the child ID, 612 * the child ID specify child index from 0 to children count, 0 stands for object self. 613 * @param pszHelpFile, [in,out] use to return the HelpTopic of the proper object. 614 * @param pidTopic, use to return the HelpTopic ID of the proper object. 615 * @return S_OK if successful and E_FAIL if failure. 616 * Not implemented yet 617 */ 618 STDMETHODIMP CMAccessible::get_accHelpTopic(BSTR *, VARIANT, long *) 619 { 620 return E_NOTIMPL; 621 } 622 623 static void GetMnemonicChar( const ::rtl::OUString& aStr, WCHAR* wStr) 624 { 625 int nLen = aStr.pData->length; 626 int i = 0; 627 WCHAR* text = aStr.pData->buffer; 628 629 while ( i < nLen ) 630 { 631 if ( text[i] == L'~' ) 632 if ( text[i+1] != L'~' ) 633 { 634 wStr[0] = text[i+1]; 635 break; 636 } 637 i++; 638 } 639 } 640 641 /** 642 * Returns the accessible keyboard shortcut of the current COM object self or its one child to AT. 643 * @param varChild, vt member of varChild must be VT_I4,and lVal member stores the child ID, 644 * the child ID specify child index from 0 to children count, 0 stands for object self. 645 * @param pszKeyboardShortcut, [in,out] use to return the kbshortcut of the proper object. 646 * @return S_OK if successful and E_FAIL if failure. 647 */ 648 STDMETHODIMP CMAccessible::get_accKeyboardShortcut(VARIANT varChild, BSTR *pszKeyboardShortcut) 649 { 650 651 CHECK_ENABLE_INF 652 ENTER_PROTECTED_BLOCK 653 654 ISDESTROY() 655 // #CHECK# 656 if(pszKeyboardShortcut == NULL) 657 { 658 return E_INVALIDARG; 659 } 660 661 if(varChild.vt==VT_I4) 662 { 663 if(varChild.lVal == CHILDID_SELF) 664 { 665 if( pUNOInterface ) 666 { 667 Reference<XAccessibleContext> pRContext = pUNOInterface->getAccessibleContext(); 668 if( !pRContext.is() ) 669 return S_FALSE; 670 671 Reference<XAccessibleAction> pRXI(pRContext,UNO_QUERY); 672 673 OLECHAR wString[64]={0}; 674 675 if( pRXI.is() && pRXI->getAccessibleActionCount() >= 1) 676 { 677 Reference< XAccessibleKeyBinding > binding = pRXI->getAccessibleActionKeyBinding(0); 678 if( binding.is() ) 679 { 680 long nCount = binding->getAccessibleKeyBindingCount(); 681 if(nCount >= 1) 682 { 683 CAccAction::GetkeyBindingStrByXkeyBinding( binding->getAccessibleKeyBinding(0),wString ); 684 } 685 } 686 } 687 if(wString[0] == 0) 688 { 689 Reference<XAccessibleRelationSet> pRrelationSet = pRContext->getAccessibleRelationSet(); 690 if(!pRrelationSet.is()) 691 { 692 return S_FALSE; 693 } 694 695 long nRelCount = pRrelationSet->getRelationCount(); 696 697 // Modified by Steve Yin, for SODC_1552 698 if( /*nRelCount <= 0 &&*/ m_iRole == ROLE_SYSTEM_TEXT ) 699 { 700 VARIANT varParentRole; 701 VariantInit( &varParentRole ); 702 703 m_pIParent->get_accRole(varChild, &varParentRole); 704 705 if( m_pIParent && varParentRole.lVal == ROLE_SYSTEM_COMBOBOX ) // edit in comoboBox 706 { 707 m_pIParent->get_accKeyboardShortcut(varChild, pszKeyboardShortcut); 708 return S_OK; 709 } 710 } 711 712 AccessibleRelation *paccRelation = NULL; 713 AccessibleRelation accRelation; 714 for(int i=0; i<nRelCount ; i++) 715 { 716 if( pRrelationSet->getRelation(i).RelationType == 6 ) 717 { 718 accRelation = pRrelationSet->getRelation(i); 719 paccRelation = &accRelation; 720 } 721 } 722 723 if(paccRelation == NULL) 724 return S_FALSE; 725 726 Sequence< Reference< XInterface > > xTargets = paccRelation->TargetSet; 727 Reference<XInterface> pRAcc = xTargets[0]; 728 729 XAccessible* pXAcc = (XAccessible*)pRAcc.get(); 730 731 Reference<XAccessibleContext> pRLebelContext = pXAcc->getAccessibleContext(); 732 if(!pRLebelContext.is()) 733 return S_FALSE; 734 735 pRrelationSet = pRLebelContext->getAccessibleRelationSet(); 736 nRelCount = pRrelationSet->getRelationCount(); 737 738 paccRelation = NULL; 739 for(int j=0; j<nRelCount ; j++) 740 { 741 if( pRrelationSet->getRelation(j).RelationType == 5 ) 742 { 743 accRelation = pRrelationSet->getRelation(j); 744 paccRelation = &accRelation; 745 } 746 } 747 748 if(paccRelation) 749 { 750 xTargets = paccRelation->TargetSet; 751 pRAcc = xTargets[0]; 752 if(pUNOInterface != (XAccessible*)pRAcc.get()) 753 return S_FALSE; 754 } 755 756 Reference<XAccessibleExtendedComponent> pRXIE(pRLebelContext,UNO_QUERY); 757 if(!pRXIE.is()) 758 return S_FALSE; 759 760 ::rtl::OUString ouStr = pRXIE->getTitledBorderText(); 761 WCHAR key[2] = {NULL}; 762 GetMnemonicChar(ouStr, key); 763 if(key[0] != 0) 764 { 765 wcscat(wString, L"Alt+"); 766 wcscat(wString, key); 767 } 768 else 769 return S_FALSE; 770 } 771 772 SAFE_SYSFREESTRING(*pszKeyboardShortcut); 773 *pszKeyboardShortcut = SysAllocString(wString); 774 775 return S_OK; 776 } 777 else 778 { 779 return S_FALSE; 780 } 781 } 782 783 long lVal = varChild.lVal; 784 varChild.lVal = CHILDID_SELF; 785 IMAccessible *pChild = this->GetChildInterface(lVal); 786 if(!pChild) 787 return E_FAIL; 788 789 return pChild->get_accKeyboardShortcut(varChild,pszKeyboardShortcut); 790 } 791 return S_FALSE; 792 793 LEAVE_PROTECTED_BLOCK 794 } 795 796 /** 797 * Returns the current focused child to AT. 798 * @param pvarChild, [in,out] vt member of pvarChild must be VT_I4,and lVal member stores the child ID, 799 * the child ID specify child index from 0 to children count, 0 stands for object self. 800 * @return S_OK if successful and E_FAIL if failure. 801 */ 802 STDMETHODIMP CMAccessible::get_accFocus(VARIANT *pvarChild) 803 { 804 805 CHECK_ENABLE_INF 806 ENTER_PROTECTED_BLOCK 807 ISDESTROY() 808 // #CHECK# 809 if(pvarChild == NULL) 810 { 811 return E_INVALIDARG; 812 } 813 if( m_dFocusChildID==UACC_NO_FOCUS ) 814 { 815 pvarChild->vt = VT_EMPTY;//no focus on the object and its children 816 return S_OK; 817 } 818 //if the descendant of current object has focus indicated by m_dFocusChildID, return the IDispatch of this focused object 819 else 820 { 821 IMAccessible* pIMAcc = NULL; 822 g_pAgent->GetIAccessibleFromResID(m_dFocusChildID,&pIMAcc); 823 pIMAcc->AddRef(); 824 pvarChild->vt = VT_DISPATCH; 825 pvarChild->pdispVal = pIMAcc; 826 827 } 828 return S_OK; 829 830 LEAVE_PROTECTED_BLOCK 831 } 832 833 /** 834 * Returns the selection of the current COM object to AT. 835 * @param pvarChildren,[in,out] 836 * if selection num is 0,return VT_EMPTY for vt, 837 * if selection num is 1,return VT_I4 for vt,and child index for lVal 838 * if selection num >1,return VT_UNKNOWN for vt, and IEnumVariant* for punkVal 839 * @return S_OK if successful and S_FALSE if failure. 840 */ 841 STDMETHODIMP CMAccessible::get_accSelection(VARIANT *pvarChildren) 842 { 843 844 CHECK_ENABLE_INF 845 ENTER_PROTECTED_BLOCK 846 ISDESTROY() 847 // #CHECK# 848 if(pvarChildren == NULL) 849 { 850 return E_INVALIDARG; 851 } 852 switch(m_pEnumVar->GetCountOfElements()) 853 { 854 case 0: 855 pvarChildren->vt = VT_EMPTY; 856 break; 857 case 1: 858 VARIANT varTmp[1]; 859 ULONG count; 860 VariantInit(&varTmp[0]); 861 m_pEnumVar->Next(1,varTmp,&count); 862 if(count!=1) 863 return S_FALSE; 864 pvarChildren->vt = VT_I4; 865 pvarChildren->lVal = varTmp[0].lVal; 866 VariantClear(&varTmp[0]); 867 m_pEnumVar->Reset(); 868 break; 869 default: 870 pvarChildren->vt = VT_UNKNOWN; 871 m_pEnumVar->AddRef(); 872 pvarChildren->punkVal = m_pEnumVar; 873 break; 874 } 875 return S_OK; 876 877 LEAVE_PROTECTED_BLOCK 878 } 879 880 /** 881 * Returns the location of the current COM object self or its one child to AT. 882 * @param varChild, vt member of varChild must be VT_I4,and lVal member stores the child ID, 883 * the child ID specify child index from 0 to children count, 0 stands for object self. 884 * @param pxLeft, [in,out] use to return the x-coordination of the proper object. 885 * @param pyTop, [in,out] use to return the y-coordination of the proper object. 886 * @param pcxWidth, [in,out] use to return the x-coordination width of the proper object. 887 * @param pcyHeight, [in,out] use to return the y-coordination height of the proper object. 888 * @return S_OK if successful and S_FALSE if failure. 889 */ 890 STDMETHODIMP CMAccessible::accLocation(long *pxLeft, long *pyTop, long *pcxWidth, long *pcyHeight, VARIANT varChild) 891 { 892 893 CHECK_ENABLE_INF 894 ENTER_PROTECTED_BLOCK 895 ISDESTROY() 896 // #CHECK# 897 if(pxLeft == NULL || pyTop == NULL || pcxWidth == NULL || pcyHeight == NULL) 898 { 899 return E_INVALIDARG; 900 } 901 902 if(varChild.vt==VT_I4) 903 { 904 if(varChild.lVal==CHILDID_SELF) 905 { 906 907 if(pUNOInterface) 908 { 909 Reference< XAccessibleContext > pRContext = pUNOInterface->getAccessibleContext(); 910 if( !pRContext.is() ) 911 return S_FALSE; 912 Reference< XAccessibleComponent > pRComponent(pRContext,UNO_QUERY); 913 if( !pRComponent.is() ) 914 return S_FALSE; 915 916 ::com::sun::star::awt::Point pCPoint = pRComponent->getLocationOnScreen(); 917 ::com::sun::star::awt::Size pCSize = pRComponent->getSize(); 918 *pxLeft = pCPoint.X; 919 *pyTop = pCPoint.Y; 920 *pcxWidth = pCSize.Width; 921 *pcyHeight = pCSize.Height; 922 return S_OK; 923 } 924 else 925 { 926 *pxLeft = m_sLocation.m_dLeft; 927 *pyTop = m_sLocation.m_dTop; 928 *pcxWidth = m_sLocation.m_dWidth; 929 *pcyHeight = m_sLocation.m_dHeight; 930 return S_OK; 931 } 932 } 933 934 } 935 return S_FALSE; 936 937 LEAVE_PROTECTED_BLOCK 938 } 939 940 /** 941 * Returns the current focused child to AT. 942 * @param navDir, the direction flag of the navigation. 943 * @param varStart, the start child id of this navigation action. 944 * @param pvarEndUpAt, [in,out] the end up child of this navigation action. 945 * @return S_OK if successful and E_FAIL if failure. 946 */ 947 STDMETHODIMP CMAccessible::accNavigate(long navDir, VARIANT varStart, VARIANT *pvarEndUpAt) 948 { 949 950 CHECK_ENABLE_INF 951 ENTER_PROTECTED_BLOCK 952 ISDESTROY() 953 // #CHECK# 954 if(pvarEndUpAt == NULL) 955 { 956 return E_INVALIDARG; 957 } 958 HRESULT ret = E_FAIL; 959 switch (navDir) 960 { 961 case NAVDIR_FIRSTCHILD: 962 ret = GetFirstChild(varStart,pvarEndUpAt); 963 break; 964 case NAVDIR_LASTCHILD: 965 ret = GetLastChild(varStart,pvarEndUpAt); 966 break; 967 case NAVDIR_NEXT: 968 ret = GetNextSibling(varStart,pvarEndUpAt); 969 break; 970 case NAVDIR_PREVIOUS: 971 ret = GetPreSibling(varStart,pvarEndUpAt); 972 break; 973 case NAVDIR_DOWN://do not implement temporarily 974 break; 975 case NAVDIR_UP://do not implement temporarily 976 break; 977 case NAVDIR_LEFT://do not implement temporarily 978 break; 979 case NAVDIR_RIGHT://do not implement temporarily 980 break; 981 default: 982 break; 983 }; 984 return ret; 985 986 LEAVE_PROTECTED_BLOCK 987 } 988 989 STDMETHODIMP CMAccessible::accHitTest(long xLeft, long yTop, VARIANT *pvarChild) 990 { 991 992 CHECK_ENABLE_INF 993 ENTER_PROTECTED_BLOCK 994 ISDESTROY() 995 // #CHECK# 996 if(pvarChild == NULL) 997 { 998 return E_INVALIDARG; 999 } 1000 long x, y, w, h; 1001 VARIANT varSelf; 1002 VariantInit(&varSelf); 1003 varSelf.vt = VT_I4; 1004 varSelf.lVal = CHILDID_SELF; 1005 accLocation(&x,&y,&w,&h,varSelf); 1006 if( (x < xLeft && (x + w) >xLeft) && (y < yTop && (y + h) >yTop) ) 1007 { 1008 int i, nCount; 1009 pvarChild->vt = VT_EMPTY; 1010 Reference< XAccessibleContext > pRContext = GetContextByXAcc(pUNOInterface); 1011 nCount = pRContext->getAccessibleChildCount(); 1012 if(nCount > 256) 1013 return E_FAIL; 1014 IMAccessible* child = NULL; 1015 for( i = 0; i<nCount; i++) 1016 { 1017 1018 child = GetChildInterface(i + 1); 1019 if(child && child->accHitTest(xLeft,yTop,pvarChild) == S_OK) 1020 break; 1021 } 1022 1023 if(pvarChild->vt == VT_DISPATCH) 1024 return S_OK; 1025 1026 if( i < nCount) 1027 { 1028 pvarChild->vt = VT_DISPATCH; 1029 pvarChild->pdispVal = child; 1030 child->AddRef(); 1031 } 1032 else 1033 { 1034 pvarChild->vt = VT_I4; 1035 pvarChild->lVal = CHILDID_SELF; 1036 } 1037 return S_OK; 1038 } 1039 return S_FALSE; 1040 1041 LEAVE_PROTECTED_BLOCK 1042 } 1043 1044 /** 1045 * Get The other Interface from CMAccessible. 1046 * @param guidService, must be IID_IAccessible here. 1047 * @param riid, the IID interface . 1048 * @return S_OK if successful and S_FALSE if failure. 1049 */ 1050 STDMETHODIMP CMAccessible::QueryService(REFGUID guidService, REFIID riid, void** ppvObject) 1051 { 1052 if( InlineIsEqualGUID(guidService, IID_IAccessible) ) 1053 return QueryInterface(riid, ppvObject); 1054 return S_FALSE; 1055 } 1056 1057 /** 1058 * Set the accessible name of the current COM object self or its one child from UNO. 1059 * @param varChild, vt member of varChild must be VT_I4,and lVal member stores the child ID, 1060 * the child ID specify child index from 0 to children count, 0 stands for object self. 1061 * @param szName, the name used to set the name of the proper object. 1062 * @return S_OK if successful and E_FAIL if failure. 1063 */ 1064 STDMETHODIMP CMAccessible::put_accName(VARIANT varChild, BSTR szName) 1065 { 1066 1067 ENTER_PROTECTED_BLOCK 1068 ISDESTROY() 1069 if(varChild.vt==VT_I4) 1070 { 1071 if(varChild.lVal==CHILDID_SELF) 1072 { 1073 SAFE_SYSFREESTRING(m_pszName); 1074 m_pszName=SysAllocString(szName); 1075 return S_OK; 1076 } 1077 1078 long lVal = varChild.lVal; 1079 varChild.lVal = CHILDID_SELF; 1080 IMAccessible *pChild = this->GetChildInterface(lVal); 1081 if(!pChild) 1082 return E_FAIL; 1083 return pChild->put_accName(varChild,szName); 1084 } 1085 return E_FAIL; 1086 1087 LEAVE_PROTECTED_BLOCK 1088 } 1089 1090 /** 1091 * Set the accessible value of the current COM object self or its one child from UNO. 1092 * @param varChild, vt member of varChild must be VT_I4,and lVal member stores the child ID, 1093 * the child ID specify child index from 0 to children count, 0 stands for object self. 1094 * @param szValue, the value used to set the value of the proper object. 1095 * @return S_OK if successful and E_FAIL if failure. 1096 */ 1097 STDMETHODIMP CMAccessible::put_accValue(VARIANT varChild, BSTR szValue) 1098 { 1099 1100 ENTER_PROTECTED_BLOCK 1101 ISDESTROY() 1102 if(varChild.vt==VT_I4) 1103 { 1104 if(varChild.lVal==CHILDID_SELF) 1105 { 1106 SysAllocString(m_pszValue); 1107 m_pszValue=SysAllocString(szValue); 1108 return S_OK; 1109 } 1110 1111 long lVal = varChild.lVal; 1112 varChild.lVal = CHILDID_SELF; 1113 IMAccessible *pChild = this->GetChildInterface(lVal); 1114 if(!pChild) 1115 return E_FAIL; 1116 return pChild->put_accValue(varChild,szValue); 1117 } 1118 return E_FAIL; 1119 1120 LEAVE_PROTECTED_BLOCK 1121 } 1122 1123 /** 1124 * Set the accessible name of the current COM object self from UNO. 1125 * @param pszName, the name value used to set the name of the current object. 1126 * @return S_OK if successful and E_FAIL if failure. 1127 */ 1128 STDMETHODIMP CMAccessible::Put_XAccName(const OLECHAR __RPC_FAR *pszName) 1129 { 1130 1131 ENTER_PROTECTED_BLOCK 1132 ISDESTROY() 1133 // #CHECK# 1134 if(pszName == NULL) 1135 { 1136 return E_INVALIDARG; 1137 } 1138 1139 SAFE_SYSFREESTRING(m_pszName);//?? 1140 m_pszName = SysAllocString(pszName); 1141 if(m_pszName==NULL) 1142 return E_FAIL; 1143 return S_OK; 1144 1145 LEAVE_PROTECTED_BLOCK 1146 } 1147 1148 /** 1149 * Set the accessible role of the current COM object self from UNO. 1150 * @param pRole, the role value used to set the role of the current object. 1151 * @return S_OK if successful and E_FAIL if failure. 1152 */ 1153 STDMETHODIMP CMAccessible::Put_XAccRole(unsigned short pRole) 1154 { 1155 m_iRole = pRole; 1156 return S_OK; 1157 } 1158 1159 /** 1160 * Add one state into the current state set for the current COM object from UNO. 1161 * @param pXSate, the state used to set the name of the current object. 1162 * @return S_OK if successful and E_FAIL if failure. 1163 */ 1164 STDMETHODIMP CMAccessible::DecreaseState(DWORD pXSate) 1165 { 1166 m_dState &= (~pXSate); 1167 return S_OK; 1168 } 1169 1170 /** 1171 * Delete one state into the current state set for the current COM object from UNO. 1172 * @param pXSate, the state used to set the name of the current object. 1173 * @return S_OK if successful and E_FAIL if failure. 1174 */ 1175 STDMETHODIMP CMAccessible::IncreaseState(DWORD pXSate) 1176 { 1177 m_dState |= pXSate; 1178 return S_OK; 1179 } 1180 1181 /** 1182 * Set state into the current state set for the current COM object from UNO. 1183 * @param pXSate, the state used to set the name of the current object. 1184 * @return S_OK if successful and E_FAIL if failure. 1185 */ 1186 STDMETHODIMP CMAccessible::SetState(DWORD pXSate) 1187 { 1188 m_dState = pXSate; 1189 return S_OK; 1190 } 1191 1192 1193 1194 /** 1195 * Set the accessible description of the current COM object self from UNO. 1196 * @param pszDescription, the name used to set the description of the current object. 1197 * @return S_OK if successful and E_FAIL if failure. 1198 */ 1199 STDMETHODIMP CMAccessible::Put_XAccDescription(const OLECHAR __RPC_FAR *pszDescription) 1200 { 1201 1202 ENTER_PROTECTED_BLOCK 1203 ISDESTROY() 1204 // #CHECK# 1205 if(pszDescription == NULL) 1206 { 1207 return E_INVALIDARG; 1208 } 1209 1210 SAFE_SYSFREESTRING(m_pszDescription); 1211 m_pszDescription = SysAllocString(pszDescription); 1212 1213 if(m_pszDescription==NULL) 1214 return E_FAIL; 1215 return S_OK; 1216 1217 LEAVE_PROTECTED_BLOCK 1218 } 1219 1220 /** 1221 * Set the accessible value of the current COM object self from UNO. 1222 * @param pszAccValue, the name used to set the value of the current object. 1223 * @return S_OK if successful and E_FAIL if failure. 1224 */ 1225 STDMETHODIMP CMAccessible::Put_XAccValue(const OLECHAR __RPC_FAR *pszAccValue) 1226 { 1227 1228 ENTER_PROTECTED_BLOCK 1229 ISDESTROY() 1230 // #CHECK# 1231 if(pszAccValue == NULL) 1232 { 1233 return E_INVALIDARG; 1234 } 1235 SAFE_SYSFREESTRING(m_pszValue); 1236 m_pszValue = SysAllocString(pszAccValue); 1237 if(m_pszValue==NULL) 1238 return E_FAIL; 1239 return S_OK; 1240 1241 LEAVE_PROTECTED_BLOCK 1242 } 1243 1244 /** 1245 * Set the HWND value of the current COM object self from UNO. It should set the parent IAccessible 1246 * Object through the method AccessibleObjectFromWindow(...). 1247 * @param hwnd, the HWND used to set the value of the current object. 1248 * @return S_OK if successful and E_FAIL if failure. 1249 */ 1250 STDMETHODIMP CMAccessible::Put_XAccWindowHandle(HWND hwnd) 1251 { 1252 1253 ENTER_PROTECTED_BLOCK 1254 ISDESTROY() 1255 m_hwnd = hwnd; 1256 return S_OK; 1257 1258 LEAVE_PROTECTED_BLOCK 1259 } 1260 1261 /** 1262 * Set accessible focus by specifying child ID 1263 * @param dChildID, the child id identifies the focus child. 1264 * @return S_OK if successful and E_FAIL if failure. 1265 */ 1266 STDMETHODIMP CMAccessible::Put_XAccFocus(long dChildID) 1267 { 1268 1269 ENTER_PROTECTED_BLOCK 1270 ISDESTROY() 1271 1272 if(dChildID==CHILDID_SELF) 1273 { 1274 if(m_pIParent) 1275 { 1276 m_pIParent->Put_XAccFocus(m_dChildID); 1277 } 1278 } 1279 else 1280 { 1281 m_dFocusChildID = dChildID; 1282 //traverse all ancestors to set the focused child ID so that when the get_accFocus is called on 1283 //any of the ancestors, this id can be used to get the IAccessible of focused object. 1284 if(m_pIParent) 1285 { 1286 m_pIParent->Put_XAccFocus(dChildID); 1287 } 1288 } 1289 return S_OK; 1290 1291 LEAVE_PROTECTED_BLOCK 1292 } 1293 1294 /** 1295 *Set accessible object location for the current COM object 1296 * @param sLocation, the location of the current object. 1297 * @return S_OK if successful and E_FAIL if failure. 1298 */ 1299 STDMETHODIMP CMAccessible::Put_XAccLocation(const Location sLocation) 1300 { 1301 1302 this->m_sLocation = sLocation; 1303 return S_OK; 1304 } 1305 1306 /** 1307 * Set accessible parent object for the current COM object if 1308 * the current object is a child of some COM object 1309 * @param pIParent, the parent of the current object. 1310 * @return S_OK if successful and E_FAIL if failure. 1311 */ 1312 STDMETHODIMP CMAccessible::Put_XAccParent(IMAccessible __RPC_FAR *pIParent) 1313 { 1314 this->m_pIParent = pIParent; 1315 1316 if(pIParent) 1317 m_pIParent->AddRef(); 1318 1319 return S_OK; 1320 } 1321 1322 /** 1323 * Set unique child id to COM 1324 * @param dChildID, the id of the current object. 1325 * @return S_OK if successful and E_FAIL if failure. 1326 */ 1327 STDMETHODIMP CMAccessible::Put_XAccChildID(long dChildID) 1328 { 1329 1330 this->m_dChildID = dChildID; 1331 return S_OK; 1332 } 1333 1334 /** 1335 * Set AccObjectManagerAgent object pointer to COM 1336 * @param pAgent, the AccObjectManagerAgent point. 1337 * @return S_OK if successful and E_FAIL if failure. 1338 */ 1339 STDMETHODIMP CMAccessible::Put_XAccAgent(long pAgent) 1340 { 1341 g_pAgent = (AccObjectManagerAgent*)pAgent; 1342 return S_OK; 1343 } 1344 1345 /** 1346 * When a UNO control disposing, it disposes its listeners, 1347 * then notify AccObject in bridge management, then notify 1348 * COM that the XAccessible is invalid,so set pUNOInterface as NULL 1349 * @param isDestroy, true is it need to be destroyed. 1350 * @return S_OK if successful and E_FAIL if failure. 1351 */ 1352 STDMETHODIMP CMAccessible::NotifyDestroy(BOOL isDestroy) 1353 { 1354 1355 m_isDestroy = isDestroy; 1356 pUNOInterface = NULL; 1357 return S_OK; 1358 } 1359 1360 /** 1361 *private methods that help implement public functions 1362 */ 1363 1364 /** 1365 * Return child interface pointer by child ID,note: need to call AddRef() 1366 * @param lChildID, specify child index,which AT(such as Inspect32) gives. 1367 * @return IMAccessible*, pointer to the corresponding child object. 1368 */ 1369 IMAccessible* CMAccessible::GetChildInterface(long dChildID)//for test 1370 { 1371 1372 long dChildIndex = 0; 1373 if(dChildID<0) 1374 { 1375 if(g_pAgent) 1376 { 1377 IMAccessible* pIMAcc = NULL; 1378 g_pAgent->GetIAccessibleFromResID(dChildID,&pIMAcc); 1379 return pIMAcc; 1380 } 1381 return NULL; 1382 } 1383 else 1384 { 1385 Reference< XAccessibleContext > pRContext = pUNOInterface->getAccessibleContext(); 1386 if( !pRContext.is() ) 1387 return NULL; 1388 1389 if(dChildID<1 || dChildID>pRContext->getAccessibleChildCount()) 1390 return NULL; 1391 1392 IAccessible* pChild = NULL; 1393 Reference< XAccessible > pXChild = pRContext->getAccessibleChild(dChildID-1); 1394 BOOL isGet = get_IAccessibleFromXAccessible((long)pXChild.get(),&pChild); 1395 1396 if(!isGet) 1397 { 1398 g_pAgent->InsertAccObj(pXChild.get(),pUNOInterface,(long)m_hwnd); 1399 isGet = get_IAccessibleFromXAccessible((long)pXChild.get(),&pChild); 1400 } 1401 1402 if(isGet) 1403 { 1404 IMAccessible* pIMAcc = (IMAccessible*)pChild; 1405 return pIMAcc; 1406 } 1407 } 1408 1409 return NULL; 1410 } 1411 1412 /** 1413 * For List, tree and table,these roles belong to manage_decendant in UNO, 1414 * need to process specifically when navigate 1415 * @return BOOL, if it is decendantmanager, return true. 1416 */ 1417 BOOL CMAccessible::IsDecendantManage() 1418 { 1419 1420 return (m_iRole==ROLE_SYSTEM_LIST)||(m_iRole==ROLE_SYSTEM_OUTLINE)||(m_iRole==ROLE_SYSTEM_TABLE); 1421 } 1422 1423 /** 1424 * for decendantmanager circumstance,provide child interface when navigate 1425 * @param varCur, the current child. 1426 * @param flags, the navigation direction. 1427 * @return IMAccessible*, the child of the end up node. 1428 */ 1429 IMAccessible* CMAccessible::GetNavigateChildForDM(VARIANT varCur, short flags) 1430 { 1431 1432 XAccessibleContext* pXContext = GetContextByXAcc(pUNOInterface); 1433 if(pXContext==NULL) 1434 { 1435 return NULL; 1436 } 1437 1438 int count = pXContext->getAccessibleChildCount(); 1439 if(count<1) 1440 { 1441 return NULL; 1442 } 1443 1444 IMAccessible* pCurChild = NULL; 1445 XAccessible* pChildXAcc = NULL; 1446 Reference<XAccessible> pRChildXAcc; 1447 XAccessibleContext* pChildContext = NULL; 1448 int index = 0,delta=0; 1449 switch(flags) 1450 { 1451 case DM_FIRSTCHILD: 1452 pRChildXAcc = pXContext->getAccessibleChild(0); 1453 break; 1454 case DM_LASTCHILD: 1455 pRChildXAcc = pXContext->getAccessibleChild(count-1); 1456 break; 1457 case DM_NEXTCHILD: 1458 case DM_PREVCHILD: 1459 pCurChild = GetChildInterface(varCur.lVal); 1460 if(pCurChild==NULL) 1461 { 1462 return NULL; 1463 } 1464 pCurChild->GetUNOInterface((long*)&pChildXAcc); 1465 if(pChildXAcc==NULL) 1466 { 1467 return NULL; 1468 } 1469 pChildContext = GetContextByXAcc(pChildXAcc); 1470 if(pChildContext == NULL) 1471 { 1472 return NULL; 1473 } 1474 delta = (flags==DM_NEXTCHILD)?1:-1; 1475 //currently, getAccessibleIndexInParent is error in UNO for 1476 //some kind of List,such as ValueSet, the index will be less 1 than 1477 //what should be, need to fix UNO code 1478 index = pChildContext->getAccessibleIndexInParent()+delta; 1479 if((index>=0)&&(index<=count-1)) 1480 { 1481 pRChildXAcc = pXContext->getAccessibleChild(index); 1482 } 1483 break; 1484 default: 1485 break; 1486 } 1487 1488 if(!pRChildXAcc.is()) 1489 { 1490 return NULL; 1491 } 1492 pChildXAcc = pRChildXAcc.get(); 1493 g_pAgent->InsertAccObj(pChildXAcc,pUNOInterface); 1494 return g_pAgent->GetIMAccByXAcc(pChildXAcc); 1495 } 1496 1497 /** 1498 *the following 4 private methods are for accNavigate implementation 1499 */ 1500 1501 /** 1502 * Return first child for parent container, process differently according 1503 * to whether it is decendant manage 1504 * @param varStart, the start child id of this navigation action. 1505 * @param pvarEndUpAt, [in,out] the end up child of this navigation action. 1506 * @return S_OK if successful and E_FAIL if failure. 1507 */ 1508 HRESULT CMAccessible::GetFirstChild(VARIANT varStart,VARIANT* pvarEndUpAt) 1509 { 1510 1511 ENTER_PROTECTED_BLOCK 1512 ISDESTROY() 1513 // #CHECK# 1514 if(pvarEndUpAt == NULL) 1515 { 1516 return E_INVALIDARG; 1517 } 1518 if(varStart.vt != VT_I4) 1519 { 1520 pvarEndUpAt->vt = VT_EMPTY; 1521 return E_INVALIDARG; 1522 } 1523 1524 pvarEndUpAt->pdispVal = GetNavigateChildForDM(varStart, DM_FIRSTCHILD); 1525 if(pvarEndUpAt->pdispVal) 1526 { 1527 pvarEndUpAt->pdispVal->AddRef(); 1528 pvarEndUpAt->vt = VT_DISPATCH; 1529 return S_OK; 1530 } 1531 1532 pvarEndUpAt->vt = VT_EMPTY; 1533 return E_FAIL; 1534 1535 LEAVE_PROTECTED_BLOCK 1536 } 1537 1538 /** 1539 * Return last child for parent container, process differently according 1540 * to whether it is decendant manage 1541 * @param varStart, the start child id of this navigation action. 1542 * @param pvarEndUpAt, [in,out] the end up child of this navigation action. 1543 * @return S_OK if successful and E_FAIL if failure. 1544 */ 1545 HRESULT CMAccessible::GetLastChild(VARIANT varStart,VARIANT* pvarEndUpAt) 1546 { 1547 1548 ENTER_PROTECTED_BLOCK 1549 ISDESTROY() 1550 // #CHECK# 1551 if(pvarEndUpAt == NULL) 1552 { 1553 return E_INVALIDARG; 1554 } 1555 if(varStart.vt != VT_I4) 1556 { 1557 pvarEndUpAt->vt = VT_EMPTY; 1558 return E_INVALIDARG; 1559 } 1560 1561 pvarEndUpAt->pdispVal = GetNavigateChildForDM(varStart, DM_LASTCHILD); 1562 if(pvarEndUpAt->pdispVal) 1563 { 1564 pvarEndUpAt->pdispVal->AddRef(); 1565 pvarEndUpAt->vt = VT_DISPATCH; 1566 return S_OK; 1567 } 1568 pvarEndUpAt->vt = VT_EMPTY; 1569 return E_FAIL; 1570 1571 LEAVE_PROTECTED_BLOCK 1572 } 1573 1574 /** 1575 * The method GetNextSibling is general, whatever it is decendant manage or not 1576 * Get the next sibling object. 1577 * @param varStart, the start child id of this navigation action. 1578 * @param pvarEndUpAt, [in,out] the end up child of this navigation action. 1579 * @return S_OK if successful and E_FAIL if failure. 1580 */ 1581 HRESULT CMAccessible::GetNextSibling(VARIANT varStart,VARIANT* pvarEndUpAt) 1582 { 1583 1584 ENTER_PROTECTED_BLOCK 1585 ISDESTROY() 1586 if(varStart.vt != VT_I4) 1587 { 1588 pvarEndUpAt->vt = VT_EMPTY; 1589 return E_INVALIDARG; 1590 } 1591 1592 Reference< XAccessibleContext > pRContext = GetContextByXAcc(pUNOInterface); 1593 if(pRContext.is()) 1594 { 1595 varStart.iVal = sal_Int16(pRContext->getAccessibleIndexInParent() + 2); 1596 if(m_pIParent) 1597 if( m_pIParent->get_accChild(varStart,&pvarEndUpAt->pdispVal) == S_OK) 1598 { 1599 pvarEndUpAt->vt = VT_DISPATCH; 1600 return S_OK; 1601 } 1602 } 1603 pvarEndUpAt->vt = VT_EMPTY; 1604 return E_FAIL; 1605 1606 LEAVE_PROTECTED_BLOCK 1607 } 1608 1609 /** 1610 *the method GetPreSibling is general, whatever it is decendant manage or not 1611 * @param varStart, the start child id of this navigation action. 1612 * @param pvarEndUpAt, [in,out] the end up child of this navigation action. 1613 * @return S_OK if successful and E_FAIL if failure. 1614 */ 1615 HRESULT CMAccessible::GetPreSibling(VARIANT varStart,VARIANT* pvarEndUpAt) 1616 { 1617 1618 ENTER_PROTECTED_BLOCK 1619 ISDESTROY() 1620 // #CHECK# 1621 if(pvarEndUpAt == NULL) 1622 { 1623 return E_INVALIDARG; 1624 } 1625 if(varStart.vt != VT_I4) 1626 { 1627 pvarEndUpAt->vt = VT_EMPTY; 1628 return E_INVALIDARG; 1629 } 1630 1631 Reference< XAccessibleContext > pRContext = GetContextByXAcc(pUNOInterface); 1632 if(pRContext.is()) 1633 { 1634 varStart.iVal = sal_Int16(pRContext->getAccessibleIndexInParent()); 1635 if(m_pIParent && varStart.iVal > 0) 1636 if( m_pIParent->get_accChild(varStart,&pvarEndUpAt->pdispVal) == S_OK) 1637 { 1638 pvarEndUpAt->vt = VT_DISPATCH; 1639 return S_OK; 1640 } 1641 } 1642 pvarEndUpAt->vt = VT_EMPTY; 1643 return E_FAIL; 1644 1645 LEAVE_PROTECTED_BLOCK 1646 } 1647 1648 /** 1649 * For IAccessible2 implementation methods 1650 */ 1651 STDMETHODIMP CMAccessible::get_nRelations( long __RPC_FAR *nRelations) 1652 { 1653 1654 CHECK_ENABLE_INF 1655 ENTER_PROTECTED_BLOCK 1656 1657 // #CHECK# 1658 if(nRelations == NULL) 1659 { 1660 return E_INVALIDARG; 1661 } 1662 1663 *nRelations = 0; 1664 1665 if( !pRContext.is() ) 1666 return E_FAIL; 1667 Reference<XAccessibleRelationSet> pRrelationSet = pRContext.get()->getAccessibleRelationSet(); 1668 if(!pRrelationSet.is()) 1669 { 1670 *nRelations = 0; 1671 return S_OK; 1672 } 1673 1674 *nRelations = pRrelationSet->getRelationCount(); 1675 return S_OK; 1676 1677 LEAVE_PROTECTED_BLOCK 1678 } 1679 1680 STDMETHODIMP CMAccessible::get_relation( long relationIndex, IAccessibleRelation __RPC_FAR *__RPC_FAR *relation) 1681 { 1682 1683 CHECK_ENABLE_INF 1684 ENTER_PROTECTED_BLOCK 1685 ISDESTROY() 1686 // #CHECK# 1687 if(relation == NULL) 1688 { 1689 return E_INVALIDARG; 1690 } 1691 1692 if( !pRContext.is() ) 1693 return E_FAIL; 1694 1695 1696 long nMax = 0; 1697 long nReal = 0; 1698 get_nRelations(&nMax); 1699 1700 *relation = (IAccessibleRelation*)::CoTaskMemAlloc(sizeof(IAccessibleRelation)); 1701 1702 // #CHECK Memory Allocation# 1703 if(*relation == NULL) 1704 { 1705 return E_FAIL; 1706 } 1707 1708 if( relationIndex < nMax ) 1709 { 1710 1711 1712 Reference<XAccessibleRelationSet> pRrelationSet = pRContext.get()->getAccessibleRelationSet(); 1713 if(!pRrelationSet.is()) 1714 { 1715 1716 return E_FAIL; 1717 } 1718 1719 IAccessibleRelation* pRelation = NULL; 1720 HRESULT hr = CoCreateInstance( CLSID_AccRelation, NULL, CLSCTX_SERVER , 1721 IID_IAccessibleRelation, 1722 (void **)&pRelation); 1723 if(SUCCEEDED(hr)) 1724 { 1725 IUNOXWrapper* wrapper = NULL; 1726 hr = pRelation->QueryInterface(IID_IUNOXWrapper, (void**)&wrapper); 1727 if(SUCCEEDED(hr)) 1728 { 1729 AccessibleRelation accRelation = pRrelationSet->getRelation(relationIndex); 1730 wrapper->put_XSubInterface((long)&accRelation); 1731 wrapper->Release(); 1732 *relation = pRelation; 1733 return S_OK; 1734 } 1735 1736 } 1737 } 1738 1739 return E_FAIL; 1740 1741 LEAVE_PROTECTED_BLOCK 1742 } 1743 1744 STDMETHODIMP CMAccessible::get_relations( long, IAccessibleRelation __RPC_FAR *__RPC_FAR *relation, long __RPC_FAR *nRelations) 1745 { 1746 1747 CHECK_ENABLE_INF 1748 ENTER_PROTECTED_BLOCK 1749 1750 // #CHECK# 1751 if(relation == NULL || nRelations == NULL) 1752 { 1753 return E_INVALIDARG; 1754 } 1755 // #CHECK XInterface# 1756 1757 if( !pRContext.is() ) 1758 return E_FAIL; 1759 1760 Reference<XAccessibleRelationSet> pRrelationSet = pRContext.get()->getAccessibleRelationSet(); 1761 if(!pRrelationSet.is()) 1762 { 1763 *nRelations = 0; 1764 return S_OK; 1765 } 1766 1767 long nCount = pRrelationSet->getRelationCount(); 1768 1769 *relation = (IAccessibleRelation*)::CoTaskMemAlloc(nCount*sizeof(IAccessibleRelation)); 1770 1771 // #CHECK Memory Allocation# 1772 if(*relation == NULL) 1773 { 1774 return E_FAIL; 1775 } 1776 1777 for(int i=0; i<nCount ; i++) 1778 { 1779 IAccessibleRelation* pRelation = NULL; 1780 HRESULT hr = CoCreateInstance( CLSID_AccRelation, NULL, CLSCTX_SERVER , 1781 IID_IAccessibleRelation, 1782 (void **)&pRelation); 1783 if(SUCCEEDED(hr)) 1784 { 1785 IUNOXWrapper* wrapper = NULL; 1786 hr = pRelation->QueryInterface(IID_IUNOXWrapper, (void**)&wrapper); 1787 if(SUCCEEDED(hr)) 1788 { 1789 AccessibleRelation accRelation = pRrelationSet->getRelation(i); 1790 wrapper->put_XSubInterface((long)&accRelation); 1791 wrapper->Release(); 1792 } 1793 (relation)[i] = pRelation; 1794 } 1795 } 1796 1797 *nRelations = nCount; 1798 return S_OK; 1799 1800 LEAVE_PROTECTED_BLOCK 1801 } 1802 1803 STDMETHODIMP CMAccessible::role(long __RPC_FAR *role) 1804 { 1805 ENTER_PROTECTED_BLOCK 1806 1807 (*role) = m_iRole; 1808 1809 return S_OK; 1810 1811 LEAVE_PROTECTED_BLOCK 1812 } 1813 1814 1815 STDMETHODIMP CMAccessible:: get_nActions(long __RPC_FAR *nActions) 1816 { 1817 1818 try 1819 { 1820 ISDESTROY() 1821 // #CHECK# 1822 if(nActions == NULL) 1823 { 1824 return E_INVALIDARG; 1825 } 1826 *nActions = 0L; 1827 IAccessibleAction* pAcc = NULL; 1828 HRESULT hr = QueryInterface(IID_IAccessibleAction, (void**)&pAcc); 1829 if( hr == S_OK ) 1830 { 1831 pAcc->nActions(nActions); 1832 pAcc->Release(); 1833 } 1834 1835 return S_OK; 1836 } 1837 catch(...) 1838 { 1839 *nActions = 0L; 1840 return S_OK; 1841 } 1842 } 1843 1844 1845 STDMETHODIMP CMAccessible:: scrollToPoint(enum IA2CoordinateType, long, long) 1846 { 1847 1848 ENTER_PROTECTED_BLOCK 1849 ISDESTROY() 1850 return E_NOTIMPL; 1851 LEAVE_PROTECTED_BLOCK 1852 1853 } 1854 STDMETHODIMP CMAccessible:: scrollTo(enum IA2ScrollType) 1855 { 1856 1857 ENTER_PROTECTED_BLOCK 1858 ISDESTROY() 1859 1860 return E_NOTIMPL; 1861 1862 LEAVE_PROTECTED_BLOCK 1863 } 1864 1865 static XAccessible* getTheParentOfMember(XAccessible* pXAcc) 1866 { 1867 // #CHECK# 1868 if(pXAcc == NULL) 1869 { 1870 return NULL; 1871 } 1872 Reference<XAccessibleContext> pRContext = pXAcc->getAccessibleContext(); 1873 Reference<XAccessibleRelationSet> pRrelationSet = pRContext->getAccessibleRelationSet(); 1874 long nRelations = pRrelationSet->getRelationCount(); 1875 for(int i=0 ; i<nRelations ; i++) 1876 { 1877 AccessibleRelation accRelation = pRrelationSet->getRelation(i); 1878 if(accRelation.RelationType == 7) 1879 { 1880 Sequence< Reference< XInterface > > xTargets = accRelation.TargetSet; 1881 return (XAccessible*)xTargets[0].get(); 1882 } 1883 } 1884 return NULL; 1885 } 1886 1887 STDMETHODIMP CMAccessible:: get_groupPosition(long __RPC_FAR *groupLevel,long __RPC_FAR *similarItemsInGroup,long __RPC_FAR *positionInGroup) 1888 { 1889 1890 CHECK_ENABLE_INF 1891 ENTER_PROTECTED_BLOCK 1892 ISDESTROY() 1893 // #CHECK# 1894 if(groupLevel == NULL || similarItemsInGroup == NULL || positionInGroup == NULL) 1895 { 1896 return E_INVALIDARG; 1897 } 1898 1899 Reference<XAccessibleContext> pRContext = pUNOInterface->getAccessibleContext(); 1900 if(!pRContext.is()) 1901 return E_FAIL; 1902 long Role = pRContext->getAccessibleRole(); 1903 1904 *groupLevel = 0; 1905 *similarItemsInGroup = 0; 1906 *positionInGroup = 0; 1907 1908 if (Role != AccessibleRole::DOCUMENT) 1909 { 1910 Reference< XAccessibleGroupPosition > xGroupPosition( pRContext, UNO_QUERY ); 1911 if ( xGroupPosition.is() ) 1912 { 1913 Sequence< sal_Int32 > rSeq = xGroupPosition->getGroupPosition( makeAny( pRContext ) ); 1914 sal_Int32* pSeq = rSeq.getArray(); 1915 if ( pSeq ) 1916 { 1917 *groupLevel = pSeq[0]; 1918 *similarItemsInGroup = pSeq[1]; 1919 *positionInGroup = pSeq[2]; 1920 return S_OK; 1921 } 1922 return S_OK; 1923 } 1924 } 1925 1926 Reference< XAccessible> pParentAcc = pRContext->getAccessibleParent(); 1927 if( !pParentAcc.is() ) 1928 { 1929 return S_OK; 1930 } 1931 1932 Reference<XAccessibleContext> pRParentContext = pParentAcc->getAccessibleContext(); 1933 1934 int level = 0; 1935 int index = 0; 1936 int number = 0; 1937 1938 if( Role == RADIO_BUTTON ) 1939 { 1940 Reference<XAccessibleRelationSet> pRrelationSet = pRContext->getAccessibleRelationSet(); 1941 long nRel = pRrelationSet->getRelationCount(); 1942 for(int i=0 ; i<nRel ; i++) 1943 { 1944 AccessibleRelation accRelation = pRrelationSet->getRelation(i); 1945 if(accRelation.RelationType == 7) 1946 { 1947 Sequence< Reference< XInterface > > xTargets = accRelation.TargetSet; 1948 int nCount = xTargets.getLength(); 1949 1950 Reference<XInterface> pRAcc = xTargets[0]; 1951 for(int j=0; j<pRParentContext->getAccessibleChildCount(); j++) 1952 { 1953 if( getTheParentOfMember(pRParentContext->getAccessibleChild(j).get()) 1954 == (XAccessible*)pRAcc.get() && 1955 pRParentContext->getAccessibleChild(j)->getAccessibleContext()->getAccessibleRole() == RADIO_BUTTON) 1956 number++; 1957 if(pRParentContext->getAccessibleChild(j).get() == pUNOInterface) 1958 index = number; 1959 } 1960 } 1961 } 1962 *groupLevel = 1; 1963 *similarItemsInGroup = number; 1964 *positionInGroup = index; 1965 return S_OK; 1966 } 1967 1968 else if ( COMBO_BOX == Role ) 1969 { 1970 *groupLevel = 1; 1971 *similarItemsInGroup = 0; 1972 *positionInGroup = -1; 1973 1974 long nCount = pRContext->getAccessibleChildCount(); 1975 if( 2 != nCount) 1976 { 1977 return S_OK; 1978 } 1979 Reference<XAccessible> xList=pRContext->getAccessibleChild(1); 1980 if (!xList.is()) 1981 { 1982 return S_OK; 1983 } 1984 Reference<XAccessibleContext> xListContext(xList,UNO_QUERY); 1985 if (!xListContext.is()) 1986 { 1987 return S_OK; 1988 } 1989 Reference<XAccessibleSelection> xListSel(xList,UNO_QUERY); 1990 if (!xListSel.is()) 1991 { 1992 return S_OK; 1993 } 1994 *similarItemsInGroup = xListContext->getAccessibleChildCount(); 1995 if (*similarItemsInGroup > 0 ) 1996 { 1997 try 1998 { 1999 Reference<XAccessible> xChild = xListSel->getSelectedAccessibleChild(0); 2000 if (xChild.is()) 2001 { 2002 Reference<XAccessibleContext> xChildContext(xChild,UNO_QUERY); 2003 if (xChildContext.is()) 2004 { 2005 *positionInGroup=xChildContext->getAccessibleIndexInParent() + 1 ; 2006 return S_OK; 2007 } 2008 } 2009 } 2010 catch(...) 2011 {} 2012 } 2013 return S_OK; 2014 } 2015 else if ( PAGE_TAB == Role ) 2016 { 2017 *groupLevel = 1; 2018 *similarItemsInGroup = pRParentContext->getAccessibleChildCount(); 2019 2020 if (*similarItemsInGroup > 0 ) 2021 { 2022 *positionInGroup=pRContext->getAccessibleIndexInParent() + 1 ; 2023 } 2024 else 2025 { 2026 *positionInGroup = -1; 2027 } 2028 return S_OK; 2029 } 2030 2031 2032 BOOL isFound = FALSE; 2033 while( pParentAcc.is() && !isFound) 2034 { 2035 level++; 2036 pRParentContext = pParentAcc->getAccessibleContext(); 2037 Role = pRParentContext->getAccessibleRole(); 2038 if( (Role == TREE) || (Role == LIST) ) 2039 isFound = TRUE; 2040 pParentAcc = pRParentContext->getAccessibleParent(); 2041 } 2042 2043 if( isFound ) 2044 { 2045 Reference< XAccessible> pTempAcc = pRContext->getAccessibleParent(); 2046 pRParentContext = pTempAcc->getAccessibleContext(); 2047 *groupLevel = level; 2048 *similarItemsInGroup = pRParentContext->getAccessibleChildCount(); 2049 *positionInGroup = pRContext->getAccessibleIndexInParent() + 1; 2050 } 2051 else 2052 { 2053 *groupLevel = 0; 2054 *similarItemsInGroup = 0; 2055 *positionInGroup = 0; 2056 } 2057 return S_OK; 2058 2059 LEAVE_PROTECTED_BLOCK 2060 } 2061 2062 STDMETHODIMP CMAccessible:: get_extendedStates( long, BSTR __RPC_FAR *__RPC_FAR *, long __RPC_FAR *) 2063 { 2064 2065 CHECK_ENABLE_INF 2066 ENTER_PROTECTED_BLOCK 2067 ISDESTROY() 2068 2069 return E_NOTIMPL; 2070 2071 LEAVE_PROTECTED_BLOCK 2072 } 2073 2074 2075 STDMETHODIMP CMAccessible:: get_uniqueID(long __RPC_FAR *uniqueID) 2076 { 2077 2078 ENTER_PROTECTED_BLOCK 2079 ISDESTROY() 2080 // #CHECK# 2081 if(uniqueID == NULL) 2082 { 2083 return E_INVALIDARG; 2084 } 2085 *uniqueID = m_dChildID; 2086 return S_OK; 2087 2088 LEAVE_PROTECTED_BLOCK 2089 } 2090 2091 STDMETHODIMP CMAccessible:: get_windowHandle(HWND __RPC_FAR *windowHandle) 2092 { 2093 2094 ENTER_PROTECTED_BLOCK 2095 ISDESTROY() 2096 // #CHECK# 2097 if(windowHandle == NULL) 2098 { 2099 return E_INVALIDARG; 2100 } 2101 2102 HWND nHwnd = m_hwnd; 2103 IAccessible* pParent = m_pIParent; 2104 CMAccessible* pChild = this; 2105 while((nHwnd==0) && pParent) 2106 { 2107 pChild = (CMAccessible*)pParent; 2108 if(pChild) 2109 { 2110 pParent = (IAccessible*)pChild->m_pIParent; 2111 nHwnd = (HWND)pChild->m_hwnd; 2112 } 2113 else 2114 pParent = NULL; 2115 } 2116 2117 *windowHandle = nHwnd; 2118 return S_OK; 2119 2120 LEAVE_PROTECTED_BLOCK 2121 } 2122 2123 /** 2124 * Get XAccessibleContext directly from UNO by the stored XAccessible pointer 2125 * @param pXAcc, UNO XAccessible object point. 2126 * @return XAccessibleContext*, the context of the pXAcc. 2127 */ 2128 XAccessibleContext* CMAccessible::GetContextByXAcc( XAccessible* pXAcc ) 2129 { 2130 Reference< XAccessibleContext > pRContext; 2131 if( pXAcc == NULL) 2132 return NULL; 2133 2134 pRContext = pXAcc->getAccessibleContext(); 2135 if( !pRContext.is() ) 2136 return NULL; 2137 return pRContext.get(); 2138 } 2139 2140 /** 2141 * Return the member variable m_pXAccessibleSelection, instead of 2142 * get XAccessibleSelection according to XAccessibleContext because if so,it will 2143 * depend on the UNO implementation code,so when COM is created, put XAccessibleSelection 2144 * by bridge management system 2145 * @return XAccessibleSelection*, the selection of the current object. 2146 */ 2147 Reference< XAccessibleSelection > CMAccessible::GetSelection() 2148 { 2149 if( pUNOInterface == NULL ) 2150 return NULL; 2151 Reference< XAccessibleContext > pRContext = pUNOInterface->getAccessibleContext(); 2152 if(pRContext.is()) 2153 { 2154 Reference< XAccessibleSelection > pRSelection(pRContext,UNO_QUERY); 2155 return pRSelection; 2156 } 2157 return NULL; 2158 } 2159 2160 /** 2161 * Select one XAccessible item, for accSelect implementation 2162 * @param pItem, the item should be selected. 2163 * @return S_OK if successful. 2164 */ 2165 HRESULT CMAccessible::SelectChild(XAccessible* pItem) 2166 { 2167 2168 ENTER_PROTECTED_BLOCK 2169 ISDESTROY() 2170 XAccessibleContext* pParentContext = GetContextByXAcc( pUNOInterface ); 2171 XAccessibleContext* pContext = GetContextByXAcc( pItem ); 2172 if( pParentContext == NULL || pContext == NULL ) 2173 return E_FAIL; 2174 2175 Reference< XAccessibleSelection > pRSelection = GetSelection(); 2176 if( !pRSelection.is() ) 2177 return E_FAIL; 2178 long Index = pContext->getAccessibleIndexInParent(); 2179 pRSelection->selectAccessibleChild( Index ); 2180 return S_OK; 2181 2182 LEAVE_PROTECTED_BLOCK 2183 } 2184 2185 /** 2186 * Deselect one XAccessible item, for accSelect implimentation 2187 * @param pItem, the item should be deselected. 2188 * @return S_OK if successful. 2189 */ 2190 HRESULT CMAccessible::DeSelectChild(XAccessible* pItem) 2191 { 2192 2193 ENTER_PROTECTED_BLOCK 2194 ISDESTROY() 2195 XAccessibleContext* pParentContext = GetContextByXAcc( pUNOInterface ); 2196 ; 2197 XAccessibleContext* pContext = GetContextByXAcc( pItem ); 2198 if( pParentContext == NULL || pContext == NULL ) 2199 return E_INVALIDARG; 2200 2201 Reference< XAccessibleSelection > pRSelection = GetSelection(); 2202 if( !pRSelection.is() ) 2203 return E_FAIL; 2204 long Index = pContext->getAccessibleIndexInParent(); 2205 pRSelection->deselectAccessibleChild( Index ); 2206 2207 return S_OK; 2208 2209 LEAVE_PROTECTED_BLOCK 2210 } 2211 2212 /** 2213 * Select multiple XAccessible items,for implementation of accSelect 2214 * @param pItem, the items should be selected. 2215 * @param size, the size of the items. 2216 * @return S_OK if successful. 2217 */ 2218 HRESULT CMAccessible::SelectMutipleChidren( XAccessible** pItem,int size ) 2219 { 2220 2221 ENTER_PROTECTED_BLOCK 2222 ISDESTROY() 2223 // #CHECK# 2224 if(pItem == NULL) 2225 { 2226 return E_INVALIDARG; 2227 } 2228 for(int index = 0;index < size;index++) 2229 { 2230 SelectChild( pItem[index] ); 2231 } 2232 return S_OK; 2233 2234 LEAVE_PROTECTED_BLOCK 2235 } 2236 2237 /** 2238 * Deselect multiple XAccessible items,for implementation of accSelect 2239 * @param pItem, the items should be selected. 2240 * @param size, the size of the items. 2241 * @return S_OK if successful. 2242 */ 2243 HRESULT CMAccessible::DeSelectMutipleChildren( XAccessible** pItem,int size ) 2244 { 2245 2246 ENTER_PROTECTED_BLOCK 2247 ISDESTROY() 2248 // #CHECK# 2249 if(pItem == NULL) 2250 { 2251 return E_INVALIDARG; 2252 } 2253 for(int index = 0;index < size;index++) 2254 { 2255 DeSelectChild( pItem[index] ); 2256 } 2257 return S_OK; 2258 2259 LEAVE_PROTECTED_BLOCK 2260 } 2261 2262 /** 2263 * When COM is created, UNO set XAccessible pointer to it 2264 * in order to COM can operate UNO information 2265 * @param pXAcc, the XAccessible object of current object. 2266 * @return S_OK if successful. 2267 */ 2268 STDMETHODIMP CMAccessible::SetXAccessible(long pXAcc) 2269 { 2270 pUNOInterface = (XAccessible*)pXAcc; 2271 pRef = pUNOInterface; 2272 m_pEnumVar->PutSelection(/*XAccessibleSelection*/(long)pUNOInterface); 2273 2274 pRContext = pUNOInterface->getAccessibleContext(); 2275 pRContextInterface = (XAccessibleContext*)pRContext.is(); 2276 2277 return S_OK; 2278 } 2279 2280 /** 2281 * accSelect method has many optional flags, needs to process comprehensively 2282 * Mozilla and Microsoft do not implement SELFLAG_EXTENDSELECTION flag. 2283 * The implementation of this flag is a little trouble-shooting,so we also 2284 * do not implement it now 2285 * @param flagsSelect, the selection flag of the select action. 2286 * @param varChild, the child object pointer of current action. 2287 * @return S_OK if successful. 2288 */ 2289 STDMETHODIMP CMAccessible::accSelect(long flagsSelect, VARIANT varChild) 2290 { 2291 2292 CHECK_ENABLE_INF 2293 ENTER_PROTECTED_BLOCK 2294 ISDESTROY() 2295 if( (flagsSelect&SELFLAG_ADDSELECTION) && 2296 (SELFLAG_REMOVESELECTION&flagsSelect) ) 2297 return E_INVALIDARG; 2298 2299 if ( (flagsSelect&SELFLAG_TAKESELECTION) && 2300 ( 2301 (flagsSelect&SELFLAG_ADDSELECTION) || 2302 (flagsSelect&SELFLAG_REMOVESELECTION) || 2303 (flagsSelect&SELFLAG_EXTENDSELECTION ) 2304 ) 2305 ) 2306 return E_INVALIDARG; 2307 2308 if ( varChild.vt != VT_I4 ) 2309 return E_INVALIDARG; 2310 2311 IMAccessible* pSelectAcc; 2312 if( varChild.lVal == CHILDID_SELF ) 2313 { 2314 pSelectAcc = this; 2315 pSelectAcc->AddRef(); 2316 } 2317 else 2318 { 2319 pSelectAcc = GetChildInterface(varChild.lVal); 2320 } 2321 2322 if( pSelectAcc == NULL ) 2323 return E_INVALIDARG; 2324 2325 if( flagsSelect&SELFLAG_TAKEFOCUS ) 2326 { 2327 long pTempUNO = 0; 2328 pSelectAcc->GetUNOInterface( &pTempUNO); 2329 2330 if( pTempUNO == NULL ) 2331 return NULL; 2332 2333 Reference< XAccessibleContext > pRContext = ( (XAccessible*)pTempUNO)->getAccessibleContext(); 2334 Reference< XAccessibleComponent > pRComponent(pRContext,UNO_QUERY); 2335 Reference< XAccessible > pRParentXAcc = pRContext->getAccessibleParent(); 2336 Reference< XAccessibleContext > pRParentContext = pRParentXAcc->getAccessibleContext(); 2337 Reference< XAccessibleComponent > pRParentComponent(pRParentContext,UNO_QUERY); 2338 Reference< XAccessibleSelection > pRParentSelection(pRParentContext,UNO_QUERY); 2339 2340 2341 pRComponent->grabFocus(); 2342 2343 if( flagsSelect & SELFLAG_TAKESELECTION ) 2344 { 2345 pRParentSelection->clearAccessibleSelection(); 2346 pRParentSelection->selectAccessibleChild( pRContext->getAccessibleIndexInParent() ); 2347 } 2348 2349 if( flagsSelect & SELFLAG_ADDSELECTION ) 2350 { 2351 pRParentSelection->selectAccessibleChild( pRContext->getAccessibleIndexInParent() ); 2352 } 2353 2354 if( flagsSelect & SELFLAG_REMOVESELECTION ) 2355 { 2356 pRParentSelection->deselectAccessibleChild( pRContext->getAccessibleIndexInParent() ); 2357 } 2358 2359 if( flagsSelect & SELFLAG_EXTENDSELECTION ) 2360 { 2361 long indexInParrent = pRContext->getAccessibleIndexInParent(); 2362 2363 if( pRParentSelection->isAccessibleChildSelected( indexInParrent + 1 ) || 2364 pRParentSelection->isAccessibleChildSelected( indexInParrent - 1 ) ) 2365 { 2366 pRParentSelection->selectAccessibleChild( indexInParrent ); 2367 } 2368 } 2369 2370 } 2371 2372 pSelectAcc->Release(); 2373 return S_OK; 2374 2375 LEAVE_PROTECTED_BLOCK 2376 } 2377 2378 /** 2379 * Return XAccessible interface pointer when needed 2380 * @param pXAcc, [in, out] the Uno interface of the current object. 2381 * @return S_OK if successful. 2382 */ 2383 STDMETHODIMP CMAccessible::GetUNOInterface(long* pXAcc) 2384 { 2385 // #CHECK# 2386 if(pXAcc == NULL) 2387 return E_INVALIDARG; 2388 2389 *pXAcc = (long)pUNOInterface; 2390 return S_OK; 2391 } 2392 2393 /** 2394 * Helper method for Implementation of get_accDefaultAction 2395 * @param pAction, the default action point of the current object. 2396 * @return S_OK if successful. 2397 */ 2398 STDMETHODIMP CMAccessible::SetDefaultAction(long pAction) 2399 { 2400 m_pXAction = (XAccessibleAction*)pAction; 2401 return S_OK; 2402 } 2403 2404 /** 2405 * This method is called when AT open some UI elements initially 2406 * the UI element takes the default action defined here 2407 * @param varChild, the child id of the defaultaction. 2408 * @param pszDefaultAction,[in/out] the description of the current action. 2409 * @return S_OK if successful. 2410 */ 2411 HRESULT STDMETHODCALLTYPE CMAccessible::get_accDefaultAction(VARIANT varChild, BSTR *pszDefaultAction) 2412 { 2413 2414 ENTER_PROTECTED_BLOCK 2415 ISDESTROY() 2416 // #CHECK# 2417 if(pszDefaultAction == NULL) 2418 { 2419 return E_INVALIDARG; 2420 } 2421 if(varChild.vt==VT_I4) 2422 { 2423 if(varChild.lVal==CHILDID_SELF) 2424 { 2425 if( m_pXAction == NULL ) 2426 return DISP_E_MEMBERNOTFOUND; 2427 SAFE_SYSFREESTRING(*pszDefaultAction); 2428 *pszDefaultAction = SysAllocString(m_pszActionDescription); 2429 return S_OK; 2430 } 2431 2432 long lVal = varChild.lVal; 2433 varChild.lVal = CHILDID_SELF; 2434 IMAccessible *pChild = this->GetChildInterface(lVal); 2435 if(!pChild) 2436 return E_FAIL; 2437 return pChild->get_accDefaultAction(varChild,pszDefaultAction); 2438 } 2439 return S_FALSE; 2440 2441 LEAVE_PROTECTED_BLOCK 2442 } 2443 2444 /** 2445 * AT call this method to operate application 2446 * @param varChild, the child id of the action object. 2447 * @return S_OK if successful. 2448 */ 2449 HRESULT STDMETHODCALLTYPE CMAccessible::accDoDefaultAction(VARIANT varChild) 2450 { 2451 2452 ENTER_PROTECTED_BLOCK 2453 ISDESTROY() 2454 if( varChild.vt != VT_I4 ) 2455 return E_INVALIDARG; 2456 if( m_pXAction == NULL ) 2457 return E_FAIL; 2458 if( m_pXAction->getAccessibleActionCount() == 0 ) 2459 return E_FAIL; 2460 2461 if(varChild.lVal==CHILDID_SELF) 2462 { 2463 if(m_pXAction->getAccessibleActionCount() > 0) 2464 m_pXAction->doAccessibleAction(0); 2465 return S_OK; 2466 } 2467 2468 long lVal = varChild.lVal; 2469 varChild.lVal = CHILDID_SELF; 2470 IMAccessible *pChild = this->GetChildInterface(lVal); 2471 if(!pChild) 2472 return E_FAIL; 2473 return pChild->accDoDefaultAction( varChild ); 2474 2475 LEAVE_PROTECTED_BLOCK 2476 } 2477 2478 /** 2479 * UNO set description information for action to COM. 2480 * @param szAction, the action description of the current object. 2481 * @return S_OK if successful. 2482 */ 2483 STDMETHODIMP CMAccessible::Put_ActionDescription( const OLECHAR* szAction) 2484 { 2485 2486 ENTER_PROTECTED_BLOCK 2487 ISDESTROY() 2488 // #CHECK# 2489 if(szAction == NULL) 2490 { 2491 return E_INVALIDARG; 2492 } 2493 SAFE_SYSFREESTRING(m_pszActionDescription ); 2494 m_pszActionDescription = SysAllocString( szAction ); 2495 return S_OK; 2496 2497 LEAVE_PROTECTED_BLOCK 2498 } 2499 2500 BOOL CMAccessible::GetXInterfaceFromXAccessible(XAccessible* pXAcc, XInterface** ppXI, int index) 2501 { 2502 Reference< XAccessibleContext > pRContext; 2503 2504 switch(index) 2505 { 2506 case XI_COMPONENT: 2507 QUERYXINTERFACE(AccessibleComponent) 2508 break; 2509 case XI_TEXT: 2510 QUERYXINTERFACE(AccessibleText) 2511 break; 2512 case XI_EDITABLETEXT: 2513 QUERYXINTERFACE(AccessibleEditableText) 2514 break; 2515 case XI_TABLE: 2516 QUERYXINTERFACE(AccessibleTable) 2517 break; 2518 case XI_SELECTION: 2519 QUERYXINTERFACE(AccessibleSelection) 2520 break; 2521 case XI_EXTENDEDCOMP: 2522 QUERYXINTERFACE(AccessibleExtendedComponent) 2523 break; 2524 case XI_KEYBINDING: 2525 QUERYXINTERFACE(AccessibleKeyBinding) 2526 break; 2527 case XI_ACTION: 2528 QUERYXINTERFACE(AccessibleAction) 2529 break; 2530 case XI_VALUE: 2531 QUERYXINTERFACE(AccessibleValue) 2532 break; 2533 case XI_HYPERTEXT: 2534 QUERYXINTERFACE(AccessibleHypertext) 2535 break; 2536 case XI_HYPERLINK: 2537 QUERYXINTERFACE(AccessibleHyperlink) 2538 break; 2539 case XI_IMAGE: 2540 QUERYXINTERFACE(AccessibleImage) 2541 break; 2542 default: 2543 break; 2544 } 2545 2546 return FALSE; 2547 } 2548 2549 HRESULT WINAPI CMAccessible::SmartQI(void* pv, REFIID iid, void** ppvObject) 2550 { 2551 ENTER_PROTECTED_BLOCK 2552 ISDESTROY() 2553 if( ImplIsEqualGUID(iid,IID_IAccIdentity) || 2554 ImplIsEqualGUID(iid,IID_IStdMarshalInfo) || 2555 ImplIsEqualGUID(iid,IID_IMarshal) || 2556 ImplIsEqualGUID(iid,IID_IExternalConnection)|| 2557 ImplIsEqualGUID(iid,IID_IOleWindow)) 2558 return E_FAIL; 2559 2560 2561 _UNO_AGGMAP_ENTRY* pMap = _GetAggEntries(); 2562 while(pMap && pMap->piid) 2563 { 2564 if(ImplIsEqualGUID(iid, *pMap->piid)) 2565 { 2566 XInterface* pXI = NULL; 2567 BOOL bFound = GetXInterfaceFromXAccessible(pUNOInterface,&pXI,pMap->XIFIndex); 2568 if(!bFound) 2569 { 2570 return E_FAIL; 2571 } 2572 2573 XGUIDToComObjHash::iterator pIndTemp = m_containedObjects.find( iid ); 2574 if ( pIndTemp != m_containedObjects.end() ) 2575 { 2576 return pIndTemp->second.p->QueryInterface( iid, ppvObject ); 2577 } 2578 else 2579 { 2580 HRESULT hr = pMap->pfnCreateInstance(pv, iid, ppvObject); 2581 if(hr == S_OK) 2582 { 2583 m_containedObjects.insert(XGUIDToComObjHash::value_type(*pMap->piid,(IUnknown*)*ppvObject)); 2584 IUNOXWrapper* wrapper = NULL; 2585 ((IUnknown*)*ppvObject)->QueryInterface(IID_IUNOXWrapper, (void**)&wrapper); 2586 if(wrapper) 2587 { 2588 wrapper->put_XInterface((long)pUNOInterface); 2589 wrapper->Release(); 2590 } 2591 return S_OK; 2592 } 2593 } 2594 return E_FAIL; 2595 } 2596 pMap++; 2597 } 2598 return E_FAIL; 2599 2600 LEAVE_PROTECTED_BLOCK 2601 } 2602 2603 BOOL CMAccessible::get_IAccessibleFromXAccessible(long pXAcc, IAccessible **ppIA) 2604 { 2605 2606 ENTER_PROTECTED_BLOCK 2607 2608 // #CHECK# 2609 if(ppIA == NULL) 2610 { 2611 return E_INVALIDARG; 2612 } 2613 BOOL isGet = FALSE; 2614 if(g_pAgent) 2615 isGet = g_pAgent->GetIAccessibleFromXAccessible((XAccessible*)pXAcc,ppIA); 2616 2617 if(isGet) 2618 return TRUE; 2619 else 2620 return FALSE; 2621 2622 LEAVE_PROTECTED_BLOCK 2623 } 2624 2625 void CMAccessible::get_OLECHARFromAny(Any& pAny, OLECHAR* pChar) 2626 { 2627 // #CHECK# 2628 if(pChar == NULL) 2629 return; 2630 2631 switch(pAny.getValueTypeClass()) 2632 { 2633 case TypeClass_CHAR: 2634 { 2635 sal_Int8 val; 2636 pAny >>= val; 2637 swprintf( pChar, L"%d", val); 2638 break; 2639 } 2640 case TypeClass_BOOLEAN: 2641 { 2642 sal_Bool val; 2643 pAny >>= val; 2644 swprintf( pChar, L"%d", val); 2645 break; 2646 } 2647 case TypeClass_BYTE: 2648 { 2649 sal_Int8 val; 2650 pAny >>= val; 2651 swprintf( pChar, L"%d", val); 2652 break; 2653 } 2654 case TypeClass_SHORT: 2655 { 2656 SHORT val; 2657 pAny >>= val; 2658 swprintf( pChar, L"%d", val); 2659 break; 2660 } 2661 case TypeClass_UNSIGNED_SHORT: 2662 { 2663 USHORT val; 2664 pAny >>= val; 2665 swprintf( pChar, L"%d", val); 2666 break; 2667 } 2668 case TypeClass_LONG: 2669 { 2670 LONG val; 2671 pAny >>= val; 2672 swprintf( pChar, L"%ld", val); 2673 break; 2674 } 2675 case TypeClass_UNSIGNED_LONG: 2676 { 2677 ULONG val; 2678 pAny >>= val; 2679 swprintf( pChar, L"%ld", val); 2680 break; 2681 } 2682 case TypeClass_FLOAT: 2683 { 2684 FLOAT val; 2685 pAny >>= val; 2686 swprintf( pChar, L"%.3f", val); 2687 break; 2688 } 2689 case TypeClass_DOUBLE: 2690 { 2691 DOUBLE val; 2692 pAny >>= val; 2693 swprintf( pChar, L"%.6lf", val); 2694 break; 2695 } 2696 case TypeClass_STRING: 2697 { 2698 ::rtl::OUString val; 2699 pAny >>= val; 2700 wcscpy(pChar, val.getStr()); 2701 break; 2702 } 2703 case TypeClass_SEQUENCE: 2704 { 2705 if(pAny.getValueType() == getCppuType( (Sequence< ::rtl::OUString > *)0 ) ) 2706 { 2707 Sequence < ::rtl::OUString > val; 2708 pAny >>= val; 2709 2710 ::rtl::OUString pString; 2711 2712 int count = val.getLength(); 2713 2714 for( int iIndex = 0;iIndex < count;iIndex++ ) 2715 { 2716 pString += val[iIndex]; 2717 } 2718 wcscpy(pChar, pString.getStr()); 2719 } 2720 else if (pAny.getValueType() == getCppuType( (Sequence< ::com::sun::star::style::TabStop >* )0 ) ) 2721 { 2722 Sequence < ::com::sun::star::style::TabStop > val; 2723 pAny >>= val; 2724 int count = val.getLength(); 2725 2726 for( int iIndex = 0;iIndex < count;iIndex++ ) 2727 { 2728 OLECHAR pAttrs[512] = {NULL}; 2729 2730 OLECHAR pAttrsPosition[512] = {NULL}; 2731 OLECHAR pAttrsDescimalChar[512] = {NULL}; 2732 OLECHAR pAttrsFillChar[512] = {NULL}; 2733 2734 ::com::sun::star::style::TabStop sigleVal = val[iIndex]; 2735 2736 swprintf( pAttrsPosition, L"Position=%ld,TabAlign=%ld", 2737 sigleVal.Position, sigleVal.Alignment); 2738 2739 if(sigleVal.DecimalChar==';' || sigleVal.DecimalChar == ':' || sigleVal.DecimalChar == ',' || 2740 sigleVal.DecimalChar == '=' || sigleVal.DecimalChar == '\\') 2741 swprintf( pAttrsDescimalChar, L"DecimalChar=\\%c",sigleVal.DecimalChar); 2742 else 2743 swprintf( pAttrsDescimalChar, L"DecimalChar=%c",sigleVal.DecimalChar); 2744 2745 if(sigleVal.FillChar==';' || sigleVal.FillChar == ':' || sigleVal.FillChar == ',' || 2746 sigleVal.FillChar == '=' || sigleVal.FillChar == '\\') 2747 swprintf( pAttrsFillChar, L"FillChar=\\%c",sigleVal.FillChar); 2748 else 2749 swprintf( pAttrsFillChar, L"FillChar=%c",sigleVal.FillChar); 2750 2751 swprintf( pAttrs, L"%s,%s,%s,",pAttrsPosition,pAttrsDescimalChar,pAttrsFillChar); 2752 2753 wcscat(pChar,pAttrs); 2754 } 2755 } 2756 break; 2757 } 2758 case TypeClass_ENUM: 2759 { 2760 if (pAny.getValueType() == getCppuType( (::com::sun::star::awt::FontSlant* )0 ) ) 2761 { 2762 com::sun::star::awt::FontSlant val; 2763 pAny >>= val; 2764 swprintf( pChar, L"%d", val); 2765 } 2766 } 2767 case TypeClass_STRUCT: 2768 { 2769 if (pAny.getValueType() == getCppuType( (::com::sun::star::style::LineSpacing* )0 ) ) 2770 { 2771 com::sun::star::style::LineSpacing val; 2772 pAny >>= val; 2773 swprintf( pChar, L"Mode=%ld,Height=%ld,", val.Mode, val.Height); 2774 } 2775 else if (pAny.getValueType() == getCppuType( (com::sun::star::accessibility::TextSegment *)0 ) ) 2776 { 2777 com::sun::star::accessibility::TextSegment val; 2778 pAny >>= val; 2779 ::rtl::OUString realVal(val.SegmentText); 2780 wcscpy(pChar, realVal.getStr()); 2781 } 2782 break; 2783 } 2784 case TypeClass_VOID: 2785 case TypeClass_HYPER: 2786 case TypeClass_UNSIGNED_HYPER: 2787 case TypeClass_TYPE: 2788 case TypeClass_ANY: 2789 case TypeClass_TYPEDEF: 2790 case TypeClass_UNION: 2791 case TypeClass_EXCEPTION: 2792 case TypeClass_ARRAY: 2793 case TypeClass_INTERFACE: 2794 case TypeClass_SERVICE: 2795 case TypeClass_MODULE: 2796 case TypeClass_INTERFACE_METHOD: 2797 case TypeClass_INTERFACE_ATTRIBUTE: 2798 case TypeClass_UNKNOWN: 2799 case TypeClass_PROPERTY: 2800 case TypeClass_CONSTANT: 2801 case TypeClass_CONSTANTS: 2802 case TypeClass_SINGLETON: 2803 case TypeClass_MAKE_FIXED_SIZE: 2804 break; 2805 default: 2806 break; 2807 } 2808 } 2809 2810 void CMAccessible::get_OLECHAR4Numbering(const Any& pAny, short numberingLevel,const OUString& numberingPrefix,OLECHAR* pChar) 2811 { 2812 if(pChar == NULL) 2813 return; 2814 Reference< ::com::sun::star::container::XIndexReplace > pXIndex; 2815 if((pAny>>=pXIndex) && (numberingLevel !=-1))//numbering level is -1,means invalid value 2816 { 2817 Any aAny = pXIndex->getByIndex(numberingLevel); 2818 Sequence< ::com::sun::star::beans::PropertyValue > aProps; 2819 aAny >>= aProps; 2820 const ::com::sun::star::beans::PropertyValue* pPropArray = aProps.getConstArray(); 2821 sal_Int32 nCount = aProps.getLength(); 2822 swprintf(pChar,L"Numbering:NumberingLevel=%d,",numberingLevel); 2823 for( sal_Int32 i=0; i<nCount; i++ ) 2824 { 2825 ::com::sun::star::beans::PropertyValue rProp = pPropArray[i]; 2826 if( (rProp.Name.compareTo(OUString::createFromAscii("BulletChar"))==0)|| 2827 (rProp.Name.compareTo(OUString::createFromAscii("GraphicURL"))==0)|| 2828 (rProp.Name.compareTo(OUString::createFromAscii("NumberingType"))==0)) 2829 { 2830 OLECHAR propStr[512] = {NULL}; 2831 swprintf(propStr,L"%s=",rProp.Name.getStr()); 2832 OLECHAR pTemp[256] = {NULL}; 2833 CMAccessible::get_OLECHARFromAny(rProp.Value,pTemp); 2834 if(rProp.Name.compareTo(OUString::createFromAscii("GraphicURL"))==0) 2835 { 2836 OLECHAR* pOccur = wcschr(pTemp,':'); 2837 if(pOccur) 2838 *pOccur = '.'; 2839 } 2840 wcscat(propStr,pTemp); 2841 wcscat(pChar,propStr); 2842 wcscat(pChar,L","); 2843 2844 if(rProp.Name.compareTo(OUString::createFromAscii("NumberingType"))==0) 2845 { 2846 if(numberingPrefix.getLength()!=0) 2847 { 2848 swprintf(pTemp,L"NumberingPrefix=%s,",numberingPrefix.getStr()); 2849 wcscat(pChar,pTemp); 2850 } 2851 } 2852 } 2853 } 2854 } 2855 2856 //Because now have three types numbering level: 2857 //1.real numbering list,numbering level>=0 and numbering Rule !=NULL; 2858 //2.common paragraph, numbering level >=0, and numbering Rule == NULL; 2859 //3.TOC paragraph, numbering level >0, and numbering Rule ==NULL; 2860 // IAText:numberinglevel base on 0, but TOC's level base on 1, 2861 // so NumberingLevel value will be decreased 1 in bridge code. 2862 else if(numberingLevel >0) 2863 { 2864 swprintf(pChar,L"Numbering:NumberingLevel=%d,NumberingType=4,NumberingPrefix=,",numberingLevel-1); 2865 } 2866 else 2867 { 2868 swprintf(pChar,L"Numbering:"); 2869 } 2870 } 2871 2872 void CMAccessible::ConvertAnyToVariant(const ::com::sun::star::uno::Any &rAnyVal, VARIANT *pvData) 2873 { 2874 if(rAnyVal.hasValue()) 2875 { 2876 // Clear VARIANT variable. 2877 VariantClear(pvData); 2878 2879 // Set value according to value type. 2880 switch(rAnyVal.getValueTypeClass()) 2881 { 2882 case TypeClass_CHAR: 2883 pvData->vt = VT_UI1; 2884 memcpy(&pvData->bVal, rAnyVal.getValue(), sizeof(sal_Char)); 2885 break; 2886 2887 case TypeClass_BOOLEAN: 2888 pvData->vt = VT_BOOL; 2889 memcpy(&pvData->boolVal, rAnyVal.getValue(), sizeof(sal_Bool)); 2890 break; 2891 2892 case TypeClass_BYTE: 2893 pvData->vt = VT_UI1; 2894 memcpy(&pvData->bVal, rAnyVal.getValue(), sizeof(sal_Int8)); 2895 break; 2896 2897 case TypeClass_SHORT: 2898 pvData->vt = VT_I2; 2899 memcpy(&pvData->iVal, rAnyVal.getValue(), sizeof(sal_Int16)); 2900 break; 2901 2902 case TypeClass_UNSIGNED_SHORT: 2903 pvData->vt = VT_I2; 2904 memcpy(&pvData->iVal, rAnyVal.getValue(), sizeof(sal_uInt16)); 2905 break; 2906 2907 case TypeClass_LONG: 2908 pvData->vt = VT_I4; 2909 memcpy(&pvData->lVal, rAnyVal.getValue(), sizeof(sal_Int32)); 2910 break; 2911 2912 case TypeClass_UNSIGNED_LONG: 2913 pvData->vt = VT_I4; 2914 memcpy(&pvData->lVal, rAnyVal.getValue(), sizeof(sal_uInt32)); 2915 break; 2916 2917 case TypeClass_FLOAT: 2918 pvData->vt = VT_R4; 2919 memcpy(&pvData->fltVal, rAnyVal.getValue(), sizeof(float)); 2920 break; 2921 2922 case TypeClass_DOUBLE: 2923 pvData->vt = VT_R8; 2924 memcpy(&pvData->dblVal, rAnyVal.getValue(), sizeof(double)); 2925 break; 2926 2927 case TypeClass_STRING: 2928 { 2929 pvData->vt = VT_BSTR; 2930 ::rtl::OUString val; 2931 rAnyVal >>= val; 2932 pvData->bstrVal = SysAllocString((OLECHAR *)val.getStr()); 2933 break; 2934 } 2935 2936 case TypeClass_VOID: 2937 case TypeClass_HYPER: 2938 case TypeClass_UNSIGNED_HYPER: 2939 case TypeClass_TYPE: 2940 case TypeClass_ANY: 2941 case TypeClass_ENUM: 2942 case TypeClass_TYPEDEF: 2943 case TypeClass_STRUCT: 2944 case TypeClass_UNION: 2945 case TypeClass_EXCEPTION: 2946 case TypeClass_SEQUENCE: 2947 case TypeClass_ARRAY: 2948 case TypeClass_INTERFACE: 2949 { 2950 Reference< XAccessible > pXAcc; 2951 if(rAnyVal >>= pXAcc) 2952 { 2953 if(pXAcc.is()) 2954 { 2955 IAccessible* pIAcc = NULL; 2956 get_IAccessibleFromXAccessible((long)pXAcc.get(), &pIAcc); 2957 if(pIAcc == NULL) 2958 { 2959 Reference< XAccessibleContext > pXAccContext = pXAcc->getAccessibleContext(); 2960 g_pAgent->InsertAccObj(pXAcc.get(),pXAccContext->getAccessibleParent().get()); 2961 get_IAccessibleFromXAccessible((long)pXAcc.get(), &pIAcc); 2962 } 2963 if(pIAcc) 2964 { 2965 pIAcc->AddRef(); 2966 2967 pvData->vt = VT_UNKNOWN; 2968 pvData->pdispVal = (IAccessible2*)pIAcc; 2969 break; 2970 } 2971 } 2972 } 2973 } 2974 case TypeClass_SERVICE: 2975 case TypeClass_MODULE: 2976 case TypeClass_INTERFACE_METHOD: 2977 case TypeClass_INTERFACE_ATTRIBUTE: 2978 case TypeClass_UNKNOWN: 2979 case TypeClass_PROPERTY: 2980 case TypeClass_CONSTANT: 2981 case TypeClass_CONSTANTS: 2982 case TypeClass_SINGLETON: 2983 case TypeClass_MAKE_FIXED_SIZE: 2984 // Output the type string, if there is other uno value type. 2985 pvData->vt = VT_BSTR; 2986 pvData->bstrVal = SysAllocString(rAnyVal.getValueTypeName().getStr()); 2987 break; 2988 2989 default: 2990 break; 2991 } 2992 } 2993 else 2994 { 2995 VariantClear(pvData); 2996 } 2997 } 2998 2999 STDMETHODIMP CMAccessible::Get_XAccChildID(long* childID) 3000 { 3001 // #CHECK# 3002 if(childID == NULL) 3003 { 3004 return E_FAIL; 3005 } 3006 *childID = m_dChildID; 3007 return S_OK; 3008 } 3009 STDMETHODIMP CMAccessible:: get_states(AccessibleStates __RPC_FAR *states ) 3010 { 3011 3012 CHECK_ENABLE_INF 3013 ENTER_PROTECTED_BLOCK 3014 ISDESTROY() 3015 // #CHECK XInterface# 3016 if( !pRContext.is() ) 3017 return E_FAIL; 3018 3019 Reference<XAccessibleStateSet> pRStateSet = pRContext.get()->getAccessibleStateSet(); 3020 if(!pRStateSet.is()) 3021 { 3022 return S_OK; 3023 } 3024 Sequence<short> pStates = pRStateSet->getStates(); 3025 3026 3027 long count = pStates.getLength() ; 3028 *states = 0x0; 3029 for( int i = 0; i < count; i++ ) 3030 { 3031 for( int j = 0; j < sizeof(UNO_STATES) / sizeof(UNO_STATES[0]); j++ ) 3032 { 3033 if( pStates[i] == UNO_STATES[j] ) 3034 { 3035 *states |= IA2_STATES[j]; 3036 break; 3037 } 3038 } 3039 } 3040 return S_OK; 3041 3042 3043 LEAVE_PROTECTED_BLOCK 3044 } 3045 3046 // return the UNO roles 3047 STDMETHODIMP CMAccessible:: get_extendedRole( BSTR __RPC_FAR * ) 3048 { 3049 3050 CHECK_ENABLE_INF 3051 ENTER_PROTECTED_BLOCK 3052 ISDESTROY() 3053 3054 return E_NOTIMPL; 3055 3056 LEAVE_PROTECTED_BLOCK 3057 } 3058 3059 STDMETHODIMP CMAccessible:: get_localizedExtendedRole( BSTR __RPC_FAR * ) 3060 { 3061 3062 ENTER_PROTECTED_BLOCK 3063 ISDESTROY() 3064 return E_NOTIMPL; 3065 3066 LEAVE_PROTECTED_BLOCK 3067 } 3068 STDMETHODIMP CMAccessible:: get_nExtendedStates( long __RPC_FAR * ) 3069 { 3070 3071 CHECK_ENABLE_INF 3072 ENTER_PROTECTED_BLOCK 3073 ISDESTROY() 3074 3075 return E_NOTIMPL; 3076 3077 LEAVE_PROTECTED_BLOCK 3078 } 3079 3080 3081 STDMETHODIMP CMAccessible:: get_localizedExtendedStates( long, BSTR __RPC_FAR *__RPC_FAR *, long __RPC_FAR *) 3082 { 3083 3084 ENTER_PROTECTED_BLOCK 3085 ISDESTROY() 3086 return E_NOTIMPL; 3087 3088 LEAVE_PROTECTED_BLOCK 3089 } 3090 3091 3092 STDMETHODIMP CMAccessible:: get_indexInParent( long __RPC_FAR *accParentIndex) 3093 { 3094 3095 CHECK_ENABLE_INF 3096 ENTER_PROTECTED_BLOCK 3097 ISDESTROY() 3098 // #CHECK# 3099 if(accParentIndex == NULL) 3100 return E_INVALIDARG; 3101 3102 // #CHECK XInterface# 3103 if( !pRContext.is() ) 3104 return E_FAIL; 3105 3106 *accParentIndex = pRContext.get()->getAccessibleIndexInParent(); 3107 return S_OK; 3108 3109 3110 LEAVE_PROTECTED_BLOCK 3111 } 3112 STDMETHODIMP CMAccessible:: get_locale( IA2Locale __RPC_FAR *locale ) 3113 { 3114 3115 CHECK_ENABLE_INF 3116 ENTER_PROTECTED_BLOCK 3117 ISDESTROY() 3118 if(locale == NULL) 3119 return E_INVALIDARG; 3120 // #CHECK XInterface# 3121 3122 if( !pRContext.is() ) 3123 return E_FAIL; 3124 3125 ::com::sun::star::lang::Locale unoLoc = pRContext.get()->getLocale(); 3126 locale->language = SysAllocString((OLECHAR*)unoLoc.Language.getStr()); 3127 locale->country = SysAllocString((OLECHAR*)unoLoc.Country.getStr()); 3128 locale->variant = SysAllocString((OLECHAR*)unoLoc.Variant.getStr()); 3129 3130 return S_OK; 3131 3132 LEAVE_PROTECTED_BLOCK 3133 } 3134 3135 DWORD GetMSAAStateFromUNO(short xState) 3136 { 3137 DWORD IState = STATE_SYSTEM_UNAVAILABLE; 3138 switch( xState ) 3139 { 3140 case /*AccessibleStateType::*/AccessibleStateType::BUSY: 3141 IState = STATE_SYSTEM_BUSY; 3142 break; 3143 case /*AccessibleStateType::*/AccessibleStateType::CHECKED: 3144 IState = STATE_SYSTEM_CHECKED; 3145 break; 3146 case /*AccessibleStateType::*/AccessibleStateType::DEFUNC: 3147 IState = STATE_SYSTEM_UNAVAILABLE; 3148 break; 3149 case /*AccessibleStateType::*/AccessibleStateType::EXPANDED: 3150 IState = STATE_SYSTEM_EXPANDED; 3151 break; 3152 case /*AccessibleStateType::*/AccessibleStateType::FOCUSABLE: 3153 IState = STATE_SYSTEM_FOCUSABLE; 3154 break; 3155 case /*AccessibleStateType::*/AccessibleStateType::FOCUSED: 3156 IState = STATE_SYSTEM_FOCUSED; 3157 break; 3158 case /*AccessibleStateType::*/AccessibleStateType::INDETERMINATE: 3159 IState = STATE_SYSTEM_MIXED; 3160 break; 3161 case /*AccessibleStateType::*/AccessibleStateType::MULTI_SELECTABLE: 3162 IState = STATE_SYSTEM_MULTISELECTABLE; 3163 break; 3164 case /*AccessibleStateType::*/AccessibleStateType::PRESSED: 3165 IState = STATE_SYSTEM_PRESSED; 3166 break; 3167 case /*AccessibleStateType::*/AccessibleStateType::RESIZABLE: 3168 IState = STATE_SYSTEM_SIZEABLE; 3169 break; 3170 case /*AccessibleStateType::*/AccessibleStateType::SELECTABLE: 3171 IState = STATE_SYSTEM_SELECTABLE; 3172 break; 3173 case /*AccessibleStateType::*/AccessibleStateType::SELECTED: 3174 IState = STATE_SYSTEM_SELECTED; 3175 break; 3176 case /*AccessibleStateType::*/AccessibleStateType::ARMED: 3177 IState = STATE_SYSTEM_FOCUSED; 3178 break; 3179 case /*AccessibleStateType::*/AccessibleStateType::EXPANDABLE: 3180 IState = STATE_SYSTEM_COLLAPSED; 3181 break; 3182 default: 3183 break; 3184 } 3185 return IState; 3186 } 3187 3188 STDMETHODIMP CMAccessible:: get_appName( BSTR __RPC_FAR *name) 3189 { 3190 3191 ENTER_PROTECTED_BLOCK 3192 ISDESTROY() 3193 if(name == NULL) 3194 return E_INVALIDARG; 3195 3196 *name = SysAllocString(OLESTR("Hannover")); 3197 return S_OK; 3198 LEAVE_PROTECTED_BLOCK 3199 } 3200 STDMETHODIMP CMAccessible:: get_appVersion(BSTR __RPC_FAR *version) 3201 { 3202 3203 ENTER_PROTECTED_BLOCK 3204 ISDESTROY() 3205 if(version == NULL) 3206 return E_INVALIDARG; 3207 *version=SysAllocString(OLESTR("3.0")); 3208 return S_OK; 3209 LEAVE_PROTECTED_BLOCK 3210 } 3211 STDMETHODIMP CMAccessible:: get_toolkitName(BSTR __RPC_FAR *name) 3212 { 3213 3214 ENTER_PROTECTED_BLOCK 3215 ISDESTROY() 3216 if(name == NULL) 3217 return E_INVALIDARG; 3218 *name = SysAllocString(OLESTR(" ")); 3219 return S_OK; 3220 LEAVE_PROTECTED_BLOCK 3221 } 3222 STDMETHODIMP CMAccessible:: get_toolkitVersion(BSTR __RPC_FAR *version) 3223 { 3224 3225 ENTER_PROTECTED_BLOCK 3226 ISDESTROY() 3227 if(version == NULL) 3228 return E_INVALIDARG; 3229 *version = SysAllocString(OLESTR(" ")); 3230 return S_OK; 3231 LEAVE_PROTECTED_BLOCK 3232 } 3233 3234 3235 STDMETHODIMP CMAccessible::get_attributes(/*[out]*/ BSTR *pAttr) 3236 { 3237 CHECK_ENABLE_INF 3238 Reference<XAccessibleContext> pRContext = pUNOInterface->getAccessibleContext(); 3239 if( !pRContext.is() ) 3240 { 3241 return E_FAIL; 3242 } 3243 Reference<XAccessibleExtendedAttributes> pRXI(pRContext,UNO_QUERY); 3244 if( !pRXI.is() ) 3245 return E_FAIL; 3246 else 3247 { 3248 com::sun::star::uno::Reference<com::sun::star::accessibility::XAccessibleExtendedAttributes> pRXAttr; 3249 pRXAttr = pRXI.get(); 3250 ::com::sun::star::uno::Any anyVal = pRXAttr->getExtendedAttributes(); 3251 3252 ::rtl::OUString val; 3253 anyVal >>= val; 3254 3255 if(*pAttr) 3256 SAFE_SYSFREESTRING(*pAttr); 3257 *pAttr = SysAllocString((OLECHAR *)val.getStr()); 3258 3259 return S_OK; 3260 } 3261 } 3262 3263