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