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 "act.hxx" 49 50 using namespace com::sun::star::accessibility::AccessibleStateType; 51 52 // IA2 states mapping, and name 53 // maintenance the consistency, change one array, change the three all 54 long IA2_STATES[] = 55 { 56 IA2_STATE_ACTIVE, // = 0x1; 57 IA2_STATE_ARMED, // = 0x2; 58 IA2_STATE_DEFUNCT, // = 0x4; 59 IA2_STATE_EDITABLE, // = 0x8; 60 IA2_STATE_HORIZONTAL, // = 0x10; 61 IA2_STATE_ICONIFIED, // = 0x20; 62 IA2_STATE_INVALID_ENTRY, // = 0x80; 63 IA2_STATE_MANAGES_DESCENDANTS, // = 0x100; 64 IA2_STATE_MODAL, // = 0x200; 65 IA2_STATE_MULTI_LINE, // = 0x400; 66 IA2_STATE_OPAQUE, // = 0x800; 67 IA2_STATE_REQUIRED, // = 0x2000; 68 IA2_STATE_SELECTABLE_TEXT, // = 0x3000; 69 IA2_STATE_SINGLE_LINE, // = 0x4000; 70 IA2_STATE_STALE, // = 0x8000; 71 IA2_STATE_SUPPORTS_AUTOCOMPLETION, // = 0x10000; 72 IA2_STATE_TRANSIENT, //= 0x20000; 73 IA2_STATE_VERTICAL // = 0x40000; 74 }; 75 /* 76 77 <=== map ===> 78 79 */ 80 short UNO_STATES[] = 81 { 82 ACTIVE, // = (sal_Int16)1; 83 ARMED, // = (sal_Int16)2; 84 DEFUNC, // = (sal_Int16)5; 85 EDITABLE, // = (sal_Int16)6; 86 HORIZONTAL, // = (sal_Int16)12; 87 ICONIFIED, // = (sal_Int16)13; 88 -1, //IA2_STATE_INVALID_ENTRY 89 MANAGES_DESCENDANTS, // = (sal_Int16)15; 90 MODAL, // = (sal_Int16)16; 91 MULTI_LINE, // = (sal_Int16)17; 92 OPAQUE, // = (sal_Int16)19; 93 -1, //IA2_STATE_REQUIRED 94 -1, //IA2_STATE_SELECTABLE_TEXT 95 SINGLE_LINE, // = (sal_Int16)26; 96 STALE, // = (sal_Int16)27; 97 -1, //IA2_STATE_SUPPORTS_AUTOCOMPLETION 98 TRANSIENT, //IA2_STATE_TRANSIENT 99 VERTICAL // = (sal_Int16)29; 100 }; 101 102 // <=== map ===> 103 104 BSTR IA2_STATES_NAME[] = 105 { 106 _T("Active"), 107 _T("Armed"), 108 _T("Defunct"), 109 _T("Editable"), 110 _T("Horizontal"), 111 _T("Iconified"), 112 _T("Invalid Entry"), 113 _T("Manages Decendents"), 114 _T("Modal"), 115 _T("Multi Line"), 116 _T("Opaque"), 117 _T("Required"), 118 _T("Selectable Text"), 119 _T("Single Line"), 120 _T("Stale"), 121 _T("Supports Autocompletion"), 122 _T("Transient"), 123 _T("Vertical") 124 }; 125 126 // IA2 states mapping, and name 127 // maintenance the consistency. change one, change them all 128 129 BSTR UNO_ALL_STATES[] = 130 { 131 _T("INVALID"), // INVALID ( 0 ) 132 _T("ACTIVE"), // ACTIVE ( 1 ) 133 _T("ARMED"), // ARMED ( 2 ) 134 _T("BUSY"), // BUSY ( 3 ) 135 _T("CHECKED"), // CHECKED ( 4 ) 136 _T("DEFUNC"), // DEFUNC ( 5 ) 137 _T("EDITABLE"), // EDITABLE ( 6 ) 138 _T("ENABLED"), // ENABLED ( 7 ) 139 _T("EXPANDABLE"), // EXPANDABLE ( 8 ) 140 _T("EXPANDED"), // EXPANDED ( 9 ) 141 _T("FOCUSABLE"), // FOCUSABLE ( 10 ) 142 _T("FOCUSED"), // FOCUSED ( 11 ) 143 _T("HORIZONTAL"), // HORIZONTAL ( 12 ) 144 _T("ICONIFIED"), // ICONIFIED ( 13 ) 145 _T("INDETERMINATE"), // INDETERMINATE ( 14 ) 146 _T("MANAGES_DESCENDANTS"),// MANAGES_DESCENDANTS ( 15 ) 147 _T("MODAL"), // MODAL ( 16 ) 148 _T("MULTI_LINE"), // MULTI_LINE ( 17 ) 149 _T("MULTI_SELECTABLE"), // MULTI_SELECTABLE ( 18 ) 150 _T("OPAQUE"), // OPAQUE ( 19 ) 151 _T("PRESSED"), // PRESSED ( 20 ) 152 _T("RESIZABLE"), // RESIZABLE ( 21 ) 153 _T("SELECTABLE"), // SELECTABLE ( 22 ) 154 _T("SELECTED"), // SELECTED ( 23 ) 155 _T("SENSITIVE"), // SENSITIVE ( 24 ) 156 _T("SHOWING"), // SHOWING ( 25 ) 157 _T("SINGLE_LINE"), // SINGLE_LINE ( 26 ) 158 _T("STALE"), // STALE ( 27 ) 159 _T("TRANSIENT"), // TRANSIENT ( 28 ) 160 _T("VERTICAL"), // VERTICAL ( 29 ) 161 _T("VISIBLE"), // VISIBLE ( 30 ) 162 _T("MOVEABLE"), // MOVEABLE ( 31 ) 163 _T("OFFSCREEN"), // OFFSCREEN ( 32 ) 164 _T("COLLAPSE"), // COLLAPSE ( 33 ) 165 _T("DEFAULT") // DEFAULT ( 34 ) 166 }; 167 168 169 using namespace com::sun::star::accessibility::AccessibleRole; 170 171 172 173 #define QUERYXINTERFACE(ainterface) \ 174 { \ 175 if(pXAcc == NULL) \ 176 return FALSE; \ 177 pRContext = pXAcc->getAccessibleContext(); \ 178 if( !pRContext.is() ) \ 179 { \ 180 return FALSE; \ 181 } \ 182 Reference<X##ainterface> pRXI(pRContext,UNO_QUERY);\ 183 if( !pRXI.is() ) \ 184 { \ 185 return FALSE; \ 186 } \ 187 *ppXI = (XInterface*)pRXI.get(); \ 188 return TRUE; \ 189 } 190 191 #define ISDESTROY() \ 192 if(m_isDestroy) \ 193 return S_FALSE; 194 195 196 AccObjectManagerAgent* CMAccessible::g_pAgent = NULL; 197 198 CMAccessible::CMAccessible(): 199 m_iRole(0x00), 200 m_dState(0x00), 201 m_dChildID(0x00), 202 m_dFocusChildID(UACC_NO_FOCUS), 203 m_hwnd(NULL), 204 m_pIParent(NULL), 205 m_pszName(NULL), 206 m_pszValue(NULL), 207 m_pszDescription(NULL), 208 m_isDestroy(FALSE), 209 m_pszActionDescription(NULL), 210 m_pXAction(NULL), 211 m_bRequiresSave(FALSE), 212 pUNOInterface(NULL) 213 { 214 m_sLocation.m_dLeft=0; 215 m_sLocation.m_dTop = 0; 216 m_sLocation.m_dWidth=0; 217 m_sLocation.m_dHeight=0; 218 CEnumVariant::Create(&m_pEnumVar); 219 m_containedObjects.clear(); 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 ActivateActContext(); 1721 HRESULT hr = CoCreateInstance( CLSID_AccRelation, NULL, CLSCTX_SERVER , 1722 IID_IAccessibleRelation, 1723 (void **)&pRelation); 1724 DeactivateActContext(); 1725 if(SUCCEEDED(hr)) 1726 { 1727 IUNOXWrapper* wrapper = NULL; 1728 hr = pRelation->QueryInterface(IID_IUNOXWrapper, (void**)&wrapper); 1729 if(SUCCEEDED(hr)) 1730 { 1731 AccessibleRelation accRelation = pRrelationSet->getRelation(relationIndex); 1732 wrapper->put_XSubInterface((long)&accRelation); 1733 wrapper->Release(); 1734 *relation = pRelation; 1735 return S_OK; 1736 } 1737 1738 } 1739 } 1740 1741 return E_FAIL; 1742 1743 LEAVE_PROTECTED_BLOCK 1744 } 1745 1746 STDMETHODIMP CMAccessible::get_relations( long, IAccessibleRelation __RPC_FAR *__RPC_FAR *relation, long __RPC_FAR *nRelations) 1747 { 1748 1749 CHECK_ENABLE_INF 1750 ENTER_PROTECTED_BLOCK 1751 1752 // #CHECK# 1753 if(relation == NULL || nRelations == NULL) 1754 { 1755 return E_INVALIDARG; 1756 } 1757 // #CHECK XInterface# 1758 1759 if( !pRContext.is() ) 1760 return E_FAIL; 1761 1762 Reference<XAccessibleRelationSet> pRrelationSet = pRContext.get()->getAccessibleRelationSet(); 1763 if(!pRrelationSet.is()) 1764 { 1765 *nRelations = 0; 1766 return S_OK; 1767 } 1768 1769 long nCount = pRrelationSet->getRelationCount(); 1770 1771 *relation = (IAccessibleRelation*)::CoTaskMemAlloc(nCount*sizeof(IAccessibleRelation)); 1772 1773 // #CHECK Memory Allocation# 1774 if(*relation == NULL) 1775 { 1776 return E_FAIL; 1777 } 1778 1779 for(int i=0; i<nCount ; i++) 1780 { 1781 IAccessibleRelation* pRelation = NULL; 1782 ActivateActContext(); 1783 HRESULT hr = CoCreateInstance( CLSID_AccRelation, NULL, CLSCTX_SERVER , 1784 IID_IAccessibleRelation, 1785 (void **)&pRelation); 1786 DeactivateActContext(); 1787 if(SUCCEEDED(hr)) 1788 { 1789 IUNOXWrapper* wrapper = NULL; 1790 hr = pRelation->QueryInterface(IID_IUNOXWrapper, (void**)&wrapper); 1791 if(SUCCEEDED(hr)) 1792 { 1793 AccessibleRelation accRelation = pRrelationSet->getRelation(i); 1794 wrapper->put_XSubInterface((long)&accRelation); 1795 wrapper->Release(); 1796 } 1797 (relation)[i] = pRelation; 1798 } 1799 } 1800 1801 *nRelations = nCount; 1802 return S_OK; 1803 1804 LEAVE_PROTECTED_BLOCK 1805 } 1806 1807 STDMETHODIMP CMAccessible::role(long __RPC_FAR *role) 1808 { 1809 ENTER_PROTECTED_BLOCK 1810 1811 (*role) = m_iRole; 1812 1813 return S_OK; 1814 1815 LEAVE_PROTECTED_BLOCK 1816 } 1817 1818 1819 STDMETHODIMP CMAccessible:: get_nActions(long __RPC_FAR *nActions) 1820 { 1821 1822 try 1823 { 1824 ISDESTROY() 1825 // #CHECK# 1826 if(nActions == NULL) 1827 { 1828 return E_INVALIDARG; 1829 } 1830 *nActions = 0L; 1831 IAccessibleAction* pAcc = NULL; 1832 HRESULT hr = QueryInterface(IID_IAccessibleAction, (void**)&pAcc); 1833 if( hr == S_OK ) 1834 { 1835 pAcc->nActions(nActions); 1836 pAcc->Release(); 1837 } 1838 1839 return S_OK; 1840 } 1841 catch(...) 1842 { 1843 *nActions = 0L; 1844 return S_OK; 1845 } 1846 } 1847 1848 1849 STDMETHODIMP CMAccessible:: scrollToPoint(enum IA2CoordinateType, long, long) 1850 { 1851 1852 ENTER_PROTECTED_BLOCK 1853 ISDESTROY() 1854 return E_NOTIMPL; 1855 LEAVE_PROTECTED_BLOCK 1856 1857 } 1858 STDMETHODIMP CMAccessible:: scrollTo(enum IA2ScrollType) 1859 { 1860 1861 ENTER_PROTECTED_BLOCK 1862 ISDESTROY() 1863 1864 return E_NOTIMPL; 1865 1866 LEAVE_PROTECTED_BLOCK 1867 } 1868 1869 static XAccessible* getTheParentOfMember(XAccessible* pXAcc) 1870 { 1871 // #CHECK# 1872 if(pXAcc == NULL) 1873 { 1874 return NULL; 1875 } 1876 Reference<XAccessibleContext> pRContext = pXAcc->getAccessibleContext(); 1877 Reference<XAccessibleRelationSet> pRrelationSet = pRContext->getAccessibleRelationSet(); 1878 long nRelations = pRrelationSet->getRelationCount(); 1879 for(int i=0 ; i<nRelations ; i++) 1880 { 1881 AccessibleRelation accRelation = pRrelationSet->getRelation(i); 1882 if(accRelation.RelationType == 7) 1883 { 1884 Sequence< Reference< XInterface > > xTargets = accRelation.TargetSet; 1885 return (XAccessible*)xTargets[0].get(); 1886 } 1887 } 1888 return NULL; 1889 } 1890 1891 STDMETHODIMP CMAccessible:: get_groupPosition(long __RPC_FAR *groupLevel,long __RPC_FAR *similarItemsInGroup,long __RPC_FAR *positionInGroup) 1892 { 1893 1894 CHECK_ENABLE_INF 1895 ENTER_PROTECTED_BLOCK 1896 ISDESTROY() 1897 // #CHECK# 1898 if(groupLevel == NULL || similarItemsInGroup == NULL || positionInGroup == NULL) 1899 { 1900 return E_INVALIDARG; 1901 } 1902 1903 Reference<XAccessibleContext> pRContext = pUNOInterface->getAccessibleContext(); 1904 if(!pRContext.is()) 1905 return E_FAIL; 1906 long Role = pRContext->getAccessibleRole(); 1907 1908 *groupLevel = 0; 1909 *similarItemsInGroup = 0; 1910 *positionInGroup = 0; 1911 1912 if (Role != AccessibleRole::DOCUMENT) 1913 { 1914 Reference< XAccessibleGroupPosition > xGroupPosition( pRContext, UNO_QUERY ); 1915 if ( xGroupPosition.is() ) 1916 { 1917 Sequence< sal_Int32 > rSeq = xGroupPosition->getGroupPosition( makeAny( pRContext ) ); 1918 sal_Int32* pSeq = rSeq.getArray(); 1919 if ( pSeq ) 1920 { 1921 *groupLevel = pSeq[0]; 1922 *similarItemsInGroup = pSeq[1]; 1923 *positionInGroup = pSeq[2]; 1924 return S_OK; 1925 } 1926 return S_OK; 1927 } 1928 } 1929 1930 Reference< XAccessible> pParentAcc = pRContext->getAccessibleParent(); 1931 if( !pParentAcc.is() ) 1932 { 1933 return S_OK; 1934 } 1935 1936 Reference<XAccessibleContext> pRParentContext = pParentAcc->getAccessibleContext(); 1937 1938 int level = 0; 1939 int index = 0; 1940 int number = 0; 1941 1942 if( Role == RADIO_BUTTON ) 1943 { 1944 Reference<XAccessibleRelationSet> pRrelationSet = pRContext->getAccessibleRelationSet(); 1945 long nRel = pRrelationSet->getRelationCount(); 1946 for(int i=0 ; i<nRel ; i++) 1947 { 1948 AccessibleRelation accRelation = pRrelationSet->getRelation(i); 1949 if(accRelation.RelationType == 7) 1950 { 1951 Sequence< Reference< XInterface > > xTargets = accRelation.TargetSet; 1952 int nCount = xTargets.getLength(); 1953 1954 Reference<XInterface> pRAcc = xTargets[0]; 1955 for(int j=0; j<pRParentContext->getAccessibleChildCount(); j++) 1956 { 1957 if( getTheParentOfMember(pRParentContext->getAccessibleChild(j).get()) 1958 == (XAccessible*)pRAcc.get() && 1959 pRParentContext->getAccessibleChild(j)->getAccessibleContext()->getAccessibleRole() == RADIO_BUTTON) 1960 number++; 1961 if(pRParentContext->getAccessibleChild(j).get() == pUNOInterface) 1962 index = number; 1963 } 1964 } 1965 } 1966 *groupLevel = 1; 1967 *similarItemsInGroup = number; 1968 *positionInGroup = index; 1969 return S_OK; 1970 } 1971 1972 else if ( COMBO_BOX == Role ) 1973 { 1974 *groupLevel = 1; 1975 *similarItemsInGroup = 0; 1976 *positionInGroup = -1; 1977 1978 long nCount = pRContext->getAccessibleChildCount(); 1979 if( 2 != nCount) 1980 { 1981 return S_OK; 1982 } 1983 Reference<XAccessible> xList=pRContext->getAccessibleChild(1); 1984 if (!xList.is()) 1985 { 1986 return S_OK; 1987 } 1988 Reference<XAccessibleContext> xListContext(xList,UNO_QUERY); 1989 if (!xListContext.is()) 1990 { 1991 return S_OK; 1992 } 1993 Reference<XAccessibleSelection> xListSel(xList,UNO_QUERY); 1994 if (!xListSel.is()) 1995 { 1996 return S_OK; 1997 } 1998 *similarItemsInGroup = xListContext->getAccessibleChildCount(); 1999 if (*similarItemsInGroup > 0 ) 2000 { 2001 try 2002 { 2003 Reference<XAccessible> xChild = xListSel->getSelectedAccessibleChild(0); 2004 if (xChild.is()) 2005 { 2006 Reference<XAccessibleContext> xChildContext(xChild,UNO_QUERY); 2007 if (xChildContext.is()) 2008 { 2009 *positionInGroup=xChildContext->getAccessibleIndexInParent() + 1 ; 2010 return S_OK; 2011 } 2012 } 2013 } 2014 catch(...) 2015 {} 2016 } 2017 return S_OK; 2018 } 2019 else if ( PAGE_TAB == Role ) 2020 { 2021 *groupLevel = 1; 2022 *similarItemsInGroup = pRParentContext->getAccessibleChildCount(); 2023 2024 if (*similarItemsInGroup > 0 ) 2025 { 2026 *positionInGroup=pRContext->getAccessibleIndexInParent() + 1 ; 2027 } 2028 else 2029 { 2030 *positionInGroup = -1; 2031 } 2032 return S_OK; 2033 } 2034 2035 2036 BOOL isFound = FALSE; 2037 while( pParentAcc.is() && !isFound) 2038 { 2039 level++; 2040 pRParentContext = pParentAcc->getAccessibleContext(); 2041 Role = pRParentContext->getAccessibleRole(); 2042 if( (Role == TREE) || (Role == LIST) ) 2043 isFound = TRUE; 2044 pParentAcc = pRParentContext->getAccessibleParent(); 2045 } 2046 2047 if( isFound ) 2048 { 2049 Reference< XAccessible> pTempAcc = pRContext->getAccessibleParent(); 2050 pRParentContext = pTempAcc->getAccessibleContext(); 2051 *groupLevel = level; 2052 *similarItemsInGroup = pRParentContext->getAccessibleChildCount(); 2053 *positionInGroup = pRContext->getAccessibleIndexInParent() + 1; 2054 } 2055 else 2056 { 2057 *groupLevel = 0; 2058 *similarItemsInGroup = 0; 2059 *positionInGroup = 0; 2060 } 2061 return S_OK; 2062 2063 LEAVE_PROTECTED_BLOCK 2064 } 2065 2066 STDMETHODIMP CMAccessible:: get_extendedStates( long, BSTR __RPC_FAR *__RPC_FAR *, long __RPC_FAR *) 2067 { 2068 2069 CHECK_ENABLE_INF 2070 ENTER_PROTECTED_BLOCK 2071 ISDESTROY() 2072 2073 return E_NOTIMPL; 2074 2075 LEAVE_PROTECTED_BLOCK 2076 } 2077 2078 2079 STDMETHODIMP CMAccessible:: get_uniqueID(long __RPC_FAR *uniqueID) 2080 { 2081 2082 ENTER_PROTECTED_BLOCK 2083 ISDESTROY() 2084 // #CHECK# 2085 if(uniqueID == NULL) 2086 { 2087 return E_INVALIDARG; 2088 } 2089 *uniqueID = m_dChildID; 2090 return S_OK; 2091 2092 LEAVE_PROTECTED_BLOCK 2093 } 2094 2095 STDMETHODIMP CMAccessible:: get_windowHandle(HWND __RPC_FAR *windowHandle) 2096 { 2097 2098 ENTER_PROTECTED_BLOCK 2099 ISDESTROY() 2100 // #CHECK# 2101 if(windowHandle == NULL) 2102 { 2103 return E_INVALIDARG; 2104 } 2105 2106 HWND nHwnd = m_hwnd; 2107 IAccessible* pParent = m_pIParent; 2108 CMAccessible* pChild = this; 2109 while((nHwnd==0) && pParent) 2110 { 2111 pChild = (CMAccessible*)pParent; 2112 if(pChild) 2113 { 2114 pParent = (IAccessible*)pChild->m_pIParent; 2115 nHwnd = (HWND)pChild->m_hwnd; 2116 } 2117 else 2118 pParent = NULL; 2119 } 2120 2121 *windowHandle = nHwnd; 2122 return S_OK; 2123 2124 LEAVE_PROTECTED_BLOCK 2125 } 2126 2127 /** 2128 * Get XAccessibleContext directly from UNO by the stored XAccessible pointer 2129 * @param pXAcc, UNO XAccessible object point. 2130 * @return XAccessibleContext*, the context of the pXAcc. 2131 */ 2132 XAccessibleContext* CMAccessible::GetContextByXAcc( XAccessible* pXAcc ) 2133 { 2134 Reference< XAccessibleContext > pRContext; 2135 if( pXAcc == NULL) 2136 return NULL; 2137 2138 pRContext = pXAcc->getAccessibleContext(); 2139 if( !pRContext.is() ) 2140 return NULL; 2141 return pRContext.get(); 2142 } 2143 2144 /** 2145 * Return the member variable m_pXAccessibleSelection, instead of 2146 * get XAccessibleSelection according to XAccessibleContext because if so,it will 2147 * depend on the UNO implementation code,so when COM is created, put XAccessibleSelection 2148 * by bridge management system 2149 * @return XAccessibleSelection*, the selection of the current object. 2150 */ 2151 Reference< XAccessibleSelection > CMAccessible::GetSelection() 2152 { 2153 if( pUNOInterface == NULL ) 2154 return NULL; 2155 Reference< XAccessibleContext > pRContext = pUNOInterface->getAccessibleContext(); 2156 if(pRContext.is()) 2157 { 2158 Reference< XAccessibleSelection > pRSelection(pRContext,UNO_QUERY); 2159 return pRSelection; 2160 } 2161 return NULL; 2162 } 2163 2164 /** 2165 * Select one XAccessible item, for accSelect implementation 2166 * @param pItem, the item should be selected. 2167 * @return S_OK if successful. 2168 */ 2169 HRESULT CMAccessible::SelectChild(XAccessible* pItem) 2170 { 2171 2172 ENTER_PROTECTED_BLOCK 2173 ISDESTROY() 2174 XAccessibleContext* pParentContext = GetContextByXAcc( pUNOInterface ); 2175 XAccessibleContext* pContext = GetContextByXAcc( pItem ); 2176 if( pParentContext == NULL || pContext == NULL ) 2177 return E_FAIL; 2178 2179 Reference< XAccessibleSelection > pRSelection = GetSelection(); 2180 if( !pRSelection.is() ) 2181 return E_FAIL; 2182 long Index = pContext->getAccessibleIndexInParent(); 2183 pRSelection->selectAccessibleChild( Index ); 2184 return S_OK; 2185 2186 LEAVE_PROTECTED_BLOCK 2187 } 2188 2189 /** 2190 * Deselect one XAccessible item, for accSelect implimentation 2191 * @param pItem, the item should be deselected. 2192 * @return S_OK if successful. 2193 */ 2194 HRESULT CMAccessible::DeSelectChild(XAccessible* pItem) 2195 { 2196 2197 ENTER_PROTECTED_BLOCK 2198 ISDESTROY() 2199 XAccessibleContext* pParentContext = GetContextByXAcc( pUNOInterface ); 2200 ; 2201 XAccessibleContext* pContext = GetContextByXAcc( pItem ); 2202 if( pParentContext == NULL || pContext == NULL ) 2203 return E_INVALIDARG; 2204 2205 Reference< XAccessibleSelection > pRSelection = GetSelection(); 2206 if( !pRSelection.is() ) 2207 return E_FAIL; 2208 long Index = pContext->getAccessibleIndexInParent(); 2209 pRSelection->deselectAccessibleChild( Index ); 2210 2211 return S_OK; 2212 2213 LEAVE_PROTECTED_BLOCK 2214 } 2215 2216 /** 2217 * Select multiple XAccessible items,for implementation of accSelect 2218 * @param pItem, the items should be selected. 2219 * @param size, the size of the items. 2220 * @return S_OK if successful. 2221 */ 2222 HRESULT CMAccessible::SelectMutipleChidren( XAccessible** pItem,int size ) 2223 { 2224 2225 ENTER_PROTECTED_BLOCK 2226 ISDESTROY() 2227 // #CHECK# 2228 if(pItem == NULL) 2229 { 2230 return E_INVALIDARG; 2231 } 2232 for(int index = 0;index < size;index++) 2233 { 2234 SelectChild( pItem[index] ); 2235 } 2236 return S_OK; 2237 2238 LEAVE_PROTECTED_BLOCK 2239 } 2240 2241 /** 2242 * Deselect multiple XAccessible items,for implementation of accSelect 2243 * @param pItem, the items should be selected. 2244 * @param size, the size of the items. 2245 * @return S_OK if successful. 2246 */ 2247 HRESULT CMAccessible::DeSelectMutipleChildren( XAccessible** pItem,int size ) 2248 { 2249 2250 ENTER_PROTECTED_BLOCK 2251 ISDESTROY() 2252 // #CHECK# 2253 if(pItem == NULL) 2254 { 2255 return E_INVALIDARG; 2256 } 2257 for(int index = 0;index < size;index++) 2258 { 2259 DeSelectChild( pItem[index] ); 2260 } 2261 return S_OK; 2262 2263 LEAVE_PROTECTED_BLOCK 2264 } 2265 2266 /** 2267 * When COM is created, UNO set XAccessible pointer to it 2268 * in order to COM can operate UNO information 2269 * @param pXAcc, the XAccessible object of current object. 2270 * @return S_OK if successful. 2271 */ 2272 STDMETHODIMP CMAccessible::SetXAccessible(long pXAcc) 2273 { 2274 pUNOInterface = (XAccessible*)pXAcc; 2275 pRef = pUNOInterface; 2276 m_pEnumVar->PutSelection(/*XAccessibleSelection*/(long)pUNOInterface); 2277 2278 pRContext = pUNOInterface->getAccessibleContext(); 2279 pRContextInterface = (XAccessibleContext*)pRContext.is(); 2280 2281 return S_OK; 2282 } 2283 2284 /** 2285 * accSelect method has many optional flags, needs to process comprehensively 2286 * Mozilla and Microsoft do not implement SELFLAG_EXTENDSELECTION flag. 2287 * The implementation of this flag is a little trouble-shooting,so we also 2288 * do not implement it now 2289 * @param flagsSelect, the selection flag of the select action. 2290 * @param varChild, the child object pointer of current action. 2291 * @return S_OK if successful. 2292 */ 2293 STDMETHODIMP CMAccessible::accSelect(long flagsSelect, VARIANT varChild) 2294 { 2295 2296 CHECK_ENABLE_INF 2297 ENTER_PROTECTED_BLOCK 2298 ISDESTROY() 2299 if( (flagsSelect&SELFLAG_ADDSELECTION) && 2300 (SELFLAG_REMOVESELECTION&flagsSelect) ) 2301 return E_INVALIDARG; 2302 2303 if ( (flagsSelect&SELFLAG_TAKESELECTION) && 2304 ( 2305 (flagsSelect&SELFLAG_ADDSELECTION) || 2306 (flagsSelect&SELFLAG_REMOVESELECTION) || 2307 (flagsSelect&SELFLAG_EXTENDSELECTION ) 2308 ) 2309 ) 2310 return E_INVALIDARG; 2311 2312 if ( varChild.vt != VT_I4 ) 2313 return E_INVALIDARG; 2314 2315 IMAccessible* pSelectAcc; 2316 if( varChild.lVal == CHILDID_SELF ) 2317 { 2318 pSelectAcc = this; 2319 pSelectAcc->AddRef(); 2320 } 2321 else 2322 { 2323 pSelectAcc = GetChildInterface(varChild.lVal); 2324 } 2325 2326 if( pSelectAcc == NULL ) 2327 return E_INVALIDARG; 2328 2329 if( flagsSelect&SELFLAG_TAKEFOCUS ) 2330 { 2331 long pTempUNO = 0; 2332 pSelectAcc->GetUNOInterface( &pTempUNO); 2333 2334 if( pTempUNO == NULL ) 2335 return NULL; 2336 2337 Reference< XAccessibleContext > pRContext = ( (XAccessible*)pTempUNO)->getAccessibleContext(); 2338 Reference< XAccessibleComponent > pRComponent(pRContext,UNO_QUERY); 2339 Reference< XAccessible > pRParentXAcc = pRContext->getAccessibleParent(); 2340 Reference< XAccessibleContext > pRParentContext = pRParentXAcc->getAccessibleContext(); 2341 Reference< XAccessibleComponent > pRParentComponent(pRParentContext,UNO_QUERY); 2342 Reference< XAccessibleSelection > pRParentSelection(pRParentContext,UNO_QUERY); 2343 2344 2345 pRComponent->grabFocus(); 2346 2347 if( flagsSelect & SELFLAG_TAKESELECTION ) 2348 { 2349 pRParentSelection->clearAccessibleSelection(); 2350 pRParentSelection->selectAccessibleChild( pRContext->getAccessibleIndexInParent() ); 2351 } 2352 2353 if( flagsSelect & SELFLAG_ADDSELECTION ) 2354 { 2355 pRParentSelection->selectAccessibleChild( pRContext->getAccessibleIndexInParent() ); 2356 } 2357 2358 if( flagsSelect & SELFLAG_REMOVESELECTION ) 2359 { 2360 pRParentSelection->deselectAccessibleChild( pRContext->getAccessibleIndexInParent() ); 2361 } 2362 2363 if( flagsSelect & SELFLAG_EXTENDSELECTION ) 2364 { 2365 long indexInParrent = pRContext->getAccessibleIndexInParent(); 2366 2367 if( pRParentSelection->isAccessibleChildSelected( indexInParrent + 1 ) || 2368 pRParentSelection->isAccessibleChildSelected( indexInParrent - 1 ) ) 2369 { 2370 pRParentSelection->selectAccessibleChild( indexInParrent ); 2371 } 2372 } 2373 2374 } 2375 2376 pSelectAcc->Release(); 2377 return S_OK; 2378 2379 LEAVE_PROTECTED_BLOCK 2380 } 2381 2382 /** 2383 * Return XAccessible interface pointer when needed 2384 * @param pXAcc, [in, out] the Uno interface of the current object. 2385 * @return S_OK if successful. 2386 */ 2387 STDMETHODIMP CMAccessible::GetUNOInterface(long* pXAcc) 2388 { 2389 // #CHECK# 2390 if(pXAcc == NULL) 2391 return E_INVALIDARG; 2392 2393 *pXAcc = (long)pUNOInterface; 2394 return S_OK; 2395 } 2396 2397 /** 2398 * Helper method for Implementation of get_accDefaultAction 2399 * @param pAction, the default action point of the current object. 2400 * @return S_OK if successful. 2401 */ 2402 STDMETHODIMP CMAccessible::SetDefaultAction(long pAction) 2403 { 2404 m_pXAction = (XAccessibleAction*)pAction; 2405 return S_OK; 2406 } 2407 2408 /** 2409 * This method is called when AT open some UI elements initially 2410 * the UI element takes the default action defined here 2411 * @param varChild, the child id of the defaultaction. 2412 * @param pszDefaultAction,[in/out] the description of the current action. 2413 * @return S_OK if successful. 2414 */ 2415 HRESULT STDMETHODCALLTYPE CMAccessible::get_accDefaultAction(VARIANT varChild, BSTR *pszDefaultAction) 2416 { 2417 2418 ENTER_PROTECTED_BLOCK 2419 ISDESTROY() 2420 // #CHECK# 2421 if(pszDefaultAction == NULL) 2422 { 2423 return E_INVALIDARG; 2424 } 2425 if(varChild.vt==VT_I4) 2426 { 2427 if(varChild.lVal==CHILDID_SELF) 2428 { 2429 if( m_pXAction == NULL ) 2430 return DISP_E_MEMBERNOTFOUND; 2431 SAFE_SYSFREESTRING(*pszDefaultAction); 2432 *pszDefaultAction = SysAllocString(m_pszActionDescription); 2433 return S_OK; 2434 } 2435 2436 long lVal = varChild.lVal; 2437 varChild.lVal = CHILDID_SELF; 2438 IMAccessible *pChild = this->GetChildInterface(lVal); 2439 if(!pChild) 2440 return E_FAIL; 2441 return pChild->get_accDefaultAction(varChild,pszDefaultAction); 2442 } 2443 return S_FALSE; 2444 2445 LEAVE_PROTECTED_BLOCK 2446 } 2447 2448 /** 2449 * AT call this method to operate application 2450 * @param varChild, the child id of the action object. 2451 * @return S_OK if successful. 2452 */ 2453 HRESULT STDMETHODCALLTYPE CMAccessible::accDoDefaultAction(VARIANT varChild) 2454 { 2455 2456 ENTER_PROTECTED_BLOCK 2457 ISDESTROY() 2458 if( varChild.vt != VT_I4 ) 2459 return E_INVALIDARG; 2460 if( m_pXAction == NULL ) 2461 return E_FAIL; 2462 if( m_pXAction->getAccessibleActionCount() == 0 ) 2463 return E_FAIL; 2464 2465 if(varChild.lVal==CHILDID_SELF) 2466 { 2467 if(m_pXAction->getAccessibleActionCount() > 0) 2468 m_pXAction->doAccessibleAction(0); 2469 return S_OK; 2470 } 2471 2472 long lVal = varChild.lVal; 2473 varChild.lVal = CHILDID_SELF; 2474 IMAccessible *pChild = this->GetChildInterface(lVal); 2475 if(!pChild) 2476 return E_FAIL; 2477 return pChild->accDoDefaultAction( varChild ); 2478 2479 LEAVE_PROTECTED_BLOCK 2480 } 2481 2482 /** 2483 * UNO set description information for action to COM. 2484 * @param szAction, the action description of the current object. 2485 * @return S_OK if successful. 2486 */ 2487 STDMETHODIMP CMAccessible::Put_ActionDescription( const OLECHAR* szAction) 2488 { 2489 2490 ENTER_PROTECTED_BLOCK 2491 ISDESTROY() 2492 // #CHECK# 2493 if(szAction == NULL) 2494 { 2495 return E_INVALIDARG; 2496 } 2497 SAFE_SYSFREESTRING(m_pszActionDescription ); 2498 m_pszActionDescription = SysAllocString( szAction ); 2499 return S_OK; 2500 2501 LEAVE_PROTECTED_BLOCK 2502 } 2503 2504 BOOL CMAccessible::GetXInterfaceFromXAccessible(XAccessible* pXAcc, XInterface** ppXI, int index) 2505 { 2506 Reference< XAccessibleContext > pRContext; 2507 2508 switch(index) 2509 { 2510 case XI_COMPONENT: 2511 QUERYXINTERFACE(AccessibleComponent) 2512 break; 2513 case XI_TEXT: 2514 QUERYXINTERFACE(AccessibleText) 2515 break; 2516 case XI_EDITABLETEXT: 2517 QUERYXINTERFACE(AccessibleEditableText) 2518 break; 2519 case XI_TABLE: 2520 QUERYXINTERFACE(AccessibleTable) 2521 break; 2522 case XI_SELECTION: 2523 QUERYXINTERFACE(AccessibleSelection) 2524 break; 2525 case XI_EXTENDEDCOMP: 2526 QUERYXINTERFACE(AccessibleExtendedComponent) 2527 break; 2528 case XI_KEYBINDING: 2529 QUERYXINTERFACE(AccessibleKeyBinding) 2530 break; 2531 case XI_ACTION: 2532 QUERYXINTERFACE(AccessibleAction) 2533 break; 2534 case XI_VALUE: 2535 QUERYXINTERFACE(AccessibleValue) 2536 break; 2537 case XI_HYPERTEXT: 2538 QUERYXINTERFACE(AccessibleHypertext) 2539 break; 2540 case XI_HYPERLINK: 2541 QUERYXINTERFACE(AccessibleHyperlink) 2542 break; 2543 case XI_IMAGE: 2544 QUERYXINTERFACE(AccessibleImage) 2545 break; 2546 default: 2547 break; 2548 } 2549 2550 return FALSE; 2551 } 2552 2553 HRESULT WINAPI CMAccessible::SmartQI(void* pv, REFIID iid, void** ppvObject) 2554 { 2555 ENTER_PROTECTED_BLOCK 2556 ISDESTROY() 2557 if( ImplIsEqualGUID(iid,IID_IAccIdentity) || 2558 ImplIsEqualGUID(iid,IID_IStdMarshalInfo) || 2559 ImplIsEqualGUID(iid,IID_IMarshal) || 2560 ImplIsEqualGUID(iid,IID_IExternalConnection)|| 2561 ImplIsEqualGUID(iid,IID_IOleWindow)) 2562 return E_FAIL; 2563 2564 2565 _UNO_AGGMAP_ENTRY* pMap = _GetAggEntries(); 2566 while(pMap && pMap->piid) 2567 { 2568 if(ImplIsEqualGUID(iid, *pMap->piid)) 2569 { 2570 XInterface* pXI = NULL; 2571 BOOL bFound = GetXInterfaceFromXAccessible(pUNOInterface,&pXI,pMap->XIFIndex); 2572 if(!bFound) 2573 { 2574 return E_FAIL; 2575 } 2576 2577 XGUIDToComObjHash::iterator pIndTemp = m_containedObjects.find( iid ); 2578 if ( pIndTemp != m_containedObjects.end() ) 2579 { 2580 return pIndTemp->second.p->QueryInterface( iid, ppvObject ); 2581 } 2582 else 2583 { 2584 ActivateActContext(); 2585 HRESULT hr = pMap->pfnCreateInstance(pv, iid, ppvObject); 2586 DeactivateActContext(); 2587 if(hr == S_OK) 2588 { 2589 m_containedObjects.insert(XGUIDToComObjHash::value_type(*pMap->piid,(IUnknown*)*ppvObject)); 2590 IUNOXWrapper* wrapper = NULL; 2591 ((IUnknown*)*ppvObject)->QueryInterface(IID_IUNOXWrapper, (void**)&wrapper); 2592 if(wrapper) 2593 { 2594 wrapper->put_XInterface((long)pUNOInterface); 2595 wrapper->Release(); 2596 } 2597 return S_OK; 2598 } 2599 } 2600 return E_FAIL; 2601 } 2602 pMap++; 2603 } 2604 return E_FAIL; 2605 2606 LEAVE_PROTECTED_BLOCK 2607 } 2608 2609 BOOL CMAccessible::get_IAccessibleFromXAccessible(long pXAcc, IAccessible **ppIA) 2610 { 2611 2612 ENTER_PROTECTED_BLOCK 2613 2614 // #CHECK# 2615 if(ppIA == NULL) 2616 { 2617 return E_INVALIDARG; 2618 } 2619 BOOL isGet = FALSE; 2620 if(g_pAgent) 2621 isGet = g_pAgent->GetIAccessibleFromXAccessible((XAccessible*)pXAcc,ppIA); 2622 2623 if(isGet) 2624 return TRUE; 2625 else 2626 return FALSE; 2627 2628 LEAVE_PROTECTED_BLOCK 2629 } 2630 2631 void CMAccessible::get_OLECHARFromAny(Any& pAny, OLECHAR* pChar) 2632 { 2633 // #CHECK# 2634 if(pChar == NULL) 2635 return; 2636 2637 switch(pAny.getValueTypeClass()) 2638 { 2639 case TypeClass_CHAR: 2640 { 2641 sal_Int8 val; 2642 pAny >>= val; 2643 swprintf( pChar, L"%d", val); 2644 break; 2645 } 2646 case TypeClass_BOOLEAN: 2647 { 2648 sal_Bool val; 2649 pAny >>= val; 2650 swprintf( pChar, L"%d", val); 2651 break; 2652 } 2653 case TypeClass_BYTE: 2654 { 2655 sal_Int8 val; 2656 pAny >>= val; 2657 swprintf( pChar, L"%d", val); 2658 break; 2659 } 2660 case TypeClass_SHORT: 2661 { 2662 SHORT val; 2663 pAny >>= val; 2664 swprintf( pChar, L"%d", val); 2665 break; 2666 } 2667 case TypeClass_UNSIGNED_SHORT: 2668 { 2669 USHORT val; 2670 pAny >>= val; 2671 swprintf( pChar, L"%d", val); 2672 break; 2673 } 2674 case TypeClass_LONG: 2675 { 2676 LONG val; 2677 pAny >>= val; 2678 swprintf( pChar, L"%ld", val); 2679 break; 2680 } 2681 case TypeClass_UNSIGNED_LONG: 2682 { 2683 ULONG val; 2684 pAny >>= val; 2685 swprintf( pChar, L"%ld", val); 2686 break; 2687 } 2688 case TypeClass_FLOAT: 2689 { 2690 FLOAT val; 2691 pAny >>= val; 2692 swprintf( pChar, L"%.3f", val); 2693 break; 2694 } 2695 case TypeClass_DOUBLE: 2696 { 2697 DOUBLE val; 2698 pAny >>= val; 2699 swprintf( pChar, L"%.6lf", val); 2700 break; 2701 } 2702 case TypeClass_STRING: 2703 { 2704 ::rtl::OUString val; 2705 pAny >>= val; 2706 wcscpy(pChar, val.getStr()); 2707 break; 2708 } 2709 case TypeClass_SEQUENCE: 2710 { 2711 if(pAny.getValueType() == getCppuType( (Sequence< ::rtl::OUString > *)0 ) ) 2712 { 2713 Sequence < ::rtl::OUString > val; 2714 pAny >>= val; 2715 2716 ::rtl::OUString pString; 2717 2718 int count = val.getLength(); 2719 2720 for( int iIndex = 0;iIndex < count;iIndex++ ) 2721 { 2722 pString += val[iIndex]; 2723 } 2724 wcscpy(pChar, pString.getStr()); 2725 } 2726 else if (pAny.getValueType() == getCppuType( (Sequence< ::com::sun::star::style::TabStop >* )0 ) ) 2727 { 2728 Sequence < ::com::sun::star::style::TabStop > val; 2729 pAny >>= val; 2730 int count = val.getLength(); 2731 2732 for( int iIndex = 0;iIndex < count;iIndex++ ) 2733 { 2734 OLECHAR pAttrs[512] = {NULL}; 2735 2736 OLECHAR pAttrsPosition[512] = {NULL}; 2737 OLECHAR pAttrsDescimalChar[512] = {NULL}; 2738 OLECHAR pAttrsFillChar[512] = {NULL}; 2739 2740 ::com::sun::star::style::TabStop sigleVal = val[iIndex]; 2741 2742 swprintf( pAttrsPosition, L"Position=%ld,TabAlign=%ld", 2743 sigleVal.Position, sigleVal.Alignment); 2744 2745 if(sigleVal.DecimalChar==';' || sigleVal.DecimalChar == ':' || sigleVal.DecimalChar == ',' || 2746 sigleVal.DecimalChar == '=' || sigleVal.DecimalChar == '\\') 2747 swprintf( pAttrsDescimalChar, L"DecimalChar=\\%c",sigleVal.DecimalChar); 2748 else 2749 swprintf( pAttrsDescimalChar, L"DecimalChar=%c",sigleVal.DecimalChar); 2750 2751 if(sigleVal.FillChar==';' || sigleVal.FillChar == ':' || sigleVal.FillChar == ',' || 2752 sigleVal.FillChar == '=' || sigleVal.FillChar == '\\') 2753 swprintf( pAttrsFillChar, L"FillChar=\\%c",sigleVal.FillChar); 2754 else 2755 swprintf( pAttrsFillChar, L"FillChar=%c",sigleVal.FillChar); 2756 2757 swprintf( pAttrs, L"%s,%s,%s,",pAttrsPosition,pAttrsDescimalChar,pAttrsFillChar); 2758 2759 wcscat(pChar,pAttrs); 2760 } 2761 } 2762 break; 2763 } 2764 case TypeClass_ENUM: 2765 { 2766 if (pAny.getValueType() == getCppuType( (::com::sun::star::awt::FontSlant* )0 ) ) 2767 { 2768 com::sun::star::awt::FontSlant val; 2769 pAny >>= val; 2770 swprintf( pChar, L"%d", val); 2771 } 2772 } 2773 case TypeClass_STRUCT: 2774 { 2775 if (pAny.getValueType() == getCppuType( (::com::sun::star::style::LineSpacing* )0 ) ) 2776 { 2777 com::sun::star::style::LineSpacing val; 2778 pAny >>= val; 2779 swprintf( pChar, L"Mode=%ld,Height=%ld,", val.Mode, val.Height); 2780 } 2781 else if (pAny.getValueType() == getCppuType( (com::sun::star::accessibility::TextSegment *)0 ) ) 2782 { 2783 com::sun::star::accessibility::TextSegment val; 2784 pAny >>= val; 2785 ::rtl::OUString realVal(val.SegmentText); 2786 wcscpy(pChar, realVal.getStr()); 2787 } 2788 break; 2789 } 2790 case TypeClass_VOID: 2791 case TypeClass_HYPER: 2792 case TypeClass_UNSIGNED_HYPER: 2793 case TypeClass_TYPE: 2794 case TypeClass_ANY: 2795 case TypeClass_TYPEDEF: 2796 case TypeClass_UNION: 2797 case TypeClass_EXCEPTION: 2798 case TypeClass_ARRAY: 2799 case TypeClass_INTERFACE: 2800 case TypeClass_SERVICE: 2801 case TypeClass_MODULE: 2802 case TypeClass_INTERFACE_METHOD: 2803 case TypeClass_INTERFACE_ATTRIBUTE: 2804 case TypeClass_UNKNOWN: 2805 case TypeClass_PROPERTY: 2806 case TypeClass_CONSTANT: 2807 case TypeClass_CONSTANTS: 2808 case TypeClass_SINGLETON: 2809 case TypeClass_MAKE_FIXED_SIZE: 2810 break; 2811 default: 2812 break; 2813 } 2814 } 2815 2816 void CMAccessible::get_OLECHAR4Numbering(const Any& pAny, short numberingLevel,const OUString& numberingPrefix,OLECHAR* pChar) 2817 { 2818 if(pChar == NULL) 2819 return; 2820 Reference< ::com::sun::star::container::XIndexReplace > pXIndex; 2821 if((pAny>>=pXIndex) && (numberingLevel !=-1))//numbering level is -1,means invalid value 2822 { 2823 Any aAny = pXIndex->getByIndex(numberingLevel); 2824 Sequence< ::com::sun::star::beans::PropertyValue > aProps; 2825 aAny >>= aProps; 2826 const ::com::sun::star::beans::PropertyValue* pPropArray = aProps.getConstArray(); 2827 sal_Int32 nCount = aProps.getLength(); 2828 swprintf(pChar,L"Numbering:NumberingLevel=%d,",numberingLevel); 2829 for( sal_Int32 i=0; i<nCount; i++ ) 2830 { 2831 ::com::sun::star::beans::PropertyValue rProp = pPropArray[i]; 2832 if( (rProp.Name.compareTo(OUString::createFromAscii("BulletChar"))==0)|| 2833 (rProp.Name.compareTo(OUString::createFromAscii("GraphicURL"))==0)|| 2834 (rProp.Name.compareTo(OUString::createFromAscii("NumberingType"))==0)) 2835 { 2836 OLECHAR propStr[512] = {NULL}; 2837 swprintf(propStr,L"%s=",rProp.Name.getStr()); 2838 OLECHAR pTemp[256] = {NULL}; 2839 CMAccessible::get_OLECHARFromAny(rProp.Value,pTemp); 2840 if(rProp.Name.compareTo(OUString::createFromAscii("GraphicURL"))==0) 2841 { 2842 OLECHAR* pOccur = wcschr(pTemp,':'); 2843 if(pOccur) 2844 *pOccur = '.'; 2845 } 2846 wcscat(propStr,pTemp); 2847 wcscat(pChar,propStr); 2848 wcscat(pChar,L","); 2849 2850 if(rProp.Name.compareTo(OUString::createFromAscii("NumberingType"))==0) 2851 { 2852 if(numberingPrefix.getLength()!=0) 2853 { 2854 swprintf(pTemp,L"NumberingPrefix=%s,",numberingPrefix.getStr()); 2855 wcscat(pChar,pTemp); 2856 } 2857 } 2858 } 2859 } 2860 } 2861 2862 //Because now have three types numbering level: 2863 //1.real numbering list,numbering level>=0 and numbering Rule !=NULL; 2864 //2.common paragraph, numbering level >=0, and numbering Rule == NULL; 2865 //3.TOC paragraph, numbering level >0, and numbering Rule ==NULL; 2866 // IAText:numberinglevel base on 0, but TOC's level base on 1, 2867 // so NumberingLevel value will be decreased 1 in bridge code. 2868 else if(numberingLevel >0) 2869 { 2870 swprintf(pChar,L"Numbering:NumberingLevel=%d,NumberingType=4,NumberingPrefix=,",numberingLevel-1); 2871 } 2872 else 2873 { 2874 swprintf(pChar,L"Numbering:"); 2875 } 2876 } 2877 2878 void CMAccessible::ConvertAnyToVariant(const ::com::sun::star::uno::Any &rAnyVal, VARIANT *pvData) 2879 { 2880 if(rAnyVal.hasValue()) 2881 { 2882 // Clear VARIANT variable. 2883 VariantClear(pvData); 2884 2885 // Set value according to value type. 2886 switch(rAnyVal.getValueTypeClass()) 2887 { 2888 case TypeClass_CHAR: 2889 pvData->vt = VT_UI1; 2890 memcpy(&pvData->bVal, rAnyVal.getValue(), sizeof(sal_Char)); 2891 break; 2892 2893 case TypeClass_BOOLEAN: 2894 pvData->vt = VT_BOOL; 2895 memcpy(&pvData->boolVal, rAnyVal.getValue(), sizeof(sal_Bool)); 2896 break; 2897 2898 case TypeClass_BYTE: 2899 pvData->vt = VT_UI1; 2900 memcpy(&pvData->bVal, rAnyVal.getValue(), sizeof(sal_Int8)); 2901 break; 2902 2903 case TypeClass_SHORT: 2904 pvData->vt = VT_I2; 2905 memcpy(&pvData->iVal, rAnyVal.getValue(), sizeof(sal_Int16)); 2906 break; 2907 2908 case TypeClass_UNSIGNED_SHORT: 2909 pvData->vt = VT_I2; 2910 memcpy(&pvData->iVal, rAnyVal.getValue(), sizeof(sal_uInt16)); 2911 break; 2912 2913 case TypeClass_LONG: 2914 pvData->vt = VT_I4; 2915 memcpy(&pvData->lVal, rAnyVal.getValue(), sizeof(sal_Int32)); 2916 break; 2917 2918 case TypeClass_UNSIGNED_LONG: 2919 pvData->vt = VT_I4; 2920 memcpy(&pvData->lVal, rAnyVal.getValue(), sizeof(sal_uInt32)); 2921 break; 2922 2923 case TypeClass_FLOAT: 2924 pvData->vt = VT_R4; 2925 memcpy(&pvData->fltVal, rAnyVal.getValue(), sizeof(float)); 2926 break; 2927 2928 case TypeClass_DOUBLE: 2929 pvData->vt = VT_R8; 2930 memcpy(&pvData->dblVal, rAnyVal.getValue(), sizeof(double)); 2931 break; 2932 2933 case TypeClass_STRING: 2934 { 2935 pvData->vt = VT_BSTR; 2936 ::rtl::OUString val; 2937 rAnyVal >>= val; 2938 pvData->bstrVal = SysAllocString((OLECHAR *)val.getStr()); 2939 break; 2940 } 2941 2942 case TypeClass_VOID: 2943 case TypeClass_HYPER: 2944 case TypeClass_UNSIGNED_HYPER: 2945 case TypeClass_TYPE: 2946 case TypeClass_ANY: 2947 case TypeClass_ENUM: 2948 case TypeClass_TYPEDEF: 2949 case TypeClass_STRUCT: 2950 case TypeClass_UNION: 2951 case TypeClass_EXCEPTION: 2952 case TypeClass_SEQUENCE: 2953 case TypeClass_ARRAY: 2954 case TypeClass_INTERFACE: 2955 { 2956 Reference< XAccessible > pXAcc; 2957 if(rAnyVal >>= pXAcc) 2958 { 2959 if(pXAcc.is()) 2960 { 2961 IAccessible* pIAcc = NULL; 2962 get_IAccessibleFromXAccessible((long)pXAcc.get(), &pIAcc); 2963 if(pIAcc == NULL) 2964 { 2965 Reference< XAccessibleContext > pXAccContext = pXAcc->getAccessibleContext(); 2966 g_pAgent->InsertAccObj(pXAcc.get(),pXAccContext->getAccessibleParent().get()); 2967 get_IAccessibleFromXAccessible((long)pXAcc.get(), &pIAcc); 2968 } 2969 if(pIAcc) 2970 { 2971 pIAcc->AddRef(); 2972 2973 pvData->vt = VT_UNKNOWN; 2974 pvData->pdispVal = (IAccessible2*)pIAcc; 2975 break; 2976 } 2977 } 2978 } 2979 } 2980 case TypeClass_SERVICE: 2981 case TypeClass_MODULE: 2982 case TypeClass_INTERFACE_METHOD: 2983 case TypeClass_INTERFACE_ATTRIBUTE: 2984 case TypeClass_UNKNOWN: 2985 case TypeClass_PROPERTY: 2986 case TypeClass_CONSTANT: 2987 case TypeClass_CONSTANTS: 2988 case TypeClass_SINGLETON: 2989 case TypeClass_MAKE_FIXED_SIZE: 2990 // Output the type string, if there is other uno value type. 2991 pvData->vt = VT_BSTR; 2992 pvData->bstrVal = SysAllocString(rAnyVal.getValueTypeName().getStr()); 2993 break; 2994 2995 default: 2996 break; 2997 } 2998 } 2999 else 3000 { 3001 VariantClear(pvData); 3002 } 3003 } 3004 3005 STDMETHODIMP CMAccessible::Get_XAccChildID(long* childID) 3006 { 3007 // #CHECK# 3008 if(childID == NULL) 3009 { 3010 return E_FAIL; 3011 } 3012 *childID = m_dChildID; 3013 return S_OK; 3014 } 3015 STDMETHODIMP CMAccessible:: get_states(AccessibleStates __RPC_FAR *states ) 3016 { 3017 3018 CHECK_ENABLE_INF 3019 ENTER_PROTECTED_BLOCK 3020 ISDESTROY() 3021 // #CHECK XInterface# 3022 if( !pRContext.is() ) 3023 return E_FAIL; 3024 3025 Reference<XAccessibleStateSet> pRStateSet = pRContext.get()->getAccessibleStateSet(); 3026 if(!pRStateSet.is()) 3027 { 3028 return S_OK; 3029 } 3030 Sequence<short> pStates = pRStateSet->getStates(); 3031 3032 3033 long count = pStates.getLength() ; 3034 *states = 0x0; 3035 for( int i = 0; i < count; i++ ) 3036 { 3037 for( int j = 0; j < sizeof(UNO_STATES) / sizeof(UNO_STATES[0]); j++ ) 3038 { 3039 if( pStates[i] == UNO_STATES[j] ) 3040 { 3041 *states |= IA2_STATES[j]; 3042 break; 3043 } 3044 } 3045 } 3046 return S_OK; 3047 3048 3049 LEAVE_PROTECTED_BLOCK 3050 } 3051 3052 // return the UNO roles 3053 STDMETHODIMP CMAccessible:: get_extendedRole( BSTR __RPC_FAR * ) 3054 { 3055 3056 CHECK_ENABLE_INF 3057 ENTER_PROTECTED_BLOCK 3058 ISDESTROY() 3059 3060 return E_NOTIMPL; 3061 3062 LEAVE_PROTECTED_BLOCK 3063 } 3064 3065 STDMETHODIMP CMAccessible:: get_localizedExtendedRole( BSTR __RPC_FAR * ) 3066 { 3067 3068 ENTER_PROTECTED_BLOCK 3069 ISDESTROY() 3070 return E_NOTIMPL; 3071 3072 LEAVE_PROTECTED_BLOCK 3073 } 3074 STDMETHODIMP CMAccessible:: get_nExtendedStates( long __RPC_FAR * ) 3075 { 3076 3077 CHECK_ENABLE_INF 3078 ENTER_PROTECTED_BLOCK 3079 ISDESTROY() 3080 3081 return E_NOTIMPL; 3082 3083 LEAVE_PROTECTED_BLOCK 3084 } 3085 3086 3087 STDMETHODIMP CMAccessible:: get_localizedExtendedStates( long, BSTR __RPC_FAR *__RPC_FAR *, long __RPC_FAR *) 3088 { 3089 3090 ENTER_PROTECTED_BLOCK 3091 ISDESTROY() 3092 return E_NOTIMPL; 3093 3094 LEAVE_PROTECTED_BLOCK 3095 } 3096 3097 3098 STDMETHODIMP CMAccessible:: get_indexInParent( long __RPC_FAR *accParentIndex) 3099 { 3100 3101 CHECK_ENABLE_INF 3102 ENTER_PROTECTED_BLOCK 3103 ISDESTROY() 3104 // #CHECK# 3105 if(accParentIndex == NULL) 3106 return E_INVALIDARG; 3107 3108 // #CHECK XInterface# 3109 if( !pRContext.is() ) 3110 return E_FAIL; 3111 3112 *accParentIndex = pRContext.get()->getAccessibleIndexInParent(); 3113 return S_OK; 3114 3115 3116 LEAVE_PROTECTED_BLOCK 3117 } 3118 STDMETHODIMP CMAccessible:: get_locale( IA2Locale __RPC_FAR *locale ) 3119 { 3120 3121 CHECK_ENABLE_INF 3122 ENTER_PROTECTED_BLOCK 3123 ISDESTROY() 3124 if(locale == NULL) 3125 return E_INVALIDARG; 3126 // #CHECK XInterface# 3127 3128 if( !pRContext.is() ) 3129 return E_FAIL; 3130 3131 ::com::sun::star::lang::Locale unoLoc = pRContext.get()->getLocale(); 3132 locale->language = SysAllocString((OLECHAR*)unoLoc.Language.getStr()); 3133 locale->country = SysAllocString((OLECHAR*)unoLoc.Country.getStr()); 3134 locale->variant = SysAllocString((OLECHAR*)unoLoc.Variant.getStr()); 3135 3136 return S_OK; 3137 3138 LEAVE_PROTECTED_BLOCK 3139 } 3140 3141 DWORD GetMSAAStateFromUNO(short xState) 3142 { 3143 DWORD IState = STATE_SYSTEM_UNAVAILABLE; 3144 switch( xState ) 3145 { 3146 case /*AccessibleStateType::*/AccessibleStateType::BUSY: 3147 IState = STATE_SYSTEM_BUSY; 3148 break; 3149 case /*AccessibleStateType::*/AccessibleStateType::CHECKED: 3150 IState = STATE_SYSTEM_CHECKED; 3151 break; 3152 case /*AccessibleStateType::*/AccessibleStateType::DEFUNC: 3153 IState = STATE_SYSTEM_UNAVAILABLE; 3154 break; 3155 case /*AccessibleStateType::*/AccessibleStateType::EXPANDED: 3156 IState = STATE_SYSTEM_EXPANDED; 3157 break; 3158 case /*AccessibleStateType::*/AccessibleStateType::FOCUSABLE: 3159 IState = STATE_SYSTEM_FOCUSABLE; 3160 break; 3161 case /*AccessibleStateType::*/AccessibleStateType::FOCUSED: 3162 IState = STATE_SYSTEM_FOCUSED; 3163 break; 3164 case /*AccessibleStateType::*/AccessibleStateType::INDETERMINATE: 3165 IState = STATE_SYSTEM_MIXED; 3166 break; 3167 case /*AccessibleStateType::*/AccessibleStateType::MULTI_SELECTABLE: 3168 IState = STATE_SYSTEM_MULTISELECTABLE; 3169 break; 3170 case /*AccessibleStateType::*/AccessibleStateType::PRESSED: 3171 IState = STATE_SYSTEM_PRESSED; 3172 break; 3173 case /*AccessibleStateType::*/AccessibleStateType::RESIZABLE: 3174 IState = STATE_SYSTEM_SIZEABLE; 3175 break; 3176 case /*AccessibleStateType::*/AccessibleStateType::SELECTABLE: 3177 IState = STATE_SYSTEM_SELECTABLE; 3178 break; 3179 case /*AccessibleStateType::*/AccessibleStateType::SELECTED: 3180 IState = STATE_SYSTEM_SELECTED; 3181 break; 3182 case /*AccessibleStateType::*/AccessibleStateType::ARMED: 3183 IState = STATE_SYSTEM_FOCUSED; 3184 break; 3185 case /*AccessibleStateType::*/AccessibleStateType::EXPANDABLE: 3186 IState = STATE_SYSTEM_COLLAPSED; 3187 break; 3188 default: 3189 break; 3190 } 3191 return IState; 3192 } 3193 3194 STDMETHODIMP CMAccessible:: get_appName( BSTR __RPC_FAR *name) 3195 { 3196 3197 ENTER_PROTECTED_BLOCK 3198 ISDESTROY() 3199 if(name == NULL) 3200 return E_INVALIDARG; 3201 3202 *name = SysAllocString(OLESTR("Hannover")); 3203 return S_OK; 3204 LEAVE_PROTECTED_BLOCK 3205 } 3206 STDMETHODIMP CMAccessible:: get_appVersion(BSTR __RPC_FAR *version) 3207 { 3208 3209 ENTER_PROTECTED_BLOCK 3210 ISDESTROY() 3211 if(version == NULL) 3212 return E_INVALIDARG; 3213 *version=SysAllocString(OLESTR("3.0")); 3214 return S_OK; 3215 LEAVE_PROTECTED_BLOCK 3216 } 3217 STDMETHODIMP CMAccessible:: get_toolkitName(BSTR __RPC_FAR *name) 3218 { 3219 3220 ENTER_PROTECTED_BLOCK 3221 ISDESTROY() 3222 if(name == NULL) 3223 return E_INVALIDARG; 3224 *name = SysAllocString(OLESTR(" ")); 3225 return S_OK; 3226 LEAVE_PROTECTED_BLOCK 3227 } 3228 STDMETHODIMP CMAccessible:: get_toolkitVersion(BSTR __RPC_FAR *version) 3229 { 3230 3231 ENTER_PROTECTED_BLOCK 3232 ISDESTROY() 3233 if(version == NULL) 3234 return E_INVALIDARG; 3235 *version = SysAllocString(OLESTR(" ")); 3236 return S_OK; 3237 LEAVE_PROTECTED_BLOCK 3238 } 3239 3240 3241 STDMETHODIMP CMAccessible::get_attributes(/*[out]*/ BSTR *pAttr) 3242 { 3243 CHECK_ENABLE_INF 3244 Reference<XAccessibleContext> pRContext = pUNOInterface->getAccessibleContext(); 3245 if( !pRContext.is() ) 3246 { 3247 return E_FAIL; 3248 } 3249 Reference<XAccessibleExtendedAttributes> pRXI(pRContext,UNO_QUERY); 3250 if( !pRXI.is() ) 3251 return E_FAIL; 3252 else 3253 { 3254 com::sun::star::uno::Reference<com::sun::star::accessibility::XAccessibleExtendedAttributes> pRXAttr; 3255 pRXAttr = pRXI.get(); 3256 ::com::sun::star::uno::Any anyVal = pRXAttr->getExtendedAttributes(); 3257 3258 ::rtl::OUString val; 3259 anyVal >>= val; 3260 3261 if(*pAttr) 3262 SAFE_SYSFREESTRING(*pAttr); 3263 *pAttr = SysAllocString((OLECHAR *)val.getStr()); 3264 3265 return S_OK; 3266 } 3267 } 3268 3269