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