1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include "MAccessible.h"
24 #pragma clang diagnostic push
25 #pragma clang diagnostic ignored "-Wnon-virtual-dtor"
29 #pragma clang diagnostic pop
35 #include "AccAction.h"
36 #include "AccRelation.h"
37 #include "AccComponent.h"
39 #include "AccEditableText.h"
43 #include "AccHypertext.h"
44 #include "AccHyperLink.h"
46 #include <rtl/ustrbuf.hxx>
47 #include <vcl/svapp.hxx>
48 #include <o3tl/char16_t2wchar_t.hxx>
49 #include <comphelper/AccessibleImplementationHelper.hxx>
51 #include <com/sun/star/accessibility/XAccessibleText.hpp>
52 #include <com/sun/star/accessibility/XAccessibleEditableText.hpp>
53 #include <com/sun/star/accessibility/XAccessibleImage.hpp>
54 #include <com/sun/star/accessibility/XAccessibleTable.hpp>
55 #include <com/sun/star/accessibility/XAccessibleExtendedComponent.hpp>
56 #include <com/sun/star/accessibility/XAccessibleAction.hpp>
57 #include <com/sun/star/accessibility/XAccessibleKeyBinding.hpp>
58 #include <com/sun/star/accessibility/XAccessibleHypertext.hpp>
59 #include <com/sun/star/accessibility/XAccessibleHyperlink.hpp>
60 #include <com/sun/star/accessibility/XAccessibleRelationSet.hpp>
61 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
62 #include <com/sun/star/accessibility/AccessibleRole.hpp>
63 #include <com/sun/star/accessibility/XAccessibleGroupPosition.hpp>
64 #include <com/sun/star/accessibility/XAccessibleValue.hpp>
65 #include <com/sun/star/accessibility/XAccessibleExtendedAttributes.hpp>
66 #include <com/sun/star/style/LineSpacing.hpp>
67 #include <com/sun/star/style/TabStop.hpp>
68 #include <com/sun/star/container/XIndexReplace.hpp>
71 using namespace com::sun::star::uno
;
72 using namespace com::sun::star::accessibility
;
73 using namespace com::sun::star::accessibility::AccessibleStateType
;
75 enum XInterfaceIndex
{
79 XI_EDITABLETEXT
= 0x04,
82 XI_EXTENDEDCOMP
= 0x07,
92 // IA2 states mapping, and name
93 // maintenance the consistency, change one array, change the three all
94 long const IA2_STATES
[] =
96 IA2_STATE_ACTIVE
, // = 0x1;
97 IA2_STATE_ARMED
, // = 0x2;
98 IA2_STATE_DEFUNCT
, // = 0x4;
99 IA2_STATE_EDITABLE
, // = 0x8;
100 IA2_STATE_HORIZONTAL
, // = 0x10;
101 IA2_STATE_ICONIFIED
, // = 0x20;
102 IA2_STATE_INVALID_ENTRY
, // = 0x80;
103 IA2_STATE_MANAGES_DESCENDANTS
, // = 0x100;
104 IA2_STATE_MODAL
, // = 0x200;
105 IA2_STATE_MULTI_LINE
, // = 0x400;
106 IA2_STATE_OPAQUE
, // = 0x800;
107 IA2_STATE_REQUIRED
, // = 0x2000;
108 IA2_STATE_SELECTABLE_TEXT
, // = 0x3000;
109 IA2_STATE_SINGLE_LINE
, // = 0x4000;
110 IA2_STATE_STALE
, // = 0x8000;
111 IA2_STATE_SUPPORTS_AUTOCOMPLETION
, // = 0x10000;
112 IA2_STATE_TRANSIENT
, //= 0x20000;
113 IA2_STATE_VERTICAL
// = 0x40000;
120 short const UNO_STATES
[] =
122 ACTIVE
, // = (sal_Int16)1;
123 ARMED
, // = (sal_Int16)2;
124 DEFUNC
, // = (sal_Int16)5;
125 EDITABLE
, // = (sal_Int16)6;
126 HORIZONTAL
, // = (sal_Int16)12;
127 ICONIFIED
, // = (sal_Int16)13;
128 -1, //IA2_STATE_INVALID_ENTRY
129 MANAGES_DESCENDANTS
, // = (sal_Int16)15;
130 MODAL
, // = (sal_Int16)16;
131 MULTI_LINE
, // = (sal_Int16)17;
132 OPAQUE
, // = (sal_Int16)19;
133 -1, //IA2_STATE_REQUIRED
134 -1, //IA2_STATE_SELECTABLE_TEXT
135 SINGLE_LINE
, // = (sal_Int16)26;
136 STALE
, // = (sal_Int16)27;
137 -1, //IA2_STATE_SUPPORTS_AUTOCOMPLETION
138 TRANSIENT
, //IA2_STATE_TRANSIENT
139 VERTICAL
// = (sal_Int16)29;
142 using namespace com::sun::star::accessibility::AccessibleRole
;
145 #define QUERYXINTERFACE(ainterface) \
147 if(pXAcc == nullptr) \
149 pRContext = pXAcc->getAccessibleContext(); \
150 if( !pRContext.is() ) \
154 Reference<X##ainterface> pRXI(pRContext,UNO_QUERY);\
159 *ppXI = pRXI.get(); \
163 #define ISDESTROY() \
168 AccObjectManagerAgent
* CMAccessible::g_pAgent
= nullptr;
170 CMAccessible::CMAccessible():
173 m_pszActionDescription(nullptr),
176 m_pszDescription(nullptr),
179 m_dFocusChildID(UACC_NO_FOCUS
),
182 m_bRequiresSave(FALSE
)
184 m_sLocation
.m_dLeft
=0;
185 m_sLocation
.m_dTop
= 0;
186 m_sLocation
.m_dWidth
=0;
187 m_sLocation
.m_dHeight
=0;
188 CEnumVariant::Create(&m_pEnumVar
);
189 m_containedObjects
.clear();
192 CMAccessible::~CMAccessible()
196 if(m_pszName
!=nullptr)
198 SAFE_SYSFREESTRING(m_pszName
);
200 if(m_pszValue
!=nullptr)
202 SAFE_SYSFREESTRING(m_pszValue
);
204 if(m_pszDescription
!=nullptr)
206 SAFE_SYSFREESTRING(m_pszDescription
);
209 if(m_pszActionDescription
!=nullptr)
211 SAFE_SYSFREESTRING(m_pszActionDescription
);
216 m_pIParent
->Release();
219 m_pEnumVar
->Release();
220 m_containedObjects
.clear();
224 * Returns the Parent IAccessible interface pointer to AT.
225 * It should add reference, and the client should release the component.
226 * It should return E_FAIL when the parent point is null.
227 * @param ppdispParent [in,out] used to return the parent interface point.
228 * when the point is null, should return null.
229 * @return S_OK if successful and E_FAIL if the m_pIParent is NULL.
231 COM_DECLSPEC_NOTHROW STDMETHODIMP
CMAccessible::get_accParent(IDispatch
**ppdispParent
)
235 ENTER_PROTECTED_BLOCK
238 if(ppdispParent
== nullptr)
245 *ppdispParent
= m_pIParent
;
246 (*ppdispParent
)->AddRef();
251 HRESULT hr
= AccessibleObjectFromWindow(m_hwnd
, OBJID_WINDOW
, IID_IAccessible
, reinterpret_cast<void**>(ppdispParent
));
252 if (!SUCCEEDED(hr
) || !*ppdispParent
)
260 LEAVE_PROTECTED_BLOCK
264 * Returns child count of current COM object.
265 * @param pcountChildren [in,out] used to return the children count.
266 * @return S_OK if successful.
268 COM_DECLSPEC_NOTHROW STDMETHODIMP
CMAccessible::get_accChildCount(long *pcountChildren
)
272 ENTER_PROTECTED_BLOCK
275 if(pcountChildren
== nullptr)
280 if (!m_xAccessible
.is())
283 Reference
<XAccessibleContext
> const pRContext
=
284 m_xAccessible
->getAccessibleContext();
287 *pcountChildren
= pRContext
->getAccessibleChildCount();
292 LEAVE_PROTECTED_BLOCK
296 * Returns child interface pointer for AT according to input child ID.
297 * @param varChild, vt member of varChild must be VT_I4,and lVal member stores the child ID,
298 * the child ID specify child index from 0 to children count, 0 stands for object self.
299 * @param ppdispChild, [in,out] use to return the child interface point.
300 * @return S_OK if successful and S_FALSE if failure.
302 COM_DECLSPEC_NOTHROW STDMETHODIMP
CMAccessible::get_accChild(VARIANT varChild
, IDispatch
**ppdispChild
)
306 ENTER_PROTECTED_BLOCK
309 if(ppdispChild
== nullptr)
313 if(varChild
.vt
==VT_I4
)
315 //get child interface pointer due to child ID
316 if(varChild
.lVal
==CHILDID_SELF
)
322 *ppdispChild
= GetChildInterface(varChild
.lVal
);
323 if((*ppdispChild
) == nullptr)
325 (*ppdispChild
)->AddRef();
330 LEAVE_PROTECTED_BLOCK
334 * Returns the accessible name of the current COM object self or its one child to AT.
335 * @param varChild, vt member of varChild must be VT_I4,and lVal member stores the child ID,
336 * the child ID specify child index from 0 to children count, 0 stands for object self.
337 * @param pszName, [in,out] use to return the name of the proper object.
338 * @return S_OK if successful and S_FALSE if failure.
340 COM_DECLSPEC_NOTHROW STDMETHODIMP
CMAccessible::get_accName(VARIANT varChild
, BSTR
*pszName
)
344 ENTER_PROTECTED_BLOCK
347 if(pszName
== nullptr)
351 if(varChild
.vt
==VT_I4
)
353 if(varChild
.lVal
==CHILDID_SELF
)
355 SAFE_SYSFREESTRING(*pszName
);
356 *pszName
= SysAllocString(m_pszName
);
360 long lVal
= varChild
.lVal
;
361 varChild
.lVal
= CHILDID_SELF
;
362 IMAccessible
*pChild
= this->GetChildInterface(lVal
);
365 return pChild
->get_accName(varChild
,pszName
);
369 LEAVE_PROTECTED_BLOCK
373 * Returns the accessible value of the current COM object self or its one child to AT.
374 * @param varChild, vt member of varChild must be VT_I4,and lVal member stores the child ID,
375 * the child ID specify child index from 0 to children count, 0 stands for object self.
376 * @param pszValue, [in,out] use to return the value of the proper object.
377 * @return S_OK if successful and S_FALSE if failure.
379 COM_DECLSPEC_NOTHROW STDMETHODIMP
CMAccessible::get_accValue(VARIANT varChild
, BSTR
*pszValue
)
383 ENTER_PROTECTED_BLOCK
386 if( pszValue
== nullptr )
390 if( varChild
.vt
==VT_I4
)
392 if(varChild
.lVal
==CHILDID_SELF
)
394 if(m_dState
& STATE_SYSTEM_PROTECTED
)
395 return E_ACCESSDENIED
;
397 if ( m_pszValue
!=nullptr && wcslen(m_pszValue
) == 0 )
400 SAFE_SYSFREESTRING(*pszValue
);
401 *pszValue
= SysAllocString(m_pszValue
);
405 long lVal
= varChild
.lVal
;
406 varChild
.lVal
= CHILDID_SELF
;
407 IMAccessible
*pChild
= this->GetChildInterface(lVal
);
410 return pChild
->get_accValue(varChild
,pszValue
);
414 LEAVE_PROTECTED_BLOCK
418 * Returns the accessible description of the current COM object self or its one child to AT.
419 * @param varChild, vt member of varChild must be VT_I4,and lVal member stores the child ID,
420 * the child ID specify child index from 0 to children count, 0 stands for object self.
421 * @param pszDescription, [in,out] use to return the description of the proper object.
422 * @return S_OK if successful and E_FAIL if failure.
424 COM_DECLSPEC_NOTHROW STDMETHODIMP
CMAccessible::get_accDescription(VARIANT varChild
, BSTR
*pszDescription
)
428 ENTER_PROTECTED_BLOCK
431 if(pszDescription
== nullptr)
435 if(varChild
.vt
==VT_I4
)
437 if(varChild
.lVal
==CHILDID_SELF
)
439 SAFE_SYSFREESTRING(*pszDescription
);
440 *pszDescription
= SysAllocString(m_pszDescription
);
444 long lVal
= varChild
.lVal
;
445 varChild
.lVal
= CHILDID_SELF
;
446 IMAccessible
*pChild
= this->GetChildInterface(lVal
);
449 return pChild
->get_accDescription(varChild
,pszDescription
);
453 LEAVE_PROTECTED_BLOCK
457 * Returns the accessible role of the current COM object self or its one child to AT.
458 * @param varChild, vt member of varChild must be VT_I4,and lVal member stores the child ID,
459 * the child ID specify child index from 0 to children count, 0 stands for object self.
460 * @param pvarRole, [in,out] use to return the role of the proper object.
461 * @return S_OK if successful and S_FALSE if failure.
463 COM_DECLSPEC_NOTHROW STDMETHODIMP
CMAccessible::get_accRole(VARIANT varChild
, VARIANT
*pvarRole
)
467 ENTER_PROTECTED_BLOCK
470 if(pvarRole
== nullptr)
474 if(varChild
.vt
== VT_I4
)
477 if(varChild
.lVal
== CHILDID_SELF
)
479 if( m_iRole
< IA2_ROLE_CAPTION
)
481 VariantInit(pvarRole
);
482 pvarRole
->vt
= VT_I4
;
483 pvarRole
->lVal
= m_iRole
;
487 VariantInit(pvarRole
);
488 pvarRole
->vt
= VT_I4
;
489 pvarRole
->lVal
= ROLE_SYSTEM_CLIENT
;
495 long lVal
= varChild
.lVal
;
496 varChild
.lVal
= CHILDID_SELF
;
497 IMAccessible
*pChild
= this->GetChildInterface(lVal
);
500 return pChild
->get_accRole(varChild
,pvarRole
);
504 LEAVE_PROTECTED_BLOCK
508 * Returns the accessible state of the current COM object self or its one child to AT.
509 * @param varChild, vt member of varChild must be VT_I4,and lVal member stores the child ID,
510 * the child ID specify child index from 0 to children count, 0 stands for object self.
511 * @param pvarState, [in,out] use to return the state of the proper object.
512 * @return S_OK if successful and S_FALSE if failure.
514 COM_DECLSPEC_NOTHROW STDMETHODIMP
CMAccessible::get_accState(VARIANT varChild
, VARIANT
*pvarState
)
518 ENTER_PROTECTED_BLOCK
521 if(pvarState
== nullptr)
525 if(varChild
.vt
==VT_I4
)
527 if(varChild
.lVal
== CHILDID_SELF
)
529 if (m_xAccessible
.is())
531 Reference
<XAccessibleContext
> const pContext
=
532 m_xAccessible
->getAccessibleContext();
535 // add the STATE_SYSTEM_LINKED state
536 Reference
< XAccessibleHypertext
> pRHypertext(pContext
,UNO_QUERY
);
539 if( pRHypertext
->getHyperLinkCount() > 0 )
540 m_dState
|= STATE_SYSTEM_LINKED
;
542 m_dState
&= ~STATE_SYSTEM_LINKED
;
545 m_dState
&= ~STATE_SYSTEM_LINKED
;
549 VariantInit(pvarState
);
550 pvarState
->vt
= VT_I4
;
551 pvarState
->lVal
= m_dState
;
555 long lVal
= varChild
.lVal
;
556 varChild
.lVal
= CHILDID_SELF
;
557 IMAccessible
*pChild
= this->GetChildInterface(lVal
);
560 return pChild
->get_accState(varChild
,pvarState
);
564 LEAVE_PROTECTED_BLOCK
568 * Returns the accessible helpString of the current COM object self or its one child to AT.
569 * @param varChild, vt member of varChild must be VT_I4,and lVal member stores the child ID,
570 * the child ID specify child index from 0 to children count, 0 stands for object self.
571 * @param pszHelp, [in,out] use to return the helpString of the proper object.
572 * @return S_OK if successful and E_FAIL if failure.
574 COM_DECLSPEC_NOTHROW STDMETHODIMP
CMAccessible::get_accHelp(VARIANT
, BSTR
*)
580 * Returns the accessible HelpTopic of the current COM object self or its one child to AT.
581 * @param varChild, vt member of varChild must be VT_I4,and lVal member stores the child ID,
582 * the child ID specify child index from 0 to children count, 0 stands for object self.
583 * @param pszHelpFile, [in,out] use to return the HelpTopic of the proper object.
584 * @param pidTopic, use to return the HelpTopic ID of the proper object.
585 * @return S_OK if successful and E_FAIL if failure.
586 * Not implemented yet
588 COM_DECLSPEC_NOTHROW STDMETHODIMP
CMAccessible::get_accHelpTopic(BSTR
*, VARIANT
, long *)
593 static bool GetMnemonicChar( const OUString
& aStr
, sal_Unicode
* wStr
)
595 for (sal_Int32 i
= 0;; i
+= 2) {
596 i
= aStr
.indexOf('~', i
);
597 if (i
== -1 || i
== aStr
.getLength() - 1) {
600 auto c
= aStr
[i
+ 1];
609 * Returns the accessible keyboard shortcut 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 pszKeyboardShortcut, [in,out] use to return the kbshortcut of the proper object.
613 * @return S_OK if successful and E_FAIL if failure.
615 COM_DECLSPEC_NOTHROW STDMETHODIMP
CMAccessible::get_accKeyboardShortcut(VARIANT varChild
, BSTR
*pszKeyboardShortcut
)
619 ENTER_PROTECTED_BLOCK
623 if(pszKeyboardShortcut
== nullptr)
628 if(varChild
.vt
==VT_I4
)
630 if(varChild
.lVal
== CHILDID_SELF
)
632 if (m_xAccessible
.is())
634 Reference
<XAccessibleContext
> const pRContext
=
635 m_xAccessible
->getAccessibleContext();
636 if( !pRContext
.is() )
639 Reference
<XAccessibleAction
> pRXI(pRContext
,UNO_QUERY
);
643 if( pRXI
.is() && pRXI
->getAccessibleActionCount() >= 1)
645 Reference
< XAccessibleKeyBinding
> binding
= pRXI
->getAccessibleActionKeyBinding(0);
648 long nCount
= binding
->getAccessibleKeyBindingCount();
651 wString
= comphelper::GetkeyBindingStrByXkeyBinding( binding
->getAccessibleKeyBinding(0) );
655 if(wString
.isEmpty())
657 Reference
<XAccessibleRelationSet
> pRrelationSet
= pRContext
->getAccessibleRelationSet();
658 if(!pRrelationSet
.is())
663 long nRelCount
= pRrelationSet
->getRelationCount();
665 // Modified by Steve Yin, for SODC_1552
666 if( /*nRelCount <= 0 &&*/ m_iRole
== ROLE_SYSTEM_TEXT
)
668 VARIANT varParentRole
;
669 VariantInit( &varParentRole
);
672 && SUCCEEDED(m_pIParent
->get_accRole(varChild
, &varParentRole
))
673 && varParentRole
.lVal
== ROLE_SYSTEM_COMBOBOX
) // edit in comboBox
675 m_pIParent
->get_accKeyboardShortcut(varChild
, pszKeyboardShortcut
);
680 AccessibleRelation
*paccRelation
= nullptr;
681 AccessibleRelation accRelation
;
682 for(int i
=0; i
<nRelCount
; i
++)
684 if( pRrelationSet
->getRelation(i
).RelationType
== 6 )
686 accRelation
= pRrelationSet
->getRelation(i
);
687 paccRelation
= &accRelation
;
691 if(paccRelation
== nullptr)
694 Sequence
< Reference
< XInterface
> > xTargets
= paccRelation
->TargetSet
;
695 Reference
<XInterface
> pRAcc
= xTargets
[0];
697 XAccessible
* pXAcc
= static_cast<XAccessible
*>(pRAcc
.get());
699 Reference
<XAccessibleContext
> pRLebelContext
= pXAcc
->getAccessibleContext();
700 if(!pRLebelContext
.is())
703 pRrelationSet
= pRLebelContext
->getAccessibleRelationSet();
704 nRelCount
= pRrelationSet
->getRelationCount();
706 paccRelation
= nullptr;
707 for(int j
=0; j
<nRelCount
; j
++)
709 if( pRrelationSet
->getRelation(j
).RelationType
== 5 )
711 accRelation
= pRrelationSet
->getRelation(j
);
712 paccRelation
= &accRelation
;
718 xTargets
= paccRelation
->TargetSet
;
720 if (m_xAccessible
.get() != static_cast<XAccessible
*>(pRAcc
.get()))
724 Reference
<XAccessibleExtendedComponent
> pRXIE(pRLebelContext
,UNO_QUERY
);
728 OUString ouStr
= pRXIE
->getTitledBorderText();
730 if(GetMnemonicChar(ouStr
, &key
))
732 wString
= "Alt+" + OUStringChar(key
);
738 SAFE_SYSFREESTRING(*pszKeyboardShortcut
);
739 *pszKeyboardShortcut
= SysAllocString(o3tl::toW(wString
.getStr()));
749 long lVal
= varChild
.lVal
;
750 varChild
.lVal
= CHILDID_SELF
;
751 IMAccessible
*pChild
= this->GetChildInterface(lVal
);
755 return pChild
->get_accKeyboardShortcut(varChild
,pszKeyboardShortcut
);
759 LEAVE_PROTECTED_BLOCK
763 * Returns the current focused child to AT.
764 * @param pvarChild, [in,out] vt member of pvarChild must be VT_I4,and lVal member stores the child ID,
765 * the child ID specify child index from 0 to children count, 0 stands for object self.
766 * @return S_OK if successful and E_FAIL if failure.
768 COM_DECLSPEC_NOTHROW STDMETHODIMP
CMAccessible::get_accFocus(VARIANT
*pvarChild
)
772 ENTER_PROTECTED_BLOCK
775 if(pvarChild
== nullptr)
779 if( m_dFocusChildID
==UACC_NO_FOCUS
)
781 pvarChild
->vt
= VT_EMPTY
;//no focus on the object and its children
784 //if the descendant of current object has focus indicated by m_dFocusChildID, return the IDispatch of this focused object
787 IMAccessible
* pIMAcc
= nullptr;
788 g_pAgent
->GetIAccessibleFromResID(m_dFocusChildID
,&pIMAcc
);
790 pvarChild
->vt
= VT_DISPATCH
;
791 pvarChild
->pdispVal
= pIMAcc
;
796 LEAVE_PROTECTED_BLOCK
800 * Returns the selection of the current COM object to AT.
801 * @param pvarChildren,[in,out]
802 * if selection num is 0,return VT_EMPTY for vt,
803 * if selection num is 1,return VT_I4 for vt,and child index for lVal
804 * if selection num >1,return VT_UNKNOWN for vt, and IEnumVariant* for punkVal
805 * @return S_OK if successful and S_FALSE if failure.
807 COM_DECLSPEC_NOTHROW STDMETHODIMP
CMAccessible::get_accSelection(VARIANT
*pvarChildren
)
811 ENTER_PROTECTED_BLOCK
814 if(pvarChildren
== nullptr)
818 switch(m_pEnumVar
->GetCountOfElements())
821 pvarChildren
->vt
= VT_EMPTY
;
826 VariantInit(&varTmp
[0]);
827 m_pEnumVar
->Next(1,varTmp
,&count
);
830 pvarChildren
->vt
= VT_I4
;
831 pvarChildren
->lVal
= varTmp
[0].lVal
;
832 VariantClear(&varTmp
[0]);
836 pvarChildren
->vt
= VT_UNKNOWN
;
837 m_pEnumVar
->AddRef();
838 pvarChildren
->punkVal
= m_pEnumVar
;
843 LEAVE_PROTECTED_BLOCK
847 * Returns the location of the current COM object self or its one child to AT.
848 * @param varChild, vt member of varChild must be VT_I4,and lVal member stores the child ID,
849 * the child ID specify child index from 0 to children count, 0 stands for object self.
850 * @param pxLeft, [in,out] use to return the x-coordination of the proper object.
851 * @param pyTop, [in,out] use to return the y-coordination of the proper object.
852 * @param pcxWidth, [in,out] use to return the x-coordination width of the proper object.
853 * @param pcyHeight, [in,out] use to return the y-coordination height of the proper object.
854 * @return S_OK if successful and S_FALSE if failure.
856 COM_DECLSPEC_NOTHROW STDMETHODIMP
CMAccessible::accLocation(long *pxLeft
, long *pyTop
, long *pcxWidth
, long *pcyHeight
, VARIANT varChild
)
860 ENTER_PROTECTED_BLOCK
863 if(pxLeft
== nullptr || pyTop
== nullptr || pcxWidth
== nullptr || pcyHeight
== nullptr)
868 if(varChild
.vt
==VT_I4
)
870 if(varChild
.lVal
==CHILDID_SELF
)
873 if (m_xAccessible
.is())
875 Reference
<XAccessibleContext
> const pRContext
=
876 m_xAccessible
->getAccessibleContext();
877 if( !pRContext
.is() )
879 Reference
< XAccessibleComponent
> pRComponent(pRContext
,UNO_QUERY
);
880 if( !pRComponent
.is() )
883 css::awt::Point pCPoint
= pRComponent
->getLocationOnScreen();
884 css::awt::Size pCSize
= pRComponent
->getSize();
887 *pcxWidth
= pCSize
.Width
;
888 *pcyHeight
= pCSize
.Height
;
893 *pxLeft
= m_sLocation
.m_dLeft
;
894 *pyTop
= m_sLocation
.m_dTop
;
895 *pcxWidth
= m_sLocation
.m_dWidth
;
896 *pcyHeight
= m_sLocation
.m_dHeight
;
904 LEAVE_PROTECTED_BLOCK
908 * Returns the current focused child to AT.
909 * @param navDir, the direction flag of the navigation.
910 * @param varStart, the start child id of this navigation action.
911 * @param pvarEndUpAt, [in,out] the end up child of this navigation action.
912 * @return S_OK if successful and E_FAIL if failure.
914 COM_DECLSPEC_NOTHROW STDMETHODIMP
CMAccessible::accNavigate(long navDir
, VARIANT varStart
, VARIANT
*pvarEndUpAt
)
918 ENTER_PROTECTED_BLOCK
921 if(pvarEndUpAt
== nullptr)
925 HRESULT ret
= E_FAIL
;
928 case NAVDIR_FIRSTCHILD
:
929 ret
= GetFirstChild(varStart
,pvarEndUpAt
);
931 case NAVDIR_LASTCHILD
:
932 ret
= GetLastChild(varStart
,pvarEndUpAt
);
935 ret
= GetNextSibling(varStart
,pvarEndUpAt
);
937 case NAVDIR_PREVIOUS
:
938 ret
= GetPreSibling(varStart
,pvarEndUpAt
);
940 case NAVDIR_DOWN
://do not implement temporarily
942 case NAVDIR_UP
://do not implement temporarily
944 case NAVDIR_LEFT
://do not implement temporarily
946 case NAVDIR_RIGHT
://do not implement temporarily
953 LEAVE_PROTECTED_BLOCK
956 COM_DECLSPEC_NOTHROW STDMETHODIMP
CMAccessible::accHitTest(long xLeft
, long yTop
, VARIANT
*pvarChild
)
960 ENTER_PROTECTED_BLOCK
963 if(pvarChild
== nullptr)
969 VariantInit(&varSelf
);
971 varSelf
.lVal
= CHILDID_SELF
;
972 accLocation(&x
,&y
,&w
,&h
,varSelf
);
973 if( (x
< xLeft
&& (x
+ w
) >xLeft
) && (y
< yTop
&& (y
+ h
) >yTop
) )
976 pvarChild
->vt
= VT_EMPTY
;
977 Reference
< XAccessibleContext
> pRContext
= GetContextByXAcc(m_xAccessible
.get());
978 nCount
= pRContext
->getAccessibleChildCount();
981 IMAccessible
* child
= nullptr;
982 for( i
= 0; i
<nCount
; i
++)
985 child
= GetChildInterface(i
+ 1);
986 if(child
&& child
->accHitTest(xLeft
,yTop
,pvarChild
) == S_OK
)
990 if(pvarChild
->vt
== VT_DISPATCH
)
995 pvarChild
->vt
= VT_DISPATCH
;
996 pvarChild
->pdispVal
= child
;
1001 pvarChild
->vt
= VT_I4
;
1002 pvarChild
->lVal
= CHILDID_SELF
;
1008 LEAVE_PROTECTED_BLOCK
1012 * Get The other Interface from CMAccessible.
1013 * @param guidService, must be IID_IAccessible here.
1014 * @param riid, the IID interface .
1015 * @return S_OK if successful and S_FALSE if failure.
1017 COM_DECLSPEC_NOTHROW STDMETHODIMP
CMAccessible::QueryService(REFGUID guidService
, REFIID riid
, void** ppvObject
)
1019 if( InlineIsEqualGUID(guidService
, IID_IAccessible
) )
1020 return QueryInterface(riid
, ppvObject
);
1025 * Set the accessible name of the current COM object self or its one child from UNO.
1026 * @param varChild, vt member of varChild must be VT_I4,and lVal member stores the child ID,
1027 * the child ID specify child index from 0 to children count, 0 stands for object self.
1028 * @param szName, the name used to set the name of the proper object.
1029 * @return S_OK if successful and E_FAIL if failure.
1031 COM_DECLSPEC_NOTHROW STDMETHODIMP
CMAccessible::put_accName(VARIANT varChild
, BSTR szName
)
1035 ENTER_PROTECTED_BLOCK
1037 if(varChild
.vt
==VT_I4
)
1039 if(varChild
.lVal
==CHILDID_SELF
)
1041 SAFE_SYSFREESTRING(m_pszName
);
1042 m_pszName
=SysAllocString(szName
);
1046 long lVal
= varChild
.lVal
;
1047 varChild
.lVal
= CHILDID_SELF
;
1048 IMAccessible
*pChild
= this->GetChildInterface(lVal
);
1051 return pChild
->put_accName(varChild
,szName
);
1055 LEAVE_PROTECTED_BLOCK
1059 * Set the accessible value of the current COM object self or its one child from UNO.
1060 * @param varChild, vt member of varChild must be VT_I4,and lVal member stores the child ID,
1061 * the child ID specify child index from 0 to children count, 0 stands for object self.
1062 * @param szValue, the value used to set the value of the proper object.
1063 * @return S_OK if successful and E_FAIL if failure.
1065 COM_DECLSPEC_NOTHROW STDMETHODIMP
CMAccessible::put_accValue(VARIANT varChild
, BSTR szValue
)
1069 ENTER_PROTECTED_BLOCK
1071 if(varChild
.vt
==VT_I4
)
1073 if(varChild
.lVal
==CHILDID_SELF
)
1075 SAFE_SYSFREESTRING(m_pszValue
);
1076 m_pszValue
=SysAllocString(szValue
);
1080 long lVal
= varChild
.lVal
;
1081 varChild
.lVal
= CHILDID_SELF
;
1082 IMAccessible
*pChild
= this->GetChildInterface(lVal
);
1085 return pChild
->put_accValue(varChild
,szValue
);
1089 LEAVE_PROTECTED_BLOCK
1093 * Set the accessible name of the current COM object self from UNO.
1094 * @param pszName, the name value used to set the name of the current object.
1095 * @return S_OK if successful and E_FAIL if failure.
1097 COM_DECLSPEC_NOTHROW STDMETHODIMP
CMAccessible::Put_XAccName(const OLECHAR __RPC_FAR
*pszName
)
1099 // internal IMAccessible - no mutex meeded
1101 ENTER_PROTECTED_BLOCK
1104 if(pszName
== nullptr)
1106 return E_INVALIDARG
;
1109 SAFE_SYSFREESTRING(m_pszName
);
1110 m_pszName
= SysAllocString(pszName
);
1111 if(m_pszName
==nullptr)
1115 LEAVE_PROTECTED_BLOCK
1119 * Set the accessible role of the current COM object self from UNO.
1120 * @param pRole, the role value used to set the role of the current object.
1121 * @return S_OK if successful and E_FAIL if failure.
1123 COM_DECLSPEC_NOTHROW STDMETHODIMP
CMAccessible::Put_XAccRole(unsigned short pRole
)
1125 // internal IMAccessible - no mutex meeded
1132 * Add one state into the current state set for the current COM object from UNO.
1133 * @param pXSate, the state used to set the name of the current object.
1134 * @return S_OK if successful and E_FAIL if failure.
1136 COM_DECLSPEC_NOTHROW STDMETHODIMP
CMAccessible::DecreaseState(DWORD pXSate
)
1138 // internal IMAccessible - no mutex meeded
1140 m_dState
&= (~pXSate
);
1145 * Delete one state into the current state set for the current COM object from UNO.
1146 * @param pXSate, the state used to set the name of the current object.
1147 * @return S_OK if successful and E_FAIL if failure.
1149 COM_DECLSPEC_NOTHROW STDMETHODIMP
CMAccessible::IncreaseState(DWORD pXSate
)
1151 // internal IMAccessible - no mutex meeded
1158 * Set state into the current state set for the current COM object from UNO.
1159 * @param pXSate, the state used to set the name of the current object.
1160 * @return S_OK if successful and E_FAIL if failure.
1162 COM_DECLSPEC_NOTHROW STDMETHODIMP
CMAccessible::SetState(DWORD pXSate
)
1164 // internal IMAccessible - no mutex meeded
1172 * Set the accessible description of the current COM object self from UNO.
1173 * @param pszDescription, the name used to set the description of the current object.
1174 * @return S_OK if successful and E_FAIL if failure.
1176 COM_DECLSPEC_NOTHROW STDMETHODIMP
CMAccessible::Put_XAccDescription(const OLECHAR __RPC_FAR
*pszDescription
)
1178 // internal IMAccessible - no mutex meeded
1180 ENTER_PROTECTED_BLOCK
1183 if(pszDescription
== nullptr)
1185 return E_INVALIDARG
;
1188 SAFE_SYSFREESTRING(m_pszDescription
);
1189 m_pszDescription
= SysAllocString(pszDescription
);
1191 if(m_pszDescription
==nullptr)
1195 LEAVE_PROTECTED_BLOCK
1199 * Set the accessible value of the current COM object self from UNO.
1200 * @param pszAccValue, the name used to set the value of the current object.
1201 * @return S_OK if successful and E_FAIL if failure.
1203 COM_DECLSPEC_NOTHROW STDMETHODIMP
CMAccessible::Put_XAccValue(const OLECHAR __RPC_FAR
*pszAccValue
)
1205 // internal IMAccessible - no mutex meeded
1207 ENTER_PROTECTED_BLOCK
1210 if(pszAccValue
== nullptr)
1212 return E_INVALIDARG
;
1214 SAFE_SYSFREESTRING(m_pszValue
);
1215 m_pszValue
= SysAllocString(pszAccValue
);
1216 if(m_pszValue
==nullptr)
1220 LEAVE_PROTECTED_BLOCK
1224 * Set the HWND value of the current COM object self from UNO. It should set the parent IAccessible
1225 * Object through the method AccessibleObjectFromWindow(...).
1226 * @param hwnd, the HWND used to set the value of the current object.
1227 * @return S_OK if successful and E_FAIL if failure.
1229 COM_DECLSPEC_NOTHROW STDMETHODIMP
CMAccessible::Put_XAccWindowHandle(HWND hwnd
)
1231 // internal IMAccessible - no mutex meeded
1233 ENTER_PROTECTED_BLOCK
1238 LEAVE_PROTECTED_BLOCK
1242 * Set accessible focus by specifying child ID
1243 * @param dChildID, the child id identifies the focus child.
1244 * @return S_OK if successful and E_FAIL if failure.
1246 COM_DECLSPEC_NOTHROW STDMETHODIMP
CMAccessible::Put_XAccFocus(long dChildID
)
1248 // internal IMAccessible - no mutex meeded
1250 ENTER_PROTECTED_BLOCK
1253 if(dChildID
==CHILDID_SELF
)
1257 m_pIParent
->Put_XAccFocus(m_dChildID
);
1262 m_dFocusChildID
= dChildID
;
1263 //traverse all ancestors to set the focused child ID so that when the get_accFocus is called on
1264 //any of the ancestors, this id can be used to get the IAccessible of focused object.
1267 m_pIParent
->Put_XAccFocus(dChildID
);
1272 LEAVE_PROTECTED_BLOCK
1276 *Set accessible object location for the current COM object
1277 * @param sLocation, the location of the current object.
1278 * @return S_OK if successful and E_FAIL if failure.
1280 COM_DECLSPEC_NOTHROW STDMETHODIMP
CMAccessible::Put_XAccLocation(const Location sLocation
)
1282 // internal IMAccessible - no mutex meeded
1284 this->m_sLocation
= sLocation
;
1289 * Set accessible parent object for the current COM object if
1290 * the current object is a child of some COM object
1291 * @param pIParent, the parent of the current object.
1292 * @return S_OK if successful and E_FAIL if failure.
1294 COM_DECLSPEC_NOTHROW STDMETHODIMP
CMAccessible::Put_XAccParent(IMAccessible __RPC_FAR
*pIParent
)
1296 // internal IMAccessible - no mutex meeded
1298 this->m_pIParent
= pIParent
;
1301 m_pIParent
->AddRef();
1307 * Set unique child id to COM
1308 * @param dChildID, the id of the current object.
1309 * @return S_OK if successful and E_FAIL if failure.
1311 COM_DECLSPEC_NOTHROW STDMETHODIMP
CMAccessible::Put_XAccChildID(long dChildID
)
1313 // internal IMAccessible - no mutex meeded
1315 this->m_dChildID
= dChildID
;
1320 * Set AccObjectManagerAgent object pointer to COM
1321 * @param pAgent, the AccObjectManagerAgent point.
1322 * @return S_OK if successful and E_FAIL if failure.
1324 COM_DECLSPEC_NOTHROW STDMETHODIMP
CMAccessible::Put_XAccAgent(hyper pAgent
)
1326 // internal IMAccessible - no mutex meeded
1328 g_pAgent
= reinterpret_cast<AccObjectManagerAgent
*>(pAgent
);
1333 * When a UNO control disposing, it disposes its listeners,
1334 * then notify AccObject in bridge management, then notify
1335 * COM that the XAccessible is invalid,so set m_xAccessible as NULL
1336 * @param isDestroy, true is it needs to be destroyed.
1337 * @return S_OK if successful and E_FAIL if failure.
1339 COM_DECLSPEC_NOTHROW STDMETHODIMP
CMAccessible::NotifyDestroy(BOOL isDestroy
)
1341 // internal IMAccessible - no mutex meeded
1343 m_isDestroy
= isDestroy
;
1344 m_xAccessible
.clear();
1349 *private methods that help implement public functions
1353 * Return child interface pointer by child ID,note: need to call AddRef()
1354 * @param lChildID, specify child index,which AT(such as Inspect32) gives.
1355 * @return IMAccessible*, pointer to the corresponding child object.
1357 IMAccessible
* CMAccessible::GetChildInterface(long dChildID
)//for test
1363 IMAccessible
* pIMAcc
= nullptr;
1364 g_pAgent
->GetIAccessibleFromResID(dChildID
,&pIMAcc
);
1371 if (!m_xAccessible
.is())
1374 Reference
<XAccessibleContext
> const pRContext
=
1375 m_xAccessible
->getAccessibleContext();
1376 if( !pRContext
.is() )
1379 if(dChildID
<1 || dChildID
>pRContext
->getAccessibleChildCount())
1382 IAccessible
* pChild
= nullptr;
1383 Reference
< XAccessible
> pXChild
= pRContext
->getAccessibleChild(dChildID
-1);
1384 BOOL isGet
= get_IAccessibleFromXAccessible(pXChild
.get(), &pChild
);
1388 g_pAgent
->InsertAccObj(pXChild
.get(), m_xAccessible
.get(),
1389 reinterpret_cast<sal_Int64
>(m_hwnd
));
1390 isGet
= get_IAccessibleFromXAccessible(pXChild
.get(), &pChild
);
1395 IMAccessible
* pIMAcc
= static_cast<IMAccessible
*>(pChild
);
1404 * For List, tree and table,these roles belong to manage_descendant in UNO,
1405 * need to process specifically when navigate
1406 * @return BOOL, if it is descendantmanager, return true.
1408 BOOL
CMAccessible::IsDescendantManage()
1411 return (m_iRole
==ROLE_SYSTEM_LIST
)||(m_iRole
==ROLE_SYSTEM_OUTLINE
)||(m_iRole
==ROLE_SYSTEM_TABLE
);
1415 * for descendantmanager circumstance,provide child interface when navigate
1416 * @param varCur, the current child.
1417 * @param flags, the navigation direction.
1418 * @return IMAccessible*, the child of the end up node.
1420 IMAccessible
* CMAccessible::GetNavigateChildForDM(VARIANT varCur
, short flags
)
1423 XAccessibleContext
* pXContext
= GetContextByXAcc(m_xAccessible
.get());
1424 if(pXContext
==nullptr)
1429 int count
= pXContext
->getAccessibleChildCount();
1435 IMAccessible
* pCurChild
= nullptr;
1437 XAccessible
* pChildXAcc
;
1440 Reference
<XAccessible
> pRChildXAcc
;
1441 XAccessibleContext
* pChildContext
= nullptr;
1442 int index
= 0,delta
=0;
1446 pRChildXAcc
= pXContext
->getAccessibleChild(0);
1449 pRChildXAcc
= pXContext
->getAccessibleChild(count
-1);
1453 pCurChild
= GetChildInterface(varCur
.lVal
);
1454 if(pCurChild
==nullptr)
1458 pCurChild
->GetUNOInterface(&nHyper
);
1459 if(pChildXAcc
==nullptr)
1463 pChildContext
= GetContextByXAcc(pChildXAcc
);
1464 if(pChildContext
== nullptr)
1468 delta
= (flags
==DM_NEXTCHILD
)?1:-1;
1469 //currently, getAccessibleIndexInParent is error in UNO for
1470 //some kind of List,such as ValueSet, the index will be less 1 than
1471 //what should be, need to fix UNO code
1472 index
= pChildContext
->getAccessibleIndexInParent()+delta
;
1473 if((index
>=0)&&(index
<=count
-1))
1475 pRChildXAcc
= pXContext
->getAccessibleChild(index
);
1482 if(!pRChildXAcc
.is())
1486 pChildXAcc
= pRChildXAcc
.get();
1487 g_pAgent
->InsertAccObj(pChildXAcc
, m_xAccessible
.get());
1488 return g_pAgent
->GetIMAccByXAcc(pChildXAcc
);
1492 *the following 4 private methods are for accNavigate implementation
1496 * Return first child for parent container, process differently according
1497 * to whether it is descendant manage
1498 * @param varStart, the start child id of this navigation action.
1499 * @param pvarEndUpAt, [in,out] the end up child of this navigation action.
1500 * @return S_OK if successful and E_FAIL if failure.
1502 HRESULT
CMAccessible::GetFirstChild(VARIANT varStart
,VARIANT
* pvarEndUpAt
)
1505 ENTER_PROTECTED_BLOCK
1508 if(pvarEndUpAt
== nullptr)
1510 return E_INVALIDARG
;
1512 if(varStart
.vt
!= VT_I4
)
1514 pvarEndUpAt
->vt
= VT_EMPTY
;
1515 return E_INVALIDARG
;
1518 pvarEndUpAt
->pdispVal
= GetNavigateChildForDM(varStart
, DM_FIRSTCHILD
);
1519 if(pvarEndUpAt
->pdispVal
)
1521 pvarEndUpAt
->pdispVal
->AddRef();
1522 pvarEndUpAt
->vt
= VT_DISPATCH
;
1526 pvarEndUpAt
->vt
= VT_EMPTY
;
1529 LEAVE_PROTECTED_BLOCK
1533 * Return last child for parent container, process differently according
1534 * to whether it is descendant manage
1535 * @param varStart, the start child id of this navigation action.
1536 * @param pvarEndUpAt, [in,out] the end up child of this navigation action.
1537 * @return S_OK if successful and E_FAIL if failure.
1539 HRESULT
CMAccessible::GetLastChild(VARIANT varStart
,VARIANT
* pvarEndUpAt
)
1542 ENTER_PROTECTED_BLOCK
1545 if(pvarEndUpAt
== nullptr)
1547 return E_INVALIDARG
;
1549 if(varStart
.vt
!= VT_I4
)
1551 pvarEndUpAt
->vt
= VT_EMPTY
;
1552 return E_INVALIDARG
;
1555 pvarEndUpAt
->pdispVal
= GetNavigateChildForDM(varStart
, DM_LASTCHILD
);
1556 if(pvarEndUpAt
->pdispVal
)
1558 pvarEndUpAt
->pdispVal
->AddRef();
1559 pvarEndUpAt
->vt
= VT_DISPATCH
;
1562 pvarEndUpAt
->vt
= VT_EMPTY
;
1565 LEAVE_PROTECTED_BLOCK
1569 * The method GetNextSibling is general, whatever it is descendant manage or not
1570 * Get the next sibling object.
1571 * @param varStart, the start child id of this navigation action.
1572 * @param pvarEndUpAt, [in,out] the end up child of this navigation action.
1573 * @return S_OK if successful and E_FAIL if failure.
1575 HRESULT
CMAccessible::GetNextSibling(VARIANT varStart
,VARIANT
* pvarEndUpAt
)
1578 ENTER_PROTECTED_BLOCK
1580 if(varStart
.vt
!= VT_I4
)
1582 pvarEndUpAt
->vt
= VT_EMPTY
;
1583 return E_INVALIDARG
;
1586 Reference
<XAccessibleContext
> const pRContext
=
1587 GetContextByXAcc(m_xAccessible
.get());
1590 varStart
.iVal
= sal_Int16(pRContext
->getAccessibleIndexInParent() + 2);
1592 if( m_pIParent
->get_accChild(varStart
,&pvarEndUpAt
->pdispVal
) == S_OK
)
1594 pvarEndUpAt
->vt
= VT_DISPATCH
;
1598 pvarEndUpAt
->vt
= VT_EMPTY
;
1601 LEAVE_PROTECTED_BLOCK
1605 *the method GetPreSibling is general, whatever it is descendant manage or not
1606 * @param varStart, the start child id of this navigation action.
1607 * @param pvarEndUpAt, [in,out] the end up child of this navigation action.
1608 * @return S_OK if successful and E_FAIL if failure.
1610 HRESULT
CMAccessible::GetPreSibling(VARIANT varStart
,VARIANT
* pvarEndUpAt
)
1613 ENTER_PROTECTED_BLOCK
1616 if(pvarEndUpAt
== nullptr)
1618 return E_INVALIDARG
;
1620 if(varStart
.vt
!= VT_I4
)
1622 pvarEndUpAt
->vt
= VT_EMPTY
;
1623 return E_INVALIDARG
;
1626 Reference
<XAccessibleContext
> const pRContext
=
1627 GetContextByXAcc(m_xAccessible
.get());
1630 varStart
.iVal
= sal_Int16(pRContext
->getAccessibleIndexInParent());
1631 if(m_pIParent
&& varStart
.iVal
> 0)
1632 if( m_pIParent
->get_accChild(varStart
,&pvarEndUpAt
->pdispVal
) == S_OK
)
1634 pvarEndUpAt
->vt
= VT_DISPATCH
;
1638 pvarEndUpAt
->vt
= VT_EMPTY
;
1641 LEAVE_PROTECTED_BLOCK
1645 * For IAccessible2 implementation methods
1647 COM_DECLSPEC_NOTHROW STDMETHODIMP
CMAccessible::get_nRelations( long __RPC_FAR
*nRelations
)
1651 ENTER_PROTECTED_BLOCK
1655 if(nRelations
== nullptr)
1657 return E_INVALIDARG
;
1662 if (!m_xContext
.is())
1664 Reference
<XAccessibleRelationSet
> pRrelationSet
=
1665 m_xContext
.get()->getAccessibleRelationSet();
1666 if(!pRrelationSet
.is())
1672 *nRelations
= pRrelationSet
->getRelationCount();
1675 LEAVE_PROTECTED_BLOCK
1678 COM_DECLSPEC_NOTHROW STDMETHODIMP
CMAccessible::get_relation( long relationIndex
, IAccessibleRelation __RPC_FAR
*__RPC_FAR
*relation
)
1682 ENTER_PROTECTED_BLOCK
1685 if(relation
== nullptr)
1687 return E_INVALIDARG
;
1690 if (!m_xContext
.is())
1695 get_nRelations(&nMax
);
1697 *relation
= static_cast<IAccessibleRelation
*>(::CoTaskMemAlloc(sizeof(IAccessibleRelation
)));
1699 // #CHECK Memory Allocation#
1700 if(*relation
== nullptr)
1705 if( relationIndex
< nMax
)
1707 Reference
<XAccessibleRelationSet
> const pRrelationSet
=
1708 m_xContext
.get()->getAccessibleRelationSet();
1709 if(!pRrelationSet
.is())
1715 IAccessibleRelation
* pRelation
= nullptr;
1716 HRESULT hr
= createInstance
<CAccRelation
>(IID_IAccessibleRelation
,
1720 IUNOXWrapper
* wrapper
= nullptr;
1721 hr
= pRelation
->QueryInterface(IID_IUNOXWrapper
, reinterpret_cast<void**>(&wrapper
));
1724 AccessibleRelation accRelation
= pRrelationSet
->getRelation(relationIndex
);
1725 wrapper
->put_XSubInterface(
1726 reinterpret_cast<hyper
>(&accRelation
));
1728 *relation
= pRelation
;
1737 LEAVE_PROTECTED_BLOCK
1740 COM_DECLSPEC_NOTHROW STDMETHODIMP
CMAccessible::get_relations( long, IAccessibleRelation __RPC_FAR
*__RPC_FAR
*relation
, long __RPC_FAR
*nRelations
)
1744 ENTER_PROTECTED_BLOCK
1748 if(relation
== nullptr || nRelations
== nullptr)
1750 return E_INVALIDARG
;
1752 // #CHECK XInterface#
1754 if (!m_xContext
.is())
1757 Reference
<XAccessibleRelationSet
> const pRrelationSet
=
1758 m_xContext
.get()->getAccessibleRelationSet();
1759 if(!pRrelationSet
.is())
1765 long nCount
= pRrelationSet
->getRelationCount();
1767 *relation
= static_cast<IAccessibleRelation
*>(::CoTaskMemAlloc(nCount
*sizeof(IAccessibleRelation
)));
1769 // #CHECK Memory Allocation#
1770 if(*relation
== nullptr)
1775 for(int i
=0; i
<nCount
; i
++)
1777 IAccessibleRelation
* pRelation
= nullptr;
1778 HRESULT hr
= createInstance
<CAccRelation
>(IID_IAccessibleRelation
,
1782 IUNOXWrapper
* wrapper
= nullptr;
1783 hr
= pRelation
->QueryInterface(IID_IUNOXWrapper
, reinterpret_cast<void**>(&wrapper
));
1786 AccessibleRelation accRelation
= pRrelationSet
->getRelation(i
);
1787 wrapper
->put_XSubInterface(
1788 reinterpret_cast<hyper
>(&accRelation
));
1791 relation
[i
] = pRelation
;
1795 *nRelations
= nCount
;
1798 LEAVE_PROTECTED_BLOCK
1801 COM_DECLSPEC_NOTHROW STDMETHODIMP
CMAccessible::role(long __RPC_FAR
*role
)
1805 ENTER_PROTECTED_BLOCK
1811 LEAVE_PROTECTED_BLOCK
1815 COM_DECLSPEC_NOTHROW STDMETHODIMP
CMAccessible:: get_nActions(long __RPC_FAR
*nActions
)
1823 if(nActions
== nullptr)
1825 return E_INVALIDARG
;
1828 IAccessibleAction
* pAcc
= nullptr;
1829 HRESULT hr
= QueryInterface(IID_IAccessibleAction
, reinterpret_cast<void**>(&pAcc
));
1832 pAcc
->nActions(nActions
);
1846 COM_DECLSPEC_NOTHROW STDMETHODIMP
CMAccessible:: scrollToPoint(enum IA2CoordinateType
, long, long)
1851 COM_DECLSPEC_NOTHROW STDMETHODIMP
CMAccessible:: scrollTo(enum IA2ScrollType
)
1856 static XAccessible
* getTheParentOfMember(XAccessible
* pXAcc
)
1859 if(pXAcc
== nullptr)
1863 Reference
<XAccessibleContext
> pRContext
= pXAcc
->getAccessibleContext();
1864 Reference
<XAccessibleRelationSet
> pRrelationSet
= pRContext
->getAccessibleRelationSet();
1865 sal_Int32 nRelations
= pRrelationSet
->getRelationCount();
1866 for(sal_Int32 i
=0 ; i
<nRelations
; i
++)
1868 AccessibleRelation accRelation
= pRrelationSet
->getRelation(i
);
1869 if(accRelation
.RelationType
== 7)
1871 Sequence
< Reference
< XInterface
> > xTargets
= accRelation
.TargetSet
;
1872 return static_cast<XAccessible
*>(xTargets
[0].get());
1878 COM_DECLSPEC_NOTHROW STDMETHODIMP
CMAccessible:: get_groupPosition(long __RPC_FAR
*groupLevel
,long __RPC_FAR
*similarItemsInGroup
,long __RPC_FAR
*positionInGroup
)
1882 ENTER_PROTECTED_BLOCK
1885 if(groupLevel
== nullptr || similarItemsInGroup
== nullptr || positionInGroup
== nullptr)
1887 return E_INVALIDARG
;
1890 if (!m_xAccessible
.is())
1893 Reference
<XAccessibleContext
> const pRContext
=
1894 m_xAccessible
->getAccessibleContext();
1897 long Role
= pRContext
->getAccessibleRole();
1900 *similarItemsInGroup
= 0;
1901 *positionInGroup
= 0;
1903 if (Role
!= AccessibleRole::DOCUMENT
&& Role
!= AccessibleRole::DOCUMENT_PRESENTATION
&&
1904 Role
!= AccessibleRole::DOCUMENT_SPREADSHEET
&& Role
!= AccessibleRole::DOCUMENT_TEXT
)
1906 Reference
< XAccessibleGroupPosition
> xGroupPosition( pRContext
, UNO_QUERY
);
1907 if ( xGroupPosition
.is() )
1909 Sequence
< sal_Int32
> rSeq
= xGroupPosition
->getGroupPosition( makeAny( pRContext
) );
1910 if (rSeq
.getLength() >= 3)
1912 *groupLevel
= rSeq
[0];
1913 *similarItemsInGroup
= rSeq
[1];
1914 *positionInGroup
= rSeq
[2];
1921 Reference
< XAccessible
> pParentAcc
= pRContext
->getAccessibleParent();
1922 if( !pParentAcc
.is() )
1927 Reference
<XAccessibleContext
> pRParentContext
= pParentAcc
->getAccessibleContext();
1929 if( Role
== RADIO_BUTTON
)
1933 Reference
<XAccessibleRelationSet
> pRrelationSet
= pRContext
->getAccessibleRelationSet();
1934 long nRel
= pRrelationSet
->getRelationCount();
1935 for(int i
=0 ; i
<nRel
; i
++)
1937 AccessibleRelation accRelation
= pRrelationSet
->getRelation(i
);
1938 if(accRelation
.RelationType
== 7)
1940 Sequence
< Reference
< XInterface
> > xTargets
= accRelation
.TargetSet
;
1942 Reference
<XInterface
> pRAcc
= xTargets
[0];
1943 for(int j
=0; j
<pRParentContext
->getAccessibleChildCount(); j
++)
1945 if( getTheParentOfMember(pRParentContext
->getAccessibleChild(j
).get())
1946 == static_cast<XAccessible
*>(pRAcc
.get()) &&
1947 pRParentContext
->getAccessibleChild(j
)->getAccessibleContext()->getAccessibleRole() == RADIO_BUTTON
)
1949 if (pRParentContext
->getAccessibleChild(j
).get() == m_xAccessible
.get())
1955 *similarItemsInGroup
= number
;
1956 *positionInGroup
= index
;
1960 else if ( COMBO_BOX
== Role
)
1963 *similarItemsInGroup
= 0;
1964 *positionInGroup
= -1;
1966 long nCount
= pRContext
->getAccessibleChildCount();
1971 Reference
<XAccessible
> xList
=pRContext
->getAccessibleChild(1);
1976 Reference
<XAccessibleContext
> xListContext(xList
,UNO_QUERY
);
1977 if (!xListContext
.is())
1981 Reference
<XAccessibleSelection
> xListSel(xList
,UNO_QUERY
);
1986 *similarItemsInGroup
= xListContext
->getAccessibleChildCount();
1987 if (*similarItemsInGroup
> 0 )
1991 Reference
<XAccessible
> xChild
= xListSel
->getSelectedAccessibleChild(0);
1994 Reference
<XAccessibleContext
> xChildContext(xChild
,UNO_QUERY
);
1995 if (xChildContext
.is())
1997 *positionInGroup
=xChildContext
->getAccessibleIndexInParent() + 1 ;
2007 else if ( PAGE_TAB
== Role
)
2010 *similarItemsInGroup
= pRParentContext
->getAccessibleChildCount();
2012 if (*similarItemsInGroup
> 0 )
2014 *positionInGroup
=pRContext
->getAccessibleIndexInParent() + 1 ;
2018 *positionInGroup
= -1;
2024 BOOL isFound
= FALSE
;
2025 while( pParentAcc
.is() && !isFound
)
2028 pRParentContext
= pParentAcc
->getAccessibleContext();
2029 Role
= pRParentContext
->getAccessibleRole();
2030 if( (Role
== TREE
) || (Role
== LIST
) )
2032 pParentAcc
= pRParentContext
->getAccessibleParent();
2037 Reference
< XAccessible
> pTempAcc
= pRContext
->getAccessibleParent();
2038 pRParentContext
= pTempAcc
->getAccessibleContext();
2039 *groupLevel
= level
;
2040 *similarItemsInGroup
= pRParentContext
->getAccessibleChildCount();
2041 *positionInGroup
= pRContext
->getAccessibleIndexInParent() + 1;
2046 *similarItemsInGroup
= 0;
2047 *positionInGroup
= 0;
2051 LEAVE_PROTECTED_BLOCK
2054 COM_DECLSPEC_NOTHROW STDMETHODIMP
CMAccessible:: get_extendedStates( long, BSTR __RPC_FAR
*__RPC_FAR
*, long __RPC_FAR
*)
2060 COM_DECLSPEC_NOTHROW STDMETHODIMP
CMAccessible:: get_uniqueID(long __RPC_FAR
*uniqueID
)
2064 ENTER_PROTECTED_BLOCK
2067 if(uniqueID
== nullptr)
2069 return E_INVALIDARG
;
2071 *uniqueID
= m_dChildID
;
2074 LEAVE_PROTECTED_BLOCK
2077 COM_DECLSPEC_NOTHROW STDMETHODIMP
CMAccessible:: get_windowHandle(HWND __RPC_FAR
*windowHandle
)
2081 ENTER_PROTECTED_BLOCK
2084 if(windowHandle
== nullptr)
2086 return E_INVALIDARG
;
2089 HWND nHwnd
= m_hwnd
;
2090 IAccessible
* pParent
= m_pIParent
;
2091 while((nHwnd
==nullptr) && pParent
)
2093 if (CMAccessible
* pChild
= dynamic_cast<CMAccessible
*>(pParent
))
2095 pParent
= pChild
->m_pIParent
;
2096 nHwnd
= pChild
->m_hwnd
;
2102 *windowHandle
= nHwnd
;
2105 LEAVE_PROTECTED_BLOCK
2109 * Get XAccessibleContext directly from UNO by the stored XAccessible pointer
2110 * @param pXAcc, UNO XAccessible object point.
2111 * @return XAccessibleContext*, the context of the pXAcc.
2113 XAccessibleContext
* CMAccessible::GetContextByXAcc( XAccessible
* pXAcc
)
2115 Reference
< XAccessibleContext
> pRContext
;
2116 if( pXAcc
== nullptr)
2119 pRContext
= pXAcc
->getAccessibleContext();
2120 if( !pRContext
.is() )
2122 return pRContext
.get();
2126 * Return the member variable m_pXAccessibleSelection, instead of
2127 * get XAccessibleSelection according to XAccessibleContext because if so,it will
2128 * depend on the UNO implementation code,so when COM is created, put XAccessibleSelection
2129 * by bridge management system
2130 * @return XAccessibleSelection*, the selection of the current object.
2132 Reference
< XAccessibleSelection
> CMAccessible::GetSelection()
2134 if (!m_xAccessible
.is())
2136 Reference
<XAccessibleContext
> const pRContext
=
2137 m_xAccessible
->getAccessibleContext();
2140 Reference
< XAccessibleSelection
> pRSelection(pRContext
,UNO_QUERY
);
2147 * Select one XAccessible item, for accSelect implementation
2148 * @param pItem, the item should be selected.
2149 * @return S_OK if successful.
2151 HRESULT
CMAccessible::SelectChild(XAccessible
* pItem
)
2154 ENTER_PROTECTED_BLOCK
2156 XAccessibleContext
* pParentContext
= GetContextByXAcc(m_xAccessible
.get());
2157 XAccessibleContext
* pContext
= GetContextByXAcc( pItem
);
2158 if( pParentContext
== nullptr || pContext
== nullptr )
2161 Reference
< XAccessibleSelection
> pRSelection
= GetSelection();
2162 if( !pRSelection
.is() )
2164 long Index
= pContext
->getAccessibleIndexInParent();
2165 pRSelection
->selectAccessibleChild( Index
);
2168 LEAVE_PROTECTED_BLOCK
2172 * Deselect one XAccessible item, for accSelect implementation
2173 * @param pItem, the item should be deselected.
2174 * @return S_OK if successful.
2176 HRESULT
CMAccessible::DeSelectChild(XAccessible
* pItem
)
2179 ENTER_PROTECTED_BLOCK
2181 XAccessibleContext
* pParentContext
= GetContextByXAcc(m_xAccessible
.get());
2183 XAccessibleContext
* pContext
= GetContextByXAcc( pItem
);
2184 if( pParentContext
== nullptr || pContext
== nullptr )
2185 return E_INVALIDARG
;
2187 Reference
< XAccessibleSelection
> pRSelection
= GetSelection();
2188 if( !pRSelection
.is() )
2190 long Index
= pContext
->getAccessibleIndexInParent();
2191 pRSelection
->deselectAccessibleChild( Index
);
2195 LEAVE_PROTECTED_BLOCK
2199 * Select multiple XAccessible items,for implementation of accSelect
2200 * @param pItem, the items should be selected.
2201 * @param size, the size of the items.
2202 * @return S_OK if successful.
2204 HRESULT
CMAccessible::SelectMultipleChidren( XAccessible
** pItem
,int size
)
2207 ENTER_PROTECTED_BLOCK
2210 if(pItem
== nullptr)
2212 return E_INVALIDARG
;
2214 for(int index
= 0;index
< size
;index
++)
2216 SelectChild( pItem
[index
] );
2220 LEAVE_PROTECTED_BLOCK
2224 * Deselect multiple XAccessible items,for implementation of accSelect
2225 * @param pItem, the items should be selected.
2226 * @param size, the size of the items.
2227 * @return S_OK if successful.
2229 HRESULT
CMAccessible::DeSelectMultipleChildren( XAccessible
** pItem
,int size
)
2232 ENTER_PROTECTED_BLOCK
2235 if(pItem
== nullptr)
2237 return E_INVALIDARG
;
2239 for(int index
= 0;index
< size
;index
++)
2241 DeSelectChild( pItem
[index
] );
2245 LEAVE_PROTECTED_BLOCK
2249 * When COM is created, UNO set XAccessible pointer to it
2250 * in order to COM can operate UNO information
2251 * @param pXAcc, the XAccessible object of current object.
2252 * @return S_OK if successful.
2254 COM_DECLSPEC_NOTHROW STDMETHODIMP
CMAccessible::SetXAccessible(hyper pXAcc
)
2256 // internal IMAccessible - no mutex meeded
2258 m_xAccessible
= reinterpret_cast<XAccessible
*>(pXAcc
);
2259 m_pEnumVar
->PutSelection(/*XAccessibleSelection*/
2260 reinterpret_cast<hyper
>(m_xAccessible
.get()));
2262 m_xContext
= m_xAccessible
->getAccessibleContext();
2268 * accSelect method has many optional flags, needs to process comprehensively
2269 * Mozilla and Microsoft do not implement SELFLAG_EXTENDSELECTION flag.
2270 * The implementation of this flag is a little trouble-shooting,so we also
2271 * do not implement it now
2272 * @param flagsSelect, the selection flag of the select action.
2273 * @param varChild, the child object pointer of current action.
2274 * @return S_OK if successful.
2276 COM_DECLSPEC_NOTHROW STDMETHODIMP
CMAccessible::accSelect(long flagsSelect
, VARIANT varChild
)
2280 ENTER_PROTECTED_BLOCK
2282 if( (flagsSelect
&SELFLAG_ADDSELECTION
) &&
2283 (SELFLAG_REMOVESELECTION
&flagsSelect
) )
2284 return E_INVALIDARG
;
2286 if ( (flagsSelect
&SELFLAG_TAKESELECTION
) &&
2288 (flagsSelect
&SELFLAG_ADDSELECTION
) ||
2289 (flagsSelect
&SELFLAG_REMOVESELECTION
) ||
2290 (flagsSelect
&SELFLAG_EXTENDSELECTION
)
2293 return E_INVALIDARG
;
2295 if ( varChild
.vt
!= VT_I4
)
2296 return E_INVALIDARG
;
2298 IMAccessible
* pSelectAcc
;
2299 if( varChild
.lVal
== CHILDID_SELF
)
2302 pSelectAcc
->AddRef();
2306 pSelectAcc
= GetChildInterface(varChild
.lVal
);
2309 if( pSelectAcc
== nullptr )
2310 return E_INVALIDARG
;
2312 if( flagsSelect
&SELFLAG_TAKEFOCUS
)
2315 XAccessible
* pTempUNO
;
2318 pSelectAcc
->GetUNOInterface(&nHyper
);
2320 if( pTempUNO
== nullptr )
2323 Reference
<XAccessibleContext
> pRContext
= pTempUNO
->getAccessibleContext();
2324 Reference
< XAccessibleComponent
> pRComponent(pRContext
,UNO_QUERY
);
2325 Reference
< XAccessible
> pRParentXAcc
= pRContext
->getAccessibleParent();
2326 Reference
< XAccessibleContext
> pRParentContext
= pRParentXAcc
->getAccessibleContext();
2327 Reference
< XAccessibleComponent
> pRParentComponent(pRParentContext
,UNO_QUERY
);
2328 Reference
< XAccessibleSelection
> pRParentSelection(pRParentContext
,UNO_QUERY
);
2331 pRComponent
->grabFocus();
2333 if( flagsSelect
& SELFLAG_TAKESELECTION
)
2335 pRParentSelection
->clearAccessibleSelection();
2336 pRParentSelection
->selectAccessibleChild( pRContext
->getAccessibleIndexInParent() );
2339 if( flagsSelect
& SELFLAG_ADDSELECTION
)
2341 pRParentSelection
->selectAccessibleChild( pRContext
->getAccessibleIndexInParent() );
2344 if( flagsSelect
& SELFLAG_REMOVESELECTION
)
2346 pRParentSelection
->deselectAccessibleChild( pRContext
->getAccessibleIndexInParent() );
2349 if( flagsSelect
& SELFLAG_EXTENDSELECTION
)
2351 long indexInParrent
= pRContext
->getAccessibleIndexInParent();
2353 if( pRParentSelection
->isAccessibleChildSelected( indexInParrent
+ 1 ) ||
2354 pRParentSelection
->isAccessibleChildSelected( indexInParrent
- 1 ) )
2356 pRParentSelection
->selectAccessibleChild( indexInParrent
);
2362 pSelectAcc
->Release();
2365 LEAVE_PROTECTED_BLOCK
2369 * Return XAccessible interface pointer when needed
2370 * @param pXAcc, [in, out] the Uno interface of the current object.
2371 * @return S_OK if successful.
2373 COM_DECLSPEC_NOTHROW STDMETHODIMP
CMAccessible::GetUNOInterface(hyper
* pXAcc
)
2375 // internal IMAccessible - no mutex meeded
2377 if(pXAcc
== nullptr)
2378 return E_INVALIDARG
;
2380 *pXAcc
= reinterpret_cast<hyper
>(m_xAccessible
.get());
2385 * Helper method for Implementation of get_accDefaultAction
2386 * @param pAction, the default action point of the current object.
2387 * @return S_OK if successful.
2389 COM_DECLSPEC_NOTHROW STDMETHODIMP
CMAccessible::SetDefaultAction(hyper pAction
)
2391 // internal IMAccessible - no mutex meeded
2393 m_xAction
= reinterpret_cast<XAccessibleAction
*>(pAction
);
2398 * This method is called when AT open some UI elements initially
2399 * the UI element takes the default action defined here
2400 * @param varChild, the child id of the defaultaction.
2401 * @param pszDefaultAction,[in/out] the description of the current action.
2402 * @return S_OK if successful.
2404 COM_DECLSPEC_NOTHROW HRESULT STDMETHODCALLTYPE
CMAccessible::get_accDefaultAction(VARIANT varChild
, BSTR
*pszDefaultAction
)
2408 ENTER_PROTECTED_BLOCK
2411 if(pszDefaultAction
== nullptr)
2413 return E_INVALIDARG
;
2415 if(varChild
.vt
==VT_I4
)
2417 if(varChild
.lVal
==CHILDID_SELF
)
2419 if (!m_xAction
.is())
2420 return DISP_E_MEMBERNOTFOUND
;
2421 SAFE_SYSFREESTRING(*pszDefaultAction
);
2422 *pszDefaultAction
= SysAllocString(m_pszActionDescription
);
2426 long lVal
= varChild
.lVal
;
2427 varChild
.lVal
= CHILDID_SELF
;
2428 IMAccessible
*pChild
= this->GetChildInterface(lVal
);
2431 return pChild
->get_accDefaultAction(varChild
,pszDefaultAction
);
2435 LEAVE_PROTECTED_BLOCK
2439 * AT call this method to operate application
2440 * @param varChild, the child id of the action object.
2441 * @return S_OK if successful.
2443 COM_DECLSPEC_NOTHROW HRESULT STDMETHODCALLTYPE
CMAccessible::accDoDefaultAction(VARIANT varChild
)
2447 ENTER_PROTECTED_BLOCK
2449 if( varChild
.vt
!= VT_I4
)
2450 return E_INVALIDARG
;
2451 if (!m_xAction
.is())
2453 if (m_xAction
->getAccessibleActionCount() == 0)
2456 if(varChild
.lVal
==CHILDID_SELF
)
2458 if (m_xAction
->getAccessibleActionCount() > 0)
2459 m_xAction
->doAccessibleAction(0);
2463 long lVal
= varChild
.lVal
;
2464 varChild
.lVal
= CHILDID_SELF
;
2465 IMAccessible
*pChild
= this->GetChildInterface(lVal
);
2468 return pChild
->accDoDefaultAction( varChild
);
2470 LEAVE_PROTECTED_BLOCK
2474 * UNO set description information for action to COM.
2475 * @param szAction, the action description of the current object.
2476 * @return S_OK if successful.
2478 COM_DECLSPEC_NOTHROW STDMETHODIMP
CMAccessible::Put_ActionDescription( const OLECHAR
* szAction
)
2480 // internal IMAccessible - no mutex meeded
2482 ENTER_PROTECTED_BLOCK
2485 if(szAction
== nullptr)
2487 return E_INVALIDARG
;
2489 SAFE_SYSFREESTRING(m_pszActionDescription
);
2490 m_pszActionDescription
= SysAllocString( szAction
);
2493 LEAVE_PROTECTED_BLOCK
2496 BOOL
CMAccessible::GetXInterfaceFromXAccessible(XAccessible
* pXAcc
, XInterface
** ppXI
, int index
)
2498 Reference
< XAccessibleContext
> pRContext
;
2503 QUERYXINTERFACE(AccessibleComponent
)
2506 QUERYXINTERFACE(AccessibleText
)
2508 case XI_EDITABLETEXT
:
2509 QUERYXINTERFACE(AccessibleEditableText
)
2512 QUERYXINTERFACE(AccessibleTable
)
2515 QUERYXINTERFACE(AccessibleSelection
)
2517 case XI_EXTENDEDCOMP
:
2518 QUERYXINTERFACE(AccessibleExtendedComponent
)
2521 QUERYXINTERFACE(AccessibleKeyBinding
)
2524 QUERYXINTERFACE(AccessibleAction
)
2527 QUERYXINTERFACE(AccessibleValue
)
2530 QUERYXINTERFACE(AccessibleHypertext
)
2533 QUERYXINTERFACE(AccessibleHyperlink
)
2536 QUERYXINTERFACE(AccessibleImage
)
2545 template<typename T
> static HRESULT
2546 createAggInstance(CMAccessible
&rOuter
, void ** ppvObject
)
2548 // Note: CComAggObject has special handling for IUnknown - must
2549 // query for that when creating it! Otherwise we get a T member of it
2550 // which will redirect QueryInterface back to CMAccessible infinitely.
2551 // (CComAggObject has its own ref-count too which is not a problem
2552 // since it is inserted in m_containedObjects.)
2553 return CComCreator
< CComAggObject
<T
> >::CreateInstance(
2554 rOuter
.GetControllingUnknown(), IID_IUnknown
, ppvObject
);
2557 typedef HRESULT (AggCreatorFunc
)(CMAccessible
&, void **);
2562 AggCreatorFunc
* pfnCreateInstance
;
2566 static AggMapEntry g_CMAccessible_AggMap
[] = {
2567 { &IID_IAccessibleComponent
, &createAggInstance
<CAccComponent
>, XI_COMPONENT
},
2568 { &IID_IAccessibleText
, &createAggInstance
<CAccText
>, XI_TEXT
},
2569 { &IID_IAccessibleEditableText
, &createAggInstance
<CAccEditableText
>, XI_EDITABLETEXT
},
2570 { &IID_IAccessibleImage
, &createAggInstance
<CAccImage
>, XI_IMAGE
},
2571 { &IID_IAccessibleTable
, &createAggInstance
<CAccTable
>, XI_TABLE
},
2572 { &IID_IAccessibleAction
, &createAggInstance
<CAccAction
>, XI_ACTION
},
2573 { &IID_IAccessibleValue
, &createAggInstance
<CAccValue
>, XI_VALUE
},
2574 { &IID_IAccessibleHypertext
, &createAggInstance
<CAccHypertext
>, XI_HYPERTEXT
},
2575 { &IID_IAccessibleHyperlink
, &createAggInstance
<CAccHyperLink
>, XI_HYPERLINK
},
2576 { nullptr, nullptr, 0 },
2580 HRESULT WINAPI
CMAccessible::SmartQI(void* /*pv*/, REFIID iid
, void** ppvObject
)
2582 ENTER_PROTECTED_BLOCK
2585 if (InlineIsEqualGUID(iid
,IID_IAccIdentity
) ||
2586 InlineIsEqualGUID(iid
,IID_IStdMarshalInfo
) ||
2587 InlineIsEqualGUID(iid
,IID_IMarshal
) ||
2588 InlineIsEqualGUID(iid
,IID_IExternalConnection
)||
2589 InlineIsEqualGUID(iid
,IID_IOleWindow
))
2594 AggMapEntry
* pMap
= &g_CMAccessible_AggMap
[0];
2595 while(pMap
&& pMap
->piid
)
2597 if (InlineIsEqualGUID(iid
, *pMap
->piid
))
2601 XInterface
* pXI
= nullptr;
2602 BOOL bFound
= GetXInterfaceFromXAccessible(m_xAccessible
.get(),
2603 &pXI
, pMap
->XIFIndex
);
2609 XGUIDToComObjHash::iterator pIndTemp
= m_containedObjects
.find( iid
);
2610 if ( pIndTemp
!= m_containedObjects
.end() )
2612 return pIndTemp
->second
.p
->QueryInterface( iid
, ppvObject
);
2616 HRESULT hr
= pMap
->pfnCreateInstance(*this, ppvObject
);
2620 m_containedObjects
.emplace(*pMap
->piid
, static_cast<IUnknown
*>(*ppvObject
));
2621 IUNOXWrapper
* wrapper
= nullptr;
2622 static_cast<IUnknown
*>(*ppvObject
)->QueryInterface(IID_IUNOXWrapper
, reinterpret_cast<void**>(&wrapper
));
2625 wrapper
->put_XInterface(
2626 reinterpret_cast<hyper
>(m_xAccessible
.get()));
2638 LEAVE_PROTECTED_BLOCK
2642 CMAccessible::get_IAccessibleFromXAccessible(XAccessible
* pXAcc
, IAccessible
**ppIA
)
2655 isGet
= g_pAgent
->GetIAccessibleFromXAccessible(pXAcc
, ppIA
);
2669 OUString
CMAccessible::get_StringFromAny(Any
const & pAny
)
2671 switch(pAny
.getValueTypeClass())
2673 case TypeClass_CHAR
:
2677 return OUString::number(val
);
2679 case TypeClass_BOOLEAN
:
2683 return OUString::number(int(val
));
2685 case TypeClass_BYTE
:
2689 return OUString::number(val
);
2691 case TypeClass_SHORT
:
2695 return OUString::number(val
);
2697 case TypeClass_UNSIGNED_SHORT
:
2701 return OUString::number(val
);
2703 case TypeClass_LONG
:
2707 return OUString::number(val
);
2709 case TypeClass_UNSIGNED_LONG
:
2713 return OUString::number(val
);
2715 case TypeClass_FLOAT
:
2719 return OUString::number(val
);
2721 case TypeClass_DOUBLE
:
2725 return OUString::number(val
);
2727 case TypeClass_STRING
:
2733 case TypeClass_SEQUENCE
:
2735 if(pAny
.getValueType() == cppu::UnoType
<Sequence
< OUString
>>::get())
2737 Sequence
< OUString
> val
;
2740 OUStringBuffer pString
;
2742 int count
= val
.getLength();
2744 for( int iIndex
= 0;iIndex
< count
;iIndex
++ )
2746 pString
.append(val
[iIndex
]);
2748 return pString
.makeStringAndClear();
2750 else if (pAny
.getValueType() == cppu::UnoType
<Sequence
< css::style::TabStop
>>::get())
2752 Sequence
< css::style::TabStop
> val
;
2754 int count
= val
.getLength();
2757 for( int iIndex
= 0;iIndex
< count
;iIndex
++ )
2759 css::style::TabStop sigleVal
= val
[iIndex
];
2761 buf
.append("Position=");
2762 buf
.append(sigleVal
.Position
);
2763 buf
.append(",TabAlign=");
2764 buf
.append(sal_Int32(sigleVal
.Alignment
));
2767 buf
.append("DecimalChar=");
2768 if(sigleVal
.DecimalChar
==';' || sigleVal
.DecimalChar
== ':' || sigleVal
.DecimalChar
== ',' ||
2769 sigleVal
.DecimalChar
== '=' || sigleVal
.DecimalChar
== '\\')
2771 buf
.append(sigleVal
.DecimalChar
);
2774 buf
.append("FillChar=");
2775 if(sigleVal
.FillChar
==';' || sigleVal
.FillChar
== ':' || sigleVal
.FillChar
== ',' ||
2776 sigleVal
.FillChar
== '=' || sigleVal
.FillChar
== '\\')
2778 buf
.append(sigleVal
.FillChar
);
2781 return buf
.makeStringAndClear();
2785 case TypeClass_ENUM
:
2787 if (pAny
.getValueType() == cppu::UnoType
<css::awt::FontSlant
>::get())
2789 css::awt::FontSlant val
;
2791 return OUString::number(sal_Int32(val
));
2795 case TypeClass_STRUCT
:
2797 if (pAny
.getValueType() == cppu::UnoType
<css::style::LineSpacing
>::get())
2799 css::style::LineSpacing val
;
2801 return "Mode=" + OUString::number(val
.Mode
) + ",Height="
2802 + OUString::number(val
.Height
) + ",";
2804 else if (pAny
.getValueType() == cppu::UnoType
<css::accessibility::TextSegment
>::get())
2806 css::accessibility::TextSegment val
;
2808 return val
.SegmentText
;
2812 case TypeClass_VOID
:
2813 case TypeClass_HYPER
:
2814 case TypeClass_UNSIGNED_HYPER
:
2815 case TypeClass_TYPE
:
2817 case TypeClass_TYPEDEF
:
2818 case TypeClass_EXCEPTION
:
2819 case TypeClass_INTERFACE
:
2820 case TypeClass_SERVICE
:
2821 case TypeClass_MODULE
:
2822 case TypeClass_INTERFACE_METHOD
:
2823 case TypeClass_INTERFACE_ATTRIBUTE
:
2824 case TypeClass_UNKNOWN
:
2825 case TypeClass_PROPERTY
:
2826 case TypeClass_CONSTANT
:
2827 case TypeClass_CONSTANTS
:
2828 case TypeClass_SINGLETON
:
2836 OUString
CMAccessible::get_String4Numbering(const Any
& pAny
, sal_Int16 numberingLevel
,const OUString
& numberingPrefix
)
2838 Reference
< css::container::XIndexReplace
> pXIndex
;
2839 if((pAny
>>=pXIndex
) && (numberingLevel
!=-1))//numbering level is -1,means invalid value
2841 Any aAny
= pXIndex
->getByIndex(numberingLevel
);
2842 Sequence
< css::beans::PropertyValue
> aProps
;
2844 const css::beans::PropertyValue
* pPropArray
= aProps
.getConstArray();
2845 sal_Int32 nCount
= aProps
.getLength();
2846 OUStringBuffer
buf("Numbering:NumberingLevel=");
2847 buf
.append(sal_Int32(numberingLevel
));
2849 for( sal_Int32 i
=0; i
<nCount
; i
++ )
2851 css::beans::PropertyValue rProp
= pPropArray
[i
];
2852 if( (rProp
.Name
== "BulletChar" ) ||
2853 (rProp
.Name
== "NumberingType" ))
2855 buf
.append(rProp
.Name
);
2857 auto const pTemp
= CMAccessible::get_StringFromAny(rProp
.Value
);
2861 if(rProp
.Name
== "NumberingType")
2863 if(numberingPrefix
.getLength()!=0)
2865 buf
.append("NumberingPrefix=");
2866 buf
.append(numberingPrefix
);
2871 return buf
.makeStringAndClear();
2874 //Because now have three types numbering level:
2875 //1.real numbering list,numbering level>=0 and numbering Rule !=NULL;
2876 //2.common paragraph, numbering level >=0, and numbering Rule == NULL;
2877 //3.TOC paragraph, numbering level >0, and numbering Rule ==NULL;
2878 // IAText:numberinglevel base on 0, but TOC's level base on 1,
2879 // so NumberingLevel value will be decreased 1 in bridge code.
2880 else if(numberingLevel
>0)
2882 return "Numbering:NumberingLevel=" + OUString::number(numberingLevel
-1) + ",NumberingType=4,NumberingPrefix=,";
2886 return "Numbering:";
2890 void CMAccessible::ConvertAnyToVariant(const css::uno::Any
&rAnyVal
, VARIANT
*pvData
)
2892 if(rAnyVal
.hasValue())
2894 // Clear VARIANT variable.
2895 VariantClear(pvData
);
2897 // Set value according to value type.
2898 switch(rAnyVal
.getValueTypeClass())
2900 case TypeClass_CHAR
:
2901 pvData
->vt
= VT_UI1
;
2902 memcpy(&pvData
->bVal
, rAnyVal
.getValue(), sizeof(sal_Char
));
2905 case TypeClass_BOOLEAN
:
2907 bool bBoolean(false);
2908 rAnyVal
>>= bBoolean
;
2909 pvData
->vt
= VT_BOOL
;
2910 pvData
->boolVal
= VARIANT_BOOL(bBoolean
); // boolVal is a VARIANT_BOOL, a 16bit field
2913 case TypeClass_BYTE
:
2914 pvData
->vt
= VT_UI1
;
2915 memcpy(&pvData
->bVal
, rAnyVal
.getValue(), sizeof(sal_Int8
));
2918 case TypeClass_SHORT
:
2920 memcpy(&pvData
->iVal
, rAnyVal
.getValue(), sizeof(sal_Int16
));
2923 case TypeClass_UNSIGNED_SHORT
:
2925 memcpy(&pvData
->iVal
, rAnyVal
.getValue(), sizeof(sal_uInt16
));
2928 case TypeClass_LONG
:
2930 memcpy(&pvData
->lVal
, rAnyVal
.getValue(), sizeof(sal_Int32
));
2933 case TypeClass_UNSIGNED_LONG
:
2935 memcpy(&pvData
->lVal
, rAnyVal
.getValue(), sizeof(sal_uInt32
));
2938 case TypeClass_FLOAT
:
2940 memcpy(&pvData
->fltVal
, rAnyVal
.getValue(), sizeof(float));
2943 case TypeClass_DOUBLE
:
2945 memcpy(&pvData
->dblVal
, rAnyVal
.getValue(), sizeof(double));
2948 case TypeClass_STRING
:
2950 pvData
->vt
= VT_BSTR
;
2953 pvData
->bstrVal
= SysAllocString(o3tl::toW(val
.getStr()));
2957 case TypeClass_VOID
:
2958 case TypeClass_HYPER
:
2959 case TypeClass_UNSIGNED_HYPER
:
2960 case TypeClass_TYPE
:
2962 case TypeClass_ENUM
:
2963 case TypeClass_TYPEDEF
:
2964 case TypeClass_STRUCT
:
2965 case TypeClass_EXCEPTION
:
2966 case TypeClass_SEQUENCE
:
2967 case TypeClass_INTERFACE
:
2969 Reference
< XAccessible
> pXAcc
;
2970 if(rAnyVal
>>= pXAcc
)
2974 IAccessible
* pIAcc
= nullptr;
2975 get_IAccessibleFromXAccessible(pXAcc
.get(), &pIAcc
);
2976 if(pIAcc
== nullptr)
2978 Reference
< XAccessibleContext
> pXAccContext
= pXAcc
->getAccessibleContext();
2979 g_pAgent
->InsertAccObj(pXAcc
.get(),pXAccContext
->getAccessibleParent().get());
2980 get_IAccessibleFromXAccessible(pXAcc
.get(), &pIAcc
);
2986 pvData
->vt
= VT_UNKNOWN
;
2987 pvData
->pdispVal
= static_cast<IAccessible2
*>(pIAcc
);
2994 case TypeClass_SERVICE
:
2995 case TypeClass_MODULE
:
2996 case TypeClass_INTERFACE_METHOD
:
2997 case TypeClass_INTERFACE_ATTRIBUTE
:
2998 case TypeClass_UNKNOWN
:
2999 case TypeClass_PROPERTY
:
3000 case TypeClass_CONSTANT
:
3001 case TypeClass_CONSTANTS
:
3002 case TypeClass_SINGLETON
:
3003 case TypeClass::TypeClass_MAKE_FIXED_SIZE
:
3004 // Output the type string, if there is other uno value type.
3005 pvData
->vt
= VT_BSTR
;
3006 pvData
->bstrVal
= SysAllocString(o3tl::toW(rAnyVal
.getValueTypeName().getStr()));
3015 VariantClear(pvData
);
3019 COM_DECLSPEC_NOTHROW STDMETHODIMP
CMAccessible::Get_XAccChildID(long* childID
)
3021 // internal IMAccessible - no mutex meeded
3023 if(childID
== nullptr)
3027 *childID
= m_dChildID
;
3031 COM_DECLSPEC_NOTHROW STDMETHODIMP
CMAccessible:: get_states(AccessibleStates __RPC_FAR
*states
)
3035 ENTER_PROTECTED_BLOCK
3038 if (!m_xContext
.is())
3041 Reference
<XAccessibleStateSet
> const pRStateSet
=
3042 m_xContext
.get()->getAccessibleStateSet();
3043 if(!pRStateSet
.is())
3047 Sequence
<short> pStates
= pRStateSet
->getStates();
3050 long count
= pStates
.getLength() ;
3052 for( int i
= 0; i
< count
; i
++ )
3054 for( std::size_t j
= 0; j
< SAL_N_ELEMENTS(UNO_STATES
); j
++ )
3056 if( pStates
[i
] == UNO_STATES
[j
] )
3058 *states
|= IA2_STATES
[j
];
3066 LEAVE_PROTECTED_BLOCK
3069 // return the UNO roles
3070 COM_DECLSPEC_NOTHROW STDMETHODIMP
CMAccessible:: get_extendedRole( BSTR __RPC_FAR
* )
3075 COM_DECLSPEC_NOTHROW STDMETHODIMP
CMAccessible:: get_localizedExtendedRole( BSTR __RPC_FAR
* )
3080 COM_DECLSPEC_NOTHROW STDMETHODIMP
CMAccessible:: get_nExtendedStates( long __RPC_FAR
* )
3086 COM_DECLSPEC_NOTHROW STDMETHODIMP
CMAccessible:: get_localizedExtendedStates( long, BSTR __RPC_FAR
*__RPC_FAR
*, long __RPC_FAR
*)
3092 COM_DECLSPEC_NOTHROW STDMETHODIMP
CMAccessible:: get_indexInParent( long __RPC_FAR
*accParentIndex
)
3094 ENTER_PROTECTED_BLOCK
3097 if(accParentIndex
== nullptr)
3098 return E_INVALIDARG
;
3100 if (!m_xContext
.is())
3103 *accParentIndex
= m_xContext
.get()->getAccessibleIndexInParent();
3107 LEAVE_PROTECTED_BLOCK
3109 COM_DECLSPEC_NOTHROW STDMETHODIMP
CMAccessible:: get_locale( IA2Locale __RPC_FAR
*locale
)
3111 ENTER_PROTECTED_BLOCK
3113 if(locale
== nullptr)
3114 return E_INVALIDARG
;
3116 if (!m_xContext
.is())
3119 css::lang::Locale unoLoc
= m_xContext
.get()->getLocale();
3120 locale
->language
= SysAllocString(o3tl::toW(unoLoc
.Language
.getStr()));
3121 locale
->country
= SysAllocString(o3tl::toW(unoLoc
.Country
.getStr()));
3122 locale
->variant
= SysAllocString(o3tl::toW(unoLoc
.Variant
.getStr()));
3126 LEAVE_PROTECTED_BLOCK
3129 COM_DECLSPEC_NOTHROW STDMETHODIMP
CMAccessible:: get_appName( BSTR __RPC_FAR
*name
)
3133 ENTER_PROTECTED_BLOCK
3136 return E_INVALIDARG
;
3138 *name
= SysAllocString(OLESTR("Hannover"));
3140 LEAVE_PROTECTED_BLOCK
3142 COM_DECLSPEC_NOTHROW STDMETHODIMP
CMAccessible:: get_appVersion(BSTR __RPC_FAR
*version
)
3146 ENTER_PROTECTED_BLOCK
3148 if(version
== nullptr)
3149 return E_INVALIDARG
;
3150 *version
=SysAllocString(OLESTR("3.0"));
3152 LEAVE_PROTECTED_BLOCK
3154 COM_DECLSPEC_NOTHROW STDMETHODIMP
CMAccessible:: get_toolkitName(BSTR __RPC_FAR
*name
)
3158 ENTER_PROTECTED_BLOCK
3161 return E_INVALIDARG
;
3162 *name
= SysAllocString(OLESTR(" "));
3164 LEAVE_PROTECTED_BLOCK
3166 COM_DECLSPEC_NOTHROW STDMETHODIMP
CMAccessible:: get_toolkitVersion(BSTR __RPC_FAR
*version
)
3170 ENTER_PROTECTED_BLOCK
3172 if(version
== nullptr)
3173 return E_INVALIDARG
;
3174 *version
= SysAllocString(OLESTR(" "));
3176 LEAVE_PROTECTED_BLOCK
3180 COM_DECLSPEC_NOTHROW STDMETHODIMP
CMAccessible::get_attributes(/*[out]*/ BSTR
*pAttr
)
3184 ENTER_PROTECTED_BLOCK
3187 if (!m_xAccessible
.is())
3190 Reference
<XAccessibleContext
> pRContext
= m_xAccessible
->getAccessibleContext();
3191 if( !pRContext
.is() )
3195 Reference
<XAccessibleExtendedAttributes
> pRXI(pRContext
,UNO_QUERY
);
3200 css::uno::Reference
<css::accessibility::XAccessibleExtendedAttributes
> pRXAttr
;
3201 pRXAttr
= pRXI
.get();
3202 css::uno::Any anyVal
= pRXAttr
->getExtendedAttributes();
3208 SAFE_SYSFREESTRING(*pAttr
);
3209 *pAttr
= SysAllocString(o3tl::toW(val
.getStr()));
3213 LEAVE_PROTECTED_BLOCK
3216 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */