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 <vcl/svapp.hxx>
48 #include <com/sun/star/accessibility/XAccessibleText.hpp>
49 #include <com/sun/star/accessibility/XAccessibleEditableText.hpp>
50 #include <com/sun/star/accessibility/XAccessibleImage.hpp>
51 #include <com/sun/star/accessibility/XAccessibleTable.hpp>
52 #include <com/sun/star/accessibility/XAccessibleExtendedComponent.hpp>
53 #include <com/sun/star/accessibility/XAccessibleAction.hpp>
54 #include <com/sun/star/accessibility/XAccessibleKeyBinding.hpp>
55 #include <com/sun/star/accessibility/XAccessibleHyperText.hpp>
56 #include <com/sun/star/accessibility/XAccessibleHyperlink.hpp>
57 #include <com/sun/star/accessibility/XAccessibleRelationSet.hpp>
58 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
59 #include <com/sun/star/accessibility/AccessibleRole.hpp>
60 #include <com/sun/star/accessibility/XAccessibleGroupPosition.hpp>
61 #include <com/sun/star/accessibility/XAccessibleValue.hpp>
62 #include <com/sun/star/accessibility/XAccessibleExtendedAttributes.hpp>
63 #include <com/sun/star/style/LineSpacing.hpp>
64 #include <com/sun/star/style/TabStop.hpp>
65 #include <com/sun/star/container/XIndexReplace.hpp>
68 using namespace com::sun::star::uno
;
69 using namespace com::sun::star::accessibility
;
70 using namespace com::sun::star::accessibility::AccessibleStateType
;
72 enum XInterfaceIndex
{
76 XI_EDITABLETEXT
= 0x04,
79 XI_EXTENDEDCOMP
= 0x07,
89 // IA2 states mapping, and name
90 // maintenance the consistency, change one array, change the three all
93 IA2_STATE_ACTIVE
, // = 0x1;
94 IA2_STATE_ARMED
, // = 0x2;
95 IA2_STATE_DEFUNCT
, // = 0x4;
96 IA2_STATE_EDITABLE
, // = 0x8;
97 IA2_STATE_HORIZONTAL
, // = 0x10;
98 IA2_STATE_ICONIFIED
, // = 0x20;
99 IA2_STATE_INVALID_ENTRY
, // = 0x80;
100 IA2_STATE_MANAGES_DESCENDANTS
, // = 0x100;
101 IA2_STATE_MODAL
, // = 0x200;
102 IA2_STATE_MULTI_LINE
, // = 0x400;
103 IA2_STATE_OPAQUE
, // = 0x800;
104 IA2_STATE_REQUIRED
, // = 0x2000;
105 IA2_STATE_SELECTABLE_TEXT
, // = 0x3000;
106 IA2_STATE_SINGLE_LINE
, // = 0x4000;
107 IA2_STATE_STALE
, // = 0x8000;
108 IA2_STATE_SUPPORTS_AUTOCOMPLETION
, // = 0x10000;
109 IA2_STATE_TRANSIENT
, //= 0x20000;
110 IA2_STATE_VERTICAL
// = 0x40000;
119 ACTIVE
, // = (sal_Int16)1;
120 ARMED
, // = (sal_Int16)2;
121 DEFUNC
, // = (sal_Int16)5;
122 EDITABLE
, // = (sal_Int16)6;
123 HORIZONTAL
, // = (sal_Int16)12;
124 ICONIFIED
, // = (sal_Int16)13;
125 -1, //IA2_STATE_INVALID_ENTRY
126 MANAGES_DESCENDANTS
, // = (sal_Int16)15;
127 MODAL
, // = (sal_Int16)16;
128 MULTI_LINE
, // = (sal_Int16)17;
129 OPAQUE
, // = (sal_Int16)19;
130 -1, //IA2_STATE_REQUIRED
131 -1, //IA2_STATE_SELECTABLE_TEXT
132 SINGLE_LINE
, // = (sal_Int16)26;
133 STALE
, // = (sal_Int16)27;
134 -1, //IA2_STATE_SUPPORTS_AUTOCOMPLETION
135 TRANSIENT
, //IA2_STATE_TRANSIENT
136 VERTICAL
// = (sal_Int16)29;
139 using namespace com::sun::star::accessibility::AccessibleRole
;
142 #define QUERYXINTERFACE(ainterface) \
146 pRContext = pXAcc->getAccessibleContext(); \
147 if( !pRContext.is() ) \
151 Reference<X##ainterface> pRXI(pRContext,UNO_QUERY);\
156 *ppXI = (XInterface*)pRXI.get(); \
160 #define ISDESTROY() \
165 AccObjectManagerAgent
* CMAccessible::g_pAgent
= NULL
;
167 CMAccessible::CMAccessible():
170 m_pszActionDescription(NULL
),
173 m_pszDescription(NULL
),
176 m_dFocusChildID(UACC_NO_FOCUS
),
179 m_bRequiresSave(FALSE
)
181 m_sLocation
.m_dLeft
=0;
182 m_sLocation
.m_dTop
= 0;
183 m_sLocation
.m_dWidth
=0;
184 m_sLocation
.m_dHeight
=0;
185 CEnumVariant::Create(&m_pEnumVar
);
186 m_containedObjects
.clear();
189 CMAccessible::~CMAccessible()
195 SAFE_SYSFREESTRING(m_pszName
);
200 SAFE_SYSFREESTRING(m_pszValue
);
203 if(m_pszDescription
!=NULL
)
205 SAFE_SYSFREESTRING(m_pszDescription
);
206 m_pszDescription
=NULL
;
209 if(m_pszActionDescription
!=NULL
)
211 SAFE_SYSFREESTRING(m_pszActionDescription
);
212 m_pszActionDescription
=NULL
;
217 m_pIParent
->Release();
220 m_pEnumVar
->Release();
221 m_containedObjects
.clear();
225 * Returns the Parent IAccessible interface pointer to AT.
226 * It should add reference, and the client should release the component.
227 * It should return E_FAIL when the parent point is null.
228 * @param ppdispParent [in,out] used to return the parent interface point.
229 * when the point is null, should return null.
230 * @return S_OK if successful and E_FAIL if the m_pIParent is NULL.
232 STDMETHODIMP
CMAccessible::get_accParent(IDispatch
**ppdispParent
)
236 ENTER_PROTECTED_BLOCK
239 if(ppdispParent
== NULL
)
246 *ppdispParent
= m_pIParent
;
247 (*ppdispParent
)->AddRef();
252 HRESULT hr
= AccessibleObjectFromWindow(m_hwnd
, OBJID_WINDOW
, IID_IAccessible
, (void**)ppdispParent
);
253 if( ! SUCCEEDED( hr
) || ! ppdispParent
)
261 LEAVE_PROTECTED_BLOCK
265 * Returns child count of current COM object.
266 * @param pcountChildren [in,out] used to return the children count.
267 * @return S_OK if successful.
269 STDMETHODIMP
CMAccessible::get_accChildCount(long *pcountChildren
)
273 ENTER_PROTECTED_BLOCK
276 if(pcountChildren
== NULL
)
281 if (!m_xAccessible
.is())
284 Reference
<XAccessibleContext
> const pRContext
=
285 m_xAccessible
->getAccessibleContext();
288 *pcountChildren
= pRContext
->getAccessibleChildCount();
293 LEAVE_PROTECTED_BLOCK
297 * Returns child interface pointer for AT according to input child ID.
298 * @param varChild, vt member of varChild must be VT_I4,and lVal member stores the child ID,
299 * the child ID specify child index from 0 to children count, 0 stands for object self.
300 * @param ppdispChild, [in,out] use to return the child interface point.
301 * @return S_OK if successful and S_FALSE if failure.
303 STDMETHODIMP
CMAccessible::get_accChild(VARIANT varChild
, IDispatch
**ppdispChild
)
307 ENTER_PROTECTED_BLOCK
310 if(ppdispChild
== NULL
)
314 if(varChild
.vt
==VT_I4
)
316 //get child interface pointer due to child ID
317 if(varChild
.lVal
==CHILDID_SELF
)
323 *ppdispChild
= GetChildInterface(varChild
.lVal
);
324 if((*ppdispChild
) == NULL
)
326 (*ppdispChild
)->AddRef();
331 LEAVE_PROTECTED_BLOCK
335 * Returns the accessible name of the current COM object self or its one child to AT.
336 * @param varChild, vt member of varChild must be VT_I4,and lVal member stores the child ID,
337 * the child ID specify child index from 0 to children count, 0 stands for object self.
338 * @param pszName, [in,out] use to return the name of the proper object.
339 * @return S_OK if successful and S_FALSE if failure.
341 STDMETHODIMP
CMAccessible::get_accName(VARIANT varChild
, BSTR
*pszName
)
345 ENTER_PROTECTED_BLOCK
352 if(varChild
.vt
==VT_I4
)
354 if(varChild
.lVal
==CHILDID_SELF
)
356 SAFE_SYSFREESTRING(*pszName
);
357 *pszName
= SysAllocString(m_pszName
);
361 long lVal
= varChild
.lVal
;
362 varChild
.lVal
= CHILDID_SELF
;
363 IMAccessible
*pChild
= this->GetChildInterface(lVal
);
366 return pChild
->get_accName(varChild
,pszName
);
370 LEAVE_PROTECTED_BLOCK
374 * Returns the accessible value of the current COM object self or its one child to AT.
375 * @param varChild, vt member of varChild must be VT_I4,and lVal member stores the child ID,
376 * the child ID specify child index from 0 to children count, 0 stands for object self.
377 * @param pszValue, [in,out] use to return the value of the proper object.
378 * @return S_OK if successful and S_FALSE if failure.
380 STDMETHODIMP
CMAccessible::get_accValue(VARIANT varChild
, BSTR
*pszValue
)
384 ENTER_PROTECTED_BLOCK
387 if( pszValue
== NULL
)
391 if( varChild
.vt
==VT_I4
)
393 if(varChild
.lVal
==CHILDID_SELF
)
395 if(m_dState
& STATE_SYSTEM_PROTECTED
)
396 return E_ACCESSDENIED
;
398 if ( m_pszValue
!=NULL
&& wcslen(m_pszValue
) == 0 )
401 SAFE_SYSFREESTRING(*pszValue
);
402 *pszValue
= SysAllocString(m_pszValue
);
406 long lVal
= varChild
.lVal
;
407 varChild
.lVal
= CHILDID_SELF
;
408 IMAccessible
*pChild
= this->GetChildInterface(lVal
);
411 return pChild
->get_accValue(varChild
,pszValue
);
415 LEAVE_PROTECTED_BLOCK
419 * Returns the accessible description of the current COM object self or its one child to AT.
420 * @param varChild, vt member of varChild must be VT_I4,and lVal member stores the child ID,
421 * the child ID specify child index from 0 to children count, 0 stands for object self.
422 * @param pszDescription, [in,out] use to return the description of the proper object.
423 * @return S_OK if successful and E_FAIL if failure.
425 STDMETHODIMP
CMAccessible::get_accDescription(VARIANT varChild
, BSTR
*pszDescription
)
429 ENTER_PROTECTED_BLOCK
432 if(pszDescription
== NULL
)
436 if(varChild
.vt
==VT_I4
)
438 if(varChild
.lVal
==CHILDID_SELF
)
440 SAFE_SYSFREESTRING(*pszDescription
);
441 *pszDescription
= SysAllocString(m_pszDescription
);
445 long lVal
= varChild
.lVal
;
446 varChild
.lVal
= CHILDID_SELF
;
447 IMAccessible
*pChild
= this->GetChildInterface(lVal
);
450 return pChild
->get_accDescription(varChild
,pszDescription
);
454 LEAVE_PROTECTED_BLOCK
458 * Returns the accessible role of the current COM object self or its one child to AT.
459 * @param varChild, vt member of varChild must be VT_I4,and lVal member stores the child ID,
460 * the child ID specify child index from 0 to children count, 0 stands for object self.
461 * @param pvarRole, [in,out] use to return the role of the proper object.
462 * @return S_OK if successful and S_FALSE if failure.
464 STDMETHODIMP
CMAccessible::get_accRole(VARIANT varChild
, VARIANT
*pvarRole
)
468 ENTER_PROTECTED_BLOCK
475 if(varChild
.vt
== VT_I4
)
478 if(varChild
.lVal
== CHILDID_SELF
)
480 if( m_iRole
< IA2_ROLE_CAPTION
)
482 VariantInit(pvarRole
);
483 pvarRole
->vt
= VT_I4
;
484 pvarRole
->lVal
= m_iRole
;
488 VariantInit(pvarRole
);
489 pvarRole
->vt
= VT_I4
;
490 pvarRole
->lVal
= ROLE_SYSTEM_CLIENT
;
496 long lVal
= varChild
.lVal
;
497 varChild
.lVal
= CHILDID_SELF
;
498 IMAccessible
*pChild
= this->GetChildInterface(lVal
);
501 return pChild
->get_accRole(varChild
,pvarRole
);
505 LEAVE_PROTECTED_BLOCK
509 * Returns the accessible state of the current COM object self or its one child to AT.
510 * @param varChild, vt member of varChild must be VT_I4,and lVal member stores the child ID,
511 * the child ID specify child index from 0 to children count, 0 stands for object self.
512 * @param pvarState, [in,out] use to return the state of the proper object.
513 * @return S_OK if successful and S_FALSE if failure.
515 STDMETHODIMP
CMAccessible::get_accState(VARIANT varChild
, VARIANT
*pvarState
)
519 ENTER_PROTECTED_BLOCK
522 if(pvarState
== NULL
)
526 if(varChild
.vt
==VT_I4
)
528 if(varChild
.lVal
== CHILDID_SELF
)
530 if (m_xAccessible
.is())
532 Reference
<XAccessibleContext
> const pContext
=
533 m_xAccessible
->getAccessibleContext();
536 // add the STATE_SYSTEM_LINKED state
537 Reference
< XAccessibleHypertext
> pRHypertext(pContext
,UNO_QUERY
);
540 if( pRHypertext
->getHyperLinkCount() > 0 )
541 m_dState
|= STATE_SYSTEM_LINKED
;
543 m_dState
&= ~STATE_SYSTEM_LINKED
;
546 m_dState
&= ~STATE_SYSTEM_LINKED
;
550 VariantInit(pvarState
);
551 pvarState
->vt
= VT_I4
;
552 pvarState
->lVal
= m_dState
;
556 long lVal
= varChild
.lVal
;
557 varChild
.lVal
= CHILDID_SELF
;
558 IMAccessible
*pChild
= this->GetChildInterface(lVal
);
561 return pChild
->get_accState(varChild
,pvarState
);
565 LEAVE_PROTECTED_BLOCK
569 * Returns the accessible helpString of the current COM object self or its one child to AT.
570 * @param varChild, vt member of varChild must be VT_I4,and lVal member stores the child ID,
571 * the child ID specify child index from 0 to children count, 0 stands for object self.
572 * @param pszHelp, [in,out] use to return the helpString of the proper object.
573 * @return S_OK if successful and E_FAIL if failure.
575 STDMETHODIMP
CMAccessible::get_accHelp(VARIANT
, BSTR
*)
581 * Returns the accessible HelpTopic of the current COM object self or its one child to AT.
582 * @param varChild, vt member of varChild must be VT_I4,and lVal member stores the child ID,
583 * the child ID specify child index from 0 to children count, 0 stands for object self.
584 * @param pszHelpFile, [in,out] use to return the HelpTopic of the proper object.
585 * @param pidTopic, use to return the HelpTopic ID of the proper object.
586 * @return S_OK if successful and E_FAIL if failure.
587 * Not implemented yet
589 STDMETHODIMP
CMAccessible::get_accHelpTopic(BSTR
*, VARIANT
, long *)
594 static void GetMnemonicChar( const ::rtl::OUString
& aStr
, WCHAR
* wStr
)
596 int nLen
= aStr
.pData
->length
;
598 WCHAR
* text
= aStr
.pData
->buffer
;
602 if ( text
[i
] == L
'~' )
603 if ( text
[i
+1] != L
'~' )
613 * Returns the accessible keyboard shortcut of the current COM object self or its one child to AT.
614 * @param varChild, vt member of varChild must be VT_I4,and lVal member stores the child ID,
615 * the child ID specify child index from 0 to children count, 0 stands for object self.
616 * @param pszKeyboardShortcut, [in,out] use to return the kbshortcut of the proper object.
617 * @return S_OK if successful and E_FAIL if failure.
619 STDMETHODIMP
CMAccessible::get_accKeyboardShortcut(VARIANT varChild
, BSTR
*pszKeyboardShortcut
)
623 ENTER_PROTECTED_BLOCK
627 if(pszKeyboardShortcut
== NULL
)
632 if(varChild
.vt
==VT_I4
)
634 if(varChild
.lVal
== CHILDID_SELF
)
636 if (m_xAccessible
.is())
638 Reference
<XAccessibleContext
> const pRContext
=
639 m_xAccessible
->getAccessibleContext();
640 if( !pRContext
.is() )
643 Reference
<XAccessibleAction
> pRXI(pRContext
,UNO_QUERY
);
645 OLECHAR wString
[64]={0};
647 if( pRXI
.is() && pRXI
->getAccessibleActionCount() >= 1)
649 Reference
< XAccessibleKeyBinding
> binding
= pRXI
->getAccessibleActionKeyBinding(0);
652 long nCount
= binding
->getAccessibleKeyBindingCount();
655 CAccAction::GetkeyBindingStrByXkeyBinding( binding
->getAccessibleKeyBinding(0),wString
);
661 Reference
<XAccessibleRelationSet
> pRrelationSet
= pRContext
->getAccessibleRelationSet();
662 if(!pRrelationSet
.is())
667 long nRelCount
= pRrelationSet
->getRelationCount();
669 // Modified by Steve Yin, for SODC_1552
670 if( /*nRelCount <= 0 &&*/ m_iRole
== ROLE_SYSTEM_TEXT
)
672 VARIANT varParentRole
;
673 VariantInit( &varParentRole
);
675 m_pIParent
->get_accRole(varChild
, &varParentRole
);
677 if( m_pIParent
&& varParentRole
.lVal
== ROLE_SYSTEM_COMBOBOX
) // edit in comboBox
679 m_pIParent
->get_accKeyboardShortcut(varChild
, pszKeyboardShortcut
);
684 AccessibleRelation
*paccRelation
= NULL
;
685 AccessibleRelation accRelation
;
686 for(int i
=0; i
<nRelCount
; i
++)
688 if( pRrelationSet
->getRelation(i
).RelationType
== 6 )
690 accRelation
= pRrelationSet
->getRelation(i
);
691 paccRelation
= &accRelation
;
695 if(paccRelation
== NULL
)
698 Sequence
< Reference
< XInterface
> > xTargets
= paccRelation
->TargetSet
;
699 Reference
<XInterface
> pRAcc
= xTargets
[0];
701 XAccessible
* pXAcc
= (XAccessible
*)pRAcc
.get();
703 Reference
<XAccessibleContext
> pRLebelContext
= pXAcc
->getAccessibleContext();
704 if(!pRLebelContext
.is())
707 pRrelationSet
= pRLebelContext
->getAccessibleRelationSet();
708 nRelCount
= pRrelationSet
->getRelationCount();
711 for(int j
=0; j
<nRelCount
; j
++)
713 if( pRrelationSet
->getRelation(j
).RelationType
== 5 )
715 accRelation
= pRrelationSet
->getRelation(j
);
716 paccRelation
= &accRelation
;
722 xTargets
= paccRelation
->TargetSet
;
724 if (m_xAccessible
.get() != (XAccessible
*)pRAcc
.get())
728 Reference
<XAccessibleExtendedComponent
> pRXIE(pRLebelContext
,UNO_QUERY
);
732 ::rtl::OUString ouStr
= pRXIE
->getTitledBorderText();
733 WCHAR key
[2] = {NULL
};
734 GetMnemonicChar(ouStr
, key
);
737 wcscat(wString
, L
"Alt+");
738 wcscat(wString
, key
);
744 SAFE_SYSFREESTRING(*pszKeyboardShortcut
);
745 *pszKeyboardShortcut
= SysAllocString(wString
);
755 long lVal
= varChild
.lVal
;
756 varChild
.lVal
= CHILDID_SELF
;
757 IMAccessible
*pChild
= this->GetChildInterface(lVal
);
761 return pChild
->get_accKeyboardShortcut(varChild
,pszKeyboardShortcut
);
765 LEAVE_PROTECTED_BLOCK
769 * Returns the current focused child to AT.
770 * @param pvarChild, [in,out] vt member of pvarChild must be VT_I4,and lVal member stores the child ID,
771 * the child ID specify child index from 0 to children count, 0 stands for object self.
772 * @return S_OK if successful and E_FAIL if failure.
774 STDMETHODIMP
CMAccessible::get_accFocus(VARIANT
*pvarChild
)
778 ENTER_PROTECTED_BLOCK
781 if(pvarChild
== NULL
)
785 if( m_dFocusChildID
==UACC_NO_FOCUS
)
787 pvarChild
->vt
= VT_EMPTY
;//no focus on the object and its children
790 //if the descendant of current object has focus indicated by m_dFocusChildID, return the IDispatch of this focused object
793 IMAccessible
* pIMAcc
= NULL
;
794 g_pAgent
->GetIAccessibleFromResID(m_dFocusChildID
,&pIMAcc
);
796 pvarChild
->vt
= VT_DISPATCH
;
797 pvarChild
->pdispVal
= pIMAcc
;
802 LEAVE_PROTECTED_BLOCK
806 * Returns the selection of the current COM object to AT.
807 * @param pvarChildren,[in,out]
808 * if selection num is 0,return VT_EMPTY for vt,
809 * if selection num is 1,return VT_I4 for vt,and child index for lVal
810 * if selection num >1,return VT_UNKNOWN for vt, and IEnumVariant* for punkVal
811 * @return S_OK if successful and S_FALSE if failure.
813 STDMETHODIMP
CMAccessible::get_accSelection(VARIANT
*pvarChildren
)
817 ENTER_PROTECTED_BLOCK
820 if(pvarChildren
== NULL
)
824 switch(m_pEnumVar
->GetCountOfElements())
827 pvarChildren
->vt
= VT_EMPTY
;
832 VariantInit(&varTmp
[0]);
833 m_pEnumVar
->Next(1,varTmp
,&count
);
836 pvarChildren
->vt
= VT_I4
;
837 pvarChildren
->lVal
= varTmp
[0].lVal
;
838 VariantClear(&varTmp
[0]);
842 pvarChildren
->vt
= VT_UNKNOWN
;
843 m_pEnumVar
->AddRef();
844 pvarChildren
->punkVal
= m_pEnumVar
;
849 LEAVE_PROTECTED_BLOCK
853 * Returns the location of the current COM object self or its one child to AT.
854 * @param varChild, vt member of varChild must be VT_I4,and lVal member stores the child ID,
855 * the child ID specify child index from 0 to children count, 0 stands for object self.
856 * @param pxLeft, [in,out] use to return the x-coordination of the proper object.
857 * @param pyTop, [in,out] use to return the y-coordination of the proper object.
858 * @param pcxWidth, [in,out] use to return the x-coordination width of the proper object.
859 * @param pcyHeight, [in,out] use to return the y-coordination height of the proper object.
860 * @return S_OK if successful and S_FALSE if failure.
862 STDMETHODIMP
CMAccessible::accLocation(long *pxLeft
, long *pyTop
, long *pcxWidth
, long *pcyHeight
, VARIANT varChild
)
866 ENTER_PROTECTED_BLOCK
869 if(pxLeft
== NULL
|| pyTop
== NULL
|| pcxWidth
== NULL
|| pcyHeight
== NULL
)
874 if(varChild
.vt
==VT_I4
)
876 if(varChild
.lVal
==CHILDID_SELF
)
879 if (m_xAccessible
.is())
881 Reference
<XAccessibleContext
> const pRContext
=
882 m_xAccessible
->getAccessibleContext();
883 if( !pRContext
.is() )
885 Reference
< XAccessibleComponent
> pRComponent(pRContext
,UNO_QUERY
);
886 if( !pRComponent
.is() )
889 css::awt::Point pCPoint
= pRComponent
->getLocationOnScreen();
890 css::awt::Size pCSize
= pRComponent
->getSize();
893 *pcxWidth
= pCSize
.Width
;
894 *pcyHeight
= pCSize
.Height
;
899 *pxLeft
= m_sLocation
.m_dLeft
;
900 *pyTop
= m_sLocation
.m_dTop
;
901 *pcxWidth
= m_sLocation
.m_dWidth
;
902 *pcyHeight
= m_sLocation
.m_dHeight
;
910 LEAVE_PROTECTED_BLOCK
914 * Returns the current focused child to AT.
915 * @param navDir, the direction flag of the navigation.
916 * @param varStart, the start child id of this navigation action.
917 * @param pvarEndUpAt, [in,out] the end up child of this navigation action.
918 * @return S_OK if successful and E_FAIL if failure.
920 STDMETHODIMP
CMAccessible::accNavigate(long navDir
, VARIANT varStart
, VARIANT
*pvarEndUpAt
)
924 ENTER_PROTECTED_BLOCK
927 if(pvarEndUpAt
== NULL
)
931 HRESULT ret
= E_FAIL
;
934 case NAVDIR_FIRSTCHILD
:
935 ret
= GetFirstChild(varStart
,pvarEndUpAt
);
937 case NAVDIR_LASTCHILD
:
938 ret
= GetLastChild(varStart
,pvarEndUpAt
);
941 ret
= GetNextSibling(varStart
,pvarEndUpAt
);
943 case NAVDIR_PREVIOUS
:
944 ret
= GetPreSibling(varStart
,pvarEndUpAt
);
946 case NAVDIR_DOWN
://do not implement temporarily
948 case NAVDIR_UP
://do not implement temporarily
950 case NAVDIR_LEFT
://do not implement temporarily
952 case NAVDIR_RIGHT
://do not implement temporarily
959 LEAVE_PROTECTED_BLOCK
962 STDMETHODIMP
CMAccessible::accHitTest(long xLeft
, long yTop
, VARIANT
*pvarChild
)
966 ENTER_PROTECTED_BLOCK
969 if(pvarChild
== NULL
)
975 VariantInit(&varSelf
);
977 varSelf
.lVal
= CHILDID_SELF
;
978 accLocation(&x
,&y
,&w
,&h
,varSelf
);
979 if( (x
< xLeft
&& (x
+ w
) >xLeft
) && (y
< yTop
&& (y
+ h
) >yTop
) )
982 pvarChild
->vt
= VT_EMPTY
;
983 Reference
< XAccessibleContext
> pRContext
= GetContextByXAcc(m_xAccessible
.get());
984 nCount
= pRContext
->getAccessibleChildCount();
987 IMAccessible
* child
= NULL
;
988 for( i
= 0; i
<nCount
; i
++)
991 child
= GetChildInterface(i
+ 1);
992 if(child
&& child
->accHitTest(xLeft
,yTop
,pvarChild
) == S_OK
)
996 if(pvarChild
->vt
== VT_DISPATCH
)
1001 pvarChild
->vt
= VT_DISPATCH
;
1002 pvarChild
->pdispVal
= child
;
1007 pvarChild
->vt
= VT_I4
;
1008 pvarChild
->lVal
= CHILDID_SELF
;
1014 LEAVE_PROTECTED_BLOCK
1018 * Get The other Interface from CMAccessible.
1019 * @param guidService, must be IID_IAccessible here.
1020 * @param riid, the IID interface .
1021 * @return S_OK if successful and S_FALSE if failure.
1023 STDMETHODIMP
CMAccessible::QueryService(REFGUID guidService
, REFIID riid
, void** ppvObject
)
1025 if( InlineIsEqualGUID(guidService
, IID_IAccessible
) )
1026 return QueryInterface(riid
, ppvObject
);
1031 * Set the accessible name of the current COM object self or its one child from UNO.
1032 * @param varChild, vt member of varChild must be VT_I4,and lVal member stores the child ID,
1033 * the child ID specify child index from 0 to children count, 0 stands for object self.
1034 * @param szName, the name used to set the name of the proper object.
1035 * @return S_OK if successful and E_FAIL if failure.
1037 STDMETHODIMP
CMAccessible::put_accName(VARIANT varChild
, BSTR szName
)
1041 ENTER_PROTECTED_BLOCK
1043 if(varChild
.vt
==VT_I4
)
1045 if(varChild
.lVal
==CHILDID_SELF
)
1047 SAFE_SYSFREESTRING(m_pszName
);
1048 m_pszName
=SysAllocString(szName
);
1052 long lVal
= varChild
.lVal
;
1053 varChild
.lVal
= CHILDID_SELF
;
1054 IMAccessible
*pChild
= this->GetChildInterface(lVal
);
1057 return pChild
->put_accName(varChild
,szName
);
1061 LEAVE_PROTECTED_BLOCK
1065 * Set the accessible value of the current COM object self or its one child from UNO.
1066 * @param varChild, vt member of varChild must be VT_I4,and lVal member stores the child ID,
1067 * the child ID specify child index from 0 to children count, 0 stands for object self.
1068 * @param szValue, the value used to set the value of the proper object.
1069 * @return S_OK if successful and E_FAIL if failure.
1071 STDMETHODIMP
CMAccessible::put_accValue(VARIANT varChild
, BSTR szValue
)
1075 ENTER_PROTECTED_BLOCK
1077 if(varChild
.vt
==VT_I4
)
1079 if(varChild
.lVal
==CHILDID_SELF
)
1081 SysAllocString(m_pszValue
);
1082 m_pszValue
=SysAllocString(szValue
);
1086 long lVal
= varChild
.lVal
;
1087 varChild
.lVal
= CHILDID_SELF
;
1088 IMAccessible
*pChild
= this->GetChildInterface(lVal
);
1091 return pChild
->put_accValue(varChild
,szValue
);
1095 LEAVE_PROTECTED_BLOCK
1099 * Set the accessible name of the current COM object self from UNO.
1100 * @param pszName, the name value used to set the name of the current object.
1101 * @return S_OK if successful and E_FAIL if failure.
1103 STDMETHODIMP
CMAccessible::Put_XAccName(const OLECHAR __RPC_FAR
*pszName
)
1105 // internal IMAccessible - no mutex meeded
1107 ENTER_PROTECTED_BLOCK
1112 return E_INVALIDARG
;
1115 SAFE_SYSFREESTRING(m_pszName
);//??
1116 m_pszName
= SysAllocString(pszName
);
1121 LEAVE_PROTECTED_BLOCK
1125 * Set the accessible role of the current COM object self from UNO.
1126 * @param pRole, the role value used to set the role of the current object.
1127 * @return S_OK if successful and E_FAIL if failure.
1129 STDMETHODIMP
CMAccessible::Put_XAccRole(unsigned short pRole
)
1131 // internal IMAccessible - no mutex meeded
1138 * Add one state into the current state set for the current COM object from UNO.
1139 * @param pXSate, the state used to set the name of the current object.
1140 * @return S_OK if successful and E_FAIL if failure.
1142 STDMETHODIMP
CMAccessible::DecreaseState(DWORD pXSate
)
1144 // internal IMAccessible - no mutex meeded
1146 m_dState
&= (~pXSate
);
1151 * Delete one state into the current state set for the current COM object from UNO.
1152 * @param pXSate, the state used to set the name of the current object.
1153 * @return S_OK if successful and E_FAIL if failure.
1155 STDMETHODIMP
CMAccessible::IncreaseState(DWORD pXSate
)
1157 // internal IMAccessible - no mutex meeded
1164 * Set state into the current state set for the current COM object from UNO.
1165 * @param pXSate, the state used to set the name of the current object.
1166 * @return S_OK if successful and E_FAIL if failure.
1168 STDMETHODIMP
CMAccessible::SetState(DWORD pXSate
)
1170 // internal IMAccessible - no mutex meeded
1178 * Set the accessible description of the current COM object self from UNO.
1179 * @param pszDescription, the name used to set the description of the current object.
1180 * @return S_OK if successful and E_FAIL if failure.
1182 STDMETHODIMP
CMAccessible::Put_XAccDescription(const OLECHAR __RPC_FAR
*pszDescription
)
1184 // internal IMAccessible - no mutex meeded
1186 ENTER_PROTECTED_BLOCK
1189 if(pszDescription
== NULL
)
1191 return E_INVALIDARG
;
1194 SAFE_SYSFREESTRING(m_pszDescription
);
1195 m_pszDescription
= SysAllocString(pszDescription
);
1197 if(m_pszDescription
==NULL
)
1201 LEAVE_PROTECTED_BLOCK
1205 * Set the accessible value of the current COM object self from UNO.
1206 * @param pszAccValue, the name used to set the value of the current object.
1207 * @return S_OK if successful and E_FAIL if failure.
1209 STDMETHODIMP
CMAccessible::Put_XAccValue(const OLECHAR __RPC_FAR
*pszAccValue
)
1211 // internal IMAccessible - no mutex meeded
1213 ENTER_PROTECTED_BLOCK
1216 if(pszAccValue
== NULL
)
1218 return E_INVALIDARG
;
1220 SAFE_SYSFREESTRING(m_pszValue
);
1221 m_pszValue
= SysAllocString(pszAccValue
);
1222 if(m_pszValue
==NULL
)
1226 LEAVE_PROTECTED_BLOCK
1230 * Set the HWND value of the current COM object self from UNO. It should set the parent IAccessible
1231 * Object through the method AccessibleObjectFromWindow(...).
1232 * @param hwnd, the HWND used to set the value of the current object.
1233 * @return S_OK if successful and E_FAIL if failure.
1235 STDMETHODIMP
CMAccessible::Put_XAccWindowHandle(HWND hwnd
)
1237 // internal IMAccessible - no mutex meeded
1239 ENTER_PROTECTED_BLOCK
1244 LEAVE_PROTECTED_BLOCK
1248 * Set accessible focus by specifying child ID
1249 * @param dChildID, the child id identifies the focus child.
1250 * @return S_OK if successful and E_FAIL if failure.
1252 STDMETHODIMP
CMAccessible::Put_XAccFocus(long dChildID
)
1254 // internal IMAccessible - no mutex meeded
1256 ENTER_PROTECTED_BLOCK
1259 if(dChildID
==CHILDID_SELF
)
1263 m_pIParent
->Put_XAccFocus(m_dChildID
);
1268 m_dFocusChildID
= dChildID
;
1269 //traverse all ancestors to set the focused child ID so that when the get_accFocus is called on
1270 //any of the ancestors, this id can be used to get the IAccessible of focused object.
1273 m_pIParent
->Put_XAccFocus(dChildID
);
1278 LEAVE_PROTECTED_BLOCK
1282 *Set accessible object location for the current COM object
1283 * @param sLocation, the location of the current object.
1284 * @return S_OK if successful and E_FAIL if failure.
1286 STDMETHODIMP
CMAccessible::Put_XAccLocation(const Location sLocation
)
1288 // internal IMAccessible - no mutex meeded
1290 this->m_sLocation
= sLocation
;
1295 * Set accessible parent object for the current COM object if
1296 * the current object is a child of some COM object
1297 * @param pIParent, the parent of the current object.
1298 * @return S_OK if successful and E_FAIL if failure.
1300 STDMETHODIMP
CMAccessible::Put_XAccParent(IMAccessible __RPC_FAR
*pIParent
)
1302 // internal IMAccessible - no mutex meeded
1304 this->m_pIParent
= pIParent
;
1307 m_pIParent
->AddRef();
1313 * Set unique child id to COM
1314 * @param dChildID, the id of the current object.
1315 * @return S_OK if successful and E_FAIL if failure.
1317 STDMETHODIMP
CMAccessible::Put_XAccChildID(long dChildID
)
1319 // internal IMAccessible - no mutex meeded
1321 this->m_dChildID
= dChildID
;
1326 * Set AccObjectManagerAgent object pointer to COM
1327 * @param pAgent, the AccObjectManagerAgent point.
1328 * @return S_OK if successful and E_FAIL if failure.
1330 STDMETHODIMP
CMAccessible::Put_XAccAgent(hyper pAgent
)
1332 // internal IMAccessible - no mutex meeded
1334 g_pAgent
= reinterpret_cast<AccObjectManagerAgent
*>(pAgent
);
1339 * When a UNO control disposing, it disposes its listeners,
1340 * then notify AccObject in bridge management, then notify
1341 * COM that the XAccessible is invalid,so set m_xAccessible as NULL
1342 * @param isDestroy, true is it need to be destroyed.
1343 * @return S_OK if successful and E_FAIL if failure.
1345 STDMETHODIMP
CMAccessible::NotifyDestroy(BOOL isDestroy
)
1347 // internal IMAccessible - no mutex meeded
1349 m_isDestroy
= isDestroy
;
1350 m_xAccessible
.clear();
1355 *private methods that help implement public functions
1359 * Return child interface pointer by child ID,note: need to call AddRef()
1360 * @param lChildID, specify child index,which AT(such as Inspect32) gives.
1361 * @return IMAccessible*, pointer to the corresponding child object.
1363 IMAccessible
* CMAccessible::GetChildInterface(long dChildID
)//for test
1369 IMAccessible
* pIMAcc
= NULL
;
1370 g_pAgent
->GetIAccessibleFromResID(dChildID
,&pIMAcc
);
1377 if (!m_xAccessible
.is())
1380 Reference
<XAccessibleContext
> const pRContext
=
1381 m_xAccessible
->getAccessibleContext();
1382 if( !pRContext
.is() )
1385 if(dChildID
<1 || dChildID
>pRContext
->getAccessibleChildCount())
1388 IAccessible
* pChild
= NULL
;
1389 Reference
< XAccessible
> pXChild
= pRContext
->getAccessibleChild(dChildID
-1);
1390 BOOL isGet
= get_IAccessibleFromXAccessible(pXChild
.get(), &pChild
);
1394 g_pAgent
->InsertAccObj(pXChild
.get(), m_xAccessible
.get(),
1395 reinterpret_cast<sal_Int64
>(m_hwnd
));
1396 isGet
= get_IAccessibleFromXAccessible(pXChild
.get(), &pChild
);
1401 IMAccessible
* pIMAcc
= (IMAccessible
*)pChild
;
1410 * For List, tree and table,these roles belong to manage_descendant in UNO,
1411 * need to process specifically when navigate
1412 * @return BOOL, if it is descendantmanager, return true.
1414 BOOL
CMAccessible::IsDescendantManage()
1417 return (m_iRole
==ROLE_SYSTEM_LIST
)||(m_iRole
==ROLE_SYSTEM_OUTLINE
)||(m_iRole
==ROLE_SYSTEM_TABLE
);
1421 * for descendantmanager circumstance,provide child interface when navigate
1422 * @param varCur, the current child.
1423 * @param flags, the navigation direction.
1424 * @return IMAccessible*, the child of the end up node.
1426 IMAccessible
* CMAccessible::GetNavigateChildForDM(VARIANT varCur
, short flags
)
1429 XAccessibleContext
* pXContext
= GetContextByXAcc(m_xAccessible
.get());
1435 int count
= pXContext
->getAccessibleChildCount();
1441 IMAccessible
* pCurChild
= NULL
;
1442 XAccessible
* pChildXAcc
= NULL
;
1443 Reference
<XAccessible
> pRChildXAcc
;
1444 XAccessibleContext
* pChildContext
= NULL
;
1445 int index
= 0,delta
=0;
1449 pRChildXAcc
= pXContext
->getAccessibleChild(0);
1452 pRChildXAcc
= pXContext
->getAccessibleChild(count
-1);
1456 pCurChild
= GetChildInterface(varCur
.lVal
);
1461 pCurChild
->GetUNOInterface(reinterpret_cast<hyper
*>(&pChildXAcc
));
1462 if(pChildXAcc
==NULL
)
1466 pChildContext
= GetContextByXAcc(pChildXAcc
);
1467 if(pChildContext
== NULL
)
1471 delta
= (flags
==DM_NEXTCHILD
)?1:-1;
1472 //currently, getAccessibleIndexInParent is error in UNO for
1473 //some kind of List,such as ValueSet, the index will be less 1 than
1474 //what should be, need to fix UNO code
1475 index
= pChildContext
->getAccessibleIndexInParent()+delta
;
1476 if((index
>=0)&&(index
<=count
-1))
1478 pRChildXAcc
= pXContext
->getAccessibleChild(index
);
1485 if(!pRChildXAcc
.is())
1489 pChildXAcc
= pRChildXAcc
.get();
1490 g_pAgent
->InsertAccObj(pChildXAcc
, m_xAccessible
.get());
1491 return g_pAgent
->GetIMAccByXAcc(pChildXAcc
);
1495 *the following 4 private methods are for accNavigate implementation
1499 * Return first child for parent container, process differently according
1500 * to whether it is descendant manage
1501 * @param varStart, the start child id of this navigation action.
1502 * @param pvarEndUpAt, [in,out] the end up child of this navigation action.
1503 * @return S_OK if successful and E_FAIL if failure.
1505 HRESULT
CMAccessible::GetFirstChild(VARIANT varStart
,VARIANT
* pvarEndUpAt
)
1508 ENTER_PROTECTED_BLOCK
1511 if(pvarEndUpAt
== NULL
)
1513 return E_INVALIDARG
;
1515 if(varStart
.vt
!= VT_I4
)
1517 pvarEndUpAt
->vt
= VT_EMPTY
;
1518 return E_INVALIDARG
;
1521 pvarEndUpAt
->pdispVal
= GetNavigateChildForDM(varStart
, DM_FIRSTCHILD
);
1522 if(pvarEndUpAt
->pdispVal
)
1524 pvarEndUpAt
->pdispVal
->AddRef();
1525 pvarEndUpAt
->vt
= VT_DISPATCH
;
1529 pvarEndUpAt
->vt
= VT_EMPTY
;
1532 LEAVE_PROTECTED_BLOCK
1536 * Return last child for parent container, process differently according
1537 * to whether it is descendant manage
1538 * @param varStart, the start child id of this navigation action.
1539 * @param pvarEndUpAt, [in,out] the end up child of this navigation action.
1540 * @return S_OK if successful and E_FAIL if failure.
1542 HRESULT
CMAccessible::GetLastChild(VARIANT varStart
,VARIANT
* pvarEndUpAt
)
1545 ENTER_PROTECTED_BLOCK
1548 if(pvarEndUpAt
== NULL
)
1550 return E_INVALIDARG
;
1552 if(varStart
.vt
!= VT_I4
)
1554 pvarEndUpAt
->vt
= VT_EMPTY
;
1555 return E_INVALIDARG
;
1558 pvarEndUpAt
->pdispVal
= GetNavigateChildForDM(varStart
, DM_LASTCHILD
);
1559 if(pvarEndUpAt
->pdispVal
)
1561 pvarEndUpAt
->pdispVal
->AddRef();
1562 pvarEndUpAt
->vt
= VT_DISPATCH
;
1565 pvarEndUpAt
->vt
= VT_EMPTY
;
1568 LEAVE_PROTECTED_BLOCK
1572 * The method GetNextSibling is general, whatever it is descendant manage or not
1573 * Get the next sibling object.
1574 * @param varStart, the start child id of this navigation action.
1575 * @param pvarEndUpAt, [in,out] the end up child of this navigation action.
1576 * @return S_OK if successful and E_FAIL if failure.
1578 HRESULT
CMAccessible::GetNextSibling(VARIANT varStart
,VARIANT
* pvarEndUpAt
)
1581 ENTER_PROTECTED_BLOCK
1583 if(varStart
.vt
!= VT_I4
)
1585 pvarEndUpAt
->vt
= VT_EMPTY
;
1586 return E_INVALIDARG
;
1589 Reference
<XAccessibleContext
> const pRContext
=
1590 GetContextByXAcc(m_xAccessible
.get());
1593 varStart
.iVal
= sal_Int16(pRContext
->getAccessibleIndexInParent() + 2);
1595 if( m_pIParent
->get_accChild(varStart
,&pvarEndUpAt
->pdispVal
) == S_OK
)
1597 pvarEndUpAt
->vt
= VT_DISPATCH
;
1601 pvarEndUpAt
->vt
= VT_EMPTY
;
1604 LEAVE_PROTECTED_BLOCK
1608 *the method GetPreSibling is general, whatever it is descendant manage or not
1609 * @param varStart, the start child id of this navigation action.
1610 * @param pvarEndUpAt, [in,out] the end up child of this navigation action.
1611 * @return S_OK if successful and E_FAIL if failure.
1613 HRESULT
CMAccessible::GetPreSibling(VARIANT varStart
,VARIANT
* pvarEndUpAt
)
1616 ENTER_PROTECTED_BLOCK
1619 if(pvarEndUpAt
== NULL
)
1621 return E_INVALIDARG
;
1623 if(varStart
.vt
!= VT_I4
)
1625 pvarEndUpAt
->vt
= VT_EMPTY
;
1626 return E_INVALIDARG
;
1629 Reference
<XAccessibleContext
> const pRContext
=
1630 GetContextByXAcc(m_xAccessible
.get());
1633 varStart
.iVal
= sal_Int16(pRContext
->getAccessibleIndexInParent());
1634 if(m_pIParent
&& varStart
.iVal
> 0)
1635 if( m_pIParent
->get_accChild(varStart
,&pvarEndUpAt
->pdispVal
) == S_OK
)
1637 pvarEndUpAt
->vt
= VT_DISPATCH
;
1641 pvarEndUpAt
->vt
= VT_EMPTY
;
1644 LEAVE_PROTECTED_BLOCK
1648 * For IAccessible2 implementation methods
1650 STDMETHODIMP
CMAccessible::get_nRelations( long __RPC_FAR
*nRelations
)
1654 ENTER_PROTECTED_BLOCK
1658 if(nRelations
== NULL
)
1660 return E_INVALIDARG
;
1665 if (!m_xContext
.is())
1667 Reference
<XAccessibleRelationSet
> pRrelationSet
=
1668 m_xContext
.get()->getAccessibleRelationSet();
1669 if(!pRrelationSet
.is())
1675 *nRelations
= pRrelationSet
->getRelationCount();
1678 LEAVE_PROTECTED_BLOCK
1681 STDMETHODIMP
CMAccessible::get_relation( long relationIndex
, IAccessibleRelation __RPC_FAR
*__RPC_FAR
*relation
)
1685 ENTER_PROTECTED_BLOCK
1688 if(relation
== NULL
)
1690 return E_INVALIDARG
;
1693 if (!m_xContext
.is())
1698 get_nRelations(&nMax
);
1700 *relation
= (IAccessibleRelation
*)::CoTaskMemAlloc(sizeof(IAccessibleRelation
));
1702 // #CHECK Memory Allocation#
1703 if(*relation
== NULL
)
1708 if( relationIndex
< nMax
)
1710 Reference
<XAccessibleRelationSet
> const pRrelationSet
=
1711 m_xContext
.get()->getAccessibleRelationSet();
1712 if(!pRrelationSet
.is())
1718 IAccessibleRelation
* pRelation
= NULL
;
1719 HRESULT hr
= createInstance
<CAccRelation
>(IID_IAccessibleRelation
,
1723 IUNOXWrapper
* wrapper
= NULL
;
1724 hr
= pRelation
->QueryInterface(IID_IUNOXWrapper
, (void**)&wrapper
);
1727 AccessibleRelation accRelation
= pRrelationSet
->getRelation(relationIndex
);
1728 wrapper
->put_XSubInterface(
1729 reinterpret_cast<hyper
>(&accRelation
));
1731 *relation
= pRelation
;
1740 LEAVE_PROTECTED_BLOCK
1743 STDMETHODIMP
CMAccessible::get_relations( long, IAccessibleRelation __RPC_FAR
*__RPC_FAR
*relation
, long __RPC_FAR
*nRelations
)
1747 ENTER_PROTECTED_BLOCK
1751 if(relation
== NULL
|| nRelations
== NULL
)
1753 return E_INVALIDARG
;
1755 // #CHECK XInterface#
1757 if (!m_xContext
.is())
1760 Reference
<XAccessibleRelationSet
> const pRrelationSet
=
1761 m_xContext
.get()->getAccessibleRelationSet();
1762 if(!pRrelationSet
.is())
1768 long nCount
= pRrelationSet
->getRelationCount();
1770 *relation
= (IAccessibleRelation
*)::CoTaskMemAlloc(nCount
*sizeof(IAccessibleRelation
));
1772 // #CHECK Memory Allocation#
1773 if(*relation
== NULL
)
1778 for(int i
=0; i
<nCount
; i
++)
1780 IAccessibleRelation
* pRelation
= NULL
;
1781 HRESULT hr
= createInstance
<CAccRelation
>(IID_IAccessibleRelation
,
1785 IUNOXWrapper
* wrapper
= NULL
;
1786 hr
= pRelation
->QueryInterface(IID_IUNOXWrapper
, (void**)&wrapper
);
1789 AccessibleRelation accRelation
= pRrelationSet
->getRelation(i
);
1790 wrapper
->put_XSubInterface(
1791 reinterpret_cast<hyper
>(&accRelation
));
1794 (relation
)[i
] = pRelation
;
1798 *nRelations
= nCount
;
1801 LEAVE_PROTECTED_BLOCK
1804 STDMETHODIMP
CMAccessible::role(long __RPC_FAR
*role
)
1808 ENTER_PROTECTED_BLOCK
1814 LEAVE_PROTECTED_BLOCK
1818 STDMETHODIMP
CMAccessible:: get_nActions(long __RPC_FAR
*nActions
)
1826 if(nActions
== NULL
)
1828 return E_INVALIDARG
;
1831 IAccessibleAction
* pAcc
= NULL
;
1832 HRESULT hr
= QueryInterface(IID_IAccessibleAction
, (void**)&pAcc
);
1835 pAcc
->nActions(nActions
);
1849 STDMETHODIMP
CMAccessible:: scrollToPoint(enum IA2CoordinateType
, long, long)
1854 STDMETHODIMP
CMAccessible:: scrollTo(enum IA2ScrollType
)
1859 static XAccessible
* getTheParentOfMember(XAccessible
* pXAcc
)
1866 Reference
<XAccessibleContext
> pRContext
= pXAcc
->getAccessibleContext();
1867 Reference
<XAccessibleRelationSet
> pRrelationSet
= pRContext
->getAccessibleRelationSet();
1868 long nRelations
= pRrelationSet
->getRelationCount();
1869 for(int i
=0 ; i
<nRelations
; i
++)
1871 AccessibleRelation accRelation
= pRrelationSet
->getRelation(i
);
1872 if(accRelation
.RelationType
== 7)
1874 Sequence
< Reference
< XInterface
> > xTargets
= accRelation
.TargetSet
;
1875 return (XAccessible
*)xTargets
[0].get();
1881 STDMETHODIMP
CMAccessible:: get_groupPosition(long __RPC_FAR
*groupLevel
,long __RPC_FAR
*similarItemsInGroup
,long __RPC_FAR
*positionInGroup
)
1885 ENTER_PROTECTED_BLOCK
1888 if(groupLevel
== NULL
|| similarItemsInGroup
== NULL
|| positionInGroup
== NULL
)
1890 return E_INVALIDARG
;
1893 if (!m_xAccessible
.is())
1896 Reference
<XAccessibleContext
> const pRContext
=
1897 m_xAccessible
->getAccessibleContext();
1900 long Role
= pRContext
->getAccessibleRole();
1903 *similarItemsInGroup
= 0;
1904 *positionInGroup
= 0;
1906 if (Role
!= AccessibleRole::DOCUMENT
&& Role
!= AccessibleRole::DOCUMENT_PRESENTATION
&&
1907 Role
!= AccessibleRole::DOCUMENT_SPREADSHEET
&& Role
!= AccessibleRole::DOCUMENT_TEXT
)
1909 Reference
< XAccessibleGroupPosition
> xGroupPosition( pRContext
, UNO_QUERY
);
1910 if ( xGroupPosition
.is() )
1912 Sequence
< sal_Int32
> rSeq
= xGroupPosition
->getGroupPosition( makeAny( pRContext
) );
1913 sal_Int32
* pSeq
= rSeq
.getArray();
1916 *groupLevel
= pSeq
[0];
1917 *similarItemsInGroup
= pSeq
[1];
1918 *positionInGroup
= pSeq
[2];
1925 Reference
< XAccessible
> pParentAcc
= pRContext
->getAccessibleParent();
1926 if( !pParentAcc
.is() )
1931 Reference
<XAccessibleContext
> pRParentContext
= pParentAcc
->getAccessibleContext();
1937 if( Role
== RADIO_BUTTON
)
1939 Reference
<XAccessibleRelationSet
> pRrelationSet
= pRContext
->getAccessibleRelationSet();
1940 long nRel
= pRrelationSet
->getRelationCount();
1941 for(int i
=0 ; i
<nRel
; i
++)
1943 AccessibleRelation accRelation
= pRrelationSet
->getRelation(i
);
1944 if(accRelation
.RelationType
== 7)
1946 Sequence
< Reference
< XInterface
> > xTargets
= accRelation
.TargetSet
;
1948 Reference
<XInterface
> pRAcc
= xTargets
[0];
1949 for(int j
=0; j
<pRParentContext
->getAccessibleChildCount(); j
++)
1951 if( getTheParentOfMember(pRParentContext
->getAccessibleChild(j
).get())
1952 == (XAccessible
*)pRAcc
.get() &&
1953 pRParentContext
->getAccessibleChild(j
)->getAccessibleContext()->getAccessibleRole() == RADIO_BUTTON
)
1955 if (pRParentContext
->getAccessibleChild(j
).get() == m_xAccessible
.get())
1961 *similarItemsInGroup
= number
;
1962 *positionInGroup
= index
;
1966 else if ( COMBO_BOX
== Role
)
1969 *similarItemsInGroup
= 0;
1970 *positionInGroup
= -1;
1972 long nCount
= pRContext
->getAccessibleChildCount();
1977 Reference
<XAccessible
> xList
=pRContext
->getAccessibleChild(1);
1982 Reference
<XAccessibleContext
> xListContext(xList
,UNO_QUERY
);
1983 if (!xListContext
.is())
1987 Reference
<XAccessibleSelection
> xListSel(xList
,UNO_QUERY
);
1992 *similarItemsInGroup
= xListContext
->getAccessibleChildCount();
1993 if (*similarItemsInGroup
> 0 )
1997 Reference
<XAccessible
> xChild
= xListSel
->getSelectedAccessibleChild(0);
2000 Reference
<XAccessibleContext
> xChildContext(xChild
,UNO_QUERY
);
2001 if (xChildContext
.is())
2003 *positionInGroup
=xChildContext
->getAccessibleIndexInParent() + 1 ;
2013 else if ( PAGE_TAB
== Role
)
2016 *similarItemsInGroup
= pRParentContext
->getAccessibleChildCount();
2018 if (*similarItemsInGroup
> 0 )
2020 *positionInGroup
=pRContext
->getAccessibleIndexInParent() + 1 ;
2024 *positionInGroup
= -1;
2030 BOOL isFound
= FALSE
;
2031 while( pParentAcc
.is() && !isFound
)
2034 pRParentContext
= pParentAcc
->getAccessibleContext();
2035 Role
= pRParentContext
->getAccessibleRole();
2036 if( (Role
== TREE
) || (Role
== LIST
) )
2038 pParentAcc
= pRParentContext
->getAccessibleParent();
2043 Reference
< XAccessible
> pTempAcc
= pRContext
->getAccessibleParent();
2044 pRParentContext
= pTempAcc
->getAccessibleContext();
2045 *groupLevel
= level
;
2046 *similarItemsInGroup
= pRParentContext
->getAccessibleChildCount();
2047 *positionInGroup
= pRContext
->getAccessibleIndexInParent() + 1;
2052 *similarItemsInGroup
= 0;
2053 *positionInGroup
= 0;
2057 LEAVE_PROTECTED_BLOCK
2060 STDMETHODIMP
CMAccessible:: get_extendedStates( long, BSTR __RPC_FAR
*__RPC_FAR
*, long __RPC_FAR
*)
2066 STDMETHODIMP
CMAccessible:: get_uniqueID(long __RPC_FAR
*uniqueID
)
2070 ENTER_PROTECTED_BLOCK
2073 if(uniqueID
== NULL
)
2075 return E_INVALIDARG
;
2077 *uniqueID
= m_dChildID
;
2080 LEAVE_PROTECTED_BLOCK
2083 STDMETHODIMP
CMAccessible:: get_windowHandle(HWND __RPC_FAR
*windowHandle
)
2087 ENTER_PROTECTED_BLOCK
2090 if(windowHandle
== NULL
)
2092 return E_INVALIDARG
;
2095 HWND nHwnd
= m_hwnd
;
2096 IAccessible
* pParent
= m_pIParent
;
2097 CMAccessible
* pChild
= this;
2098 while((nHwnd
==0) && pParent
)
2100 pChild
= (CMAccessible
*)pParent
;
2103 pParent
= (IAccessible
*)pChild
->m_pIParent
;
2104 nHwnd
= (HWND
)pChild
->m_hwnd
;
2110 *windowHandle
= nHwnd
;
2113 LEAVE_PROTECTED_BLOCK
2117 * Get XAccessibleContext directly from UNO by the stored XAccessible pointer
2118 * @param pXAcc, UNO XAccessible object point.
2119 * @return XAccessibleContext*, the context of the pXAcc.
2121 XAccessibleContext
* CMAccessible::GetContextByXAcc( XAccessible
* pXAcc
)
2123 Reference
< XAccessibleContext
> pRContext
;
2127 pRContext
= pXAcc
->getAccessibleContext();
2128 if( !pRContext
.is() )
2130 return pRContext
.get();
2134 * Return the member variable m_pXAccessibleSelection, instead of
2135 * get XAccessibleSelection according to XAccessibleContext because if so,it will
2136 * depend on the UNO implementation code,so when COM is created, put XAccessibleSelection
2137 * by bridge management system
2138 * @return XAccessibleSelection*, the selection of the current object.
2140 Reference
< XAccessibleSelection
> CMAccessible::GetSelection()
2142 if (!m_xAccessible
.is())
2144 Reference
<XAccessibleContext
> const pRContext
=
2145 m_xAccessible
->getAccessibleContext();
2148 Reference
< XAccessibleSelection
> pRSelection(pRContext
,UNO_QUERY
);
2155 * Select one XAccessible item, for accSelect implementation
2156 * @param pItem, the item should be selected.
2157 * @return S_OK if successful.
2159 HRESULT
CMAccessible::SelectChild(XAccessible
* pItem
)
2162 ENTER_PROTECTED_BLOCK
2164 XAccessibleContext
* pParentContext
= GetContextByXAcc(m_xAccessible
.get());
2165 XAccessibleContext
* pContext
= GetContextByXAcc( pItem
);
2166 if( pParentContext
== NULL
|| pContext
== NULL
)
2169 Reference
< XAccessibleSelection
> pRSelection
= GetSelection();
2170 if( !pRSelection
.is() )
2172 long Index
= pContext
->getAccessibleIndexInParent();
2173 pRSelection
->selectAccessibleChild( Index
);
2176 LEAVE_PROTECTED_BLOCK
2180 * Deselect one XAccessible item, for accSelect implimentation
2181 * @param pItem, the item should be deselected.
2182 * @return S_OK if successful.
2184 HRESULT
CMAccessible::DeSelectChild(XAccessible
* pItem
)
2187 ENTER_PROTECTED_BLOCK
2189 XAccessibleContext
* pParentContext
= GetContextByXAcc(m_xAccessible
.get());
2191 XAccessibleContext
* pContext
= GetContextByXAcc( pItem
);
2192 if( pParentContext
== NULL
|| pContext
== NULL
)
2193 return E_INVALIDARG
;
2195 Reference
< XAccessibleSelection
> pRSelection
= GetSelection();
2196 if( !pRSelection
.is() )
2198 long Index
= pContext
->getAccessibleIndexInParent();
2199 pRSelection
->deselectAccessibleChild( Index
);
2203 LEAVE_PROTECTED_BLOCK
2207 * Select multiple XAccessible items,for implementation of accSelect
2208 * @param pItem, the items should be selected.
2209 * @param size, the size of the items.
2210 * @return S_OK if successful.
2212 HRESULT
CMAccessible::SelectMutipleChidren( XAccessible
** pItem
,int size
)
2215 ENTER_PROTECTED_BLOCK
2220 return E_INVALIDARG
;
2222 for(int index
= 0;index
< size
;index
++)
2224 SelectChild( pItem
[index
] );
2228 LEAVE_PROTECTED_BLOCK
2232 * Deselect multiple XAccessible items,for implementation of accSelect
2233 * @param pItem, the items should be selected.
2234 * @param size, the size of the items.
2235 * @return S_OK if successful.
2237 HRESULT
CMAccessible::DeSelectMutipleChildren( XAccessible
** pItem
,int size
)
2240 ENTER_PROTECTED_BLOCK
2245 return E_INVALIDARG
;
2247 for(int index
= 0;index
< size
;index
++)
2249 DeSelectChild( pItem
[index
] );
2253 LEAVE_PROTECTED_BLOCK
2257 * When COM is created, UNO set XAccessible pointer to it
2258 * in order to COM can operate UNO information
2259 * @param pXAcc, the XAccessible object of current object.
2260 * @return S_OK if successful.
2262 STDMETHODIMP
CMAccessible::SetXAccessible(hyper pXAcc
)
2264 // internal IMAccessible - no mutex meeded
2266 m_xAccessible
= reinterpret_cast<XAccessible
*>(pXAcc
);
2267 m_pEnumVar
->PutSelection(/*XAccessibleSelection*/
2268 reinterpret_cast<hyper
>(m_xAccessible
.get()));
2270 m_xContext
= m_xAccessible
->getAccessibleContext();
2276 * accSelect method has many optional flags, needs to process comprehensively
2277 * Mozilla and Microsoft do not implement SELFLAG_EXTENDSELECTION flag.
2278 * The implementation of this flag is a little trouble-shooting,so we also
2279 * do not implement it now
2280 * @param flagsSelect, the selection flag of the select action.
2281 * @param varChild, the child object pointer of current action.
2282 * @return S_OK if successful.
2284 STDMETHODIMP
CMAccessible::accSelect(long flagsSelect
, VARIANT varChild
)
2288 ENTER_PROTECTED_BLOCK
2290 if( (flagsSelect
&SELFLAG_ADDSELECTION
) &&
2291 (SELFLAG_REMOVESELECTION
&flagsSelect
) )
2292 return E_INVALIDARG
;
2294 if ( (flagsSelect
&SELFLAG_TAKESELECTION
) &&
2296 (flagsSelect
&SELFLAG_ADDSELECTION
) ||
2297 (flagsSelect
&SELFLAG_REMOVESELECTION
) ||
2298 (flagsSelect
&SELFLAG_EXTENDSELECTION
)
2301 return E_INVALIDARG
;
2303 if ( varChild
.vt
!= VT_I4
)
2304 return E_INVALIDARG
;
2306 IMAccessible
* pSelectAcc
;
2307 if( varChild
.lVal
== CHILDID_SELF
)
2310 pSelectAcc
->AddRef();
2314 pSelectAcc
= GetChildInterface(varChild
.lVal
);
2317 if( pSelectAcc
== NULL
)
2318 return E_INVALIDARG
;
2320 if( flagsSelect
&SELFLAG_TAKEFOCUS
)
2322 XAccessible
* pTempUNO
= 0;
2323 pSelectAcc
->GetUNOInterface(reinterpret_cast<hyper
*>(&pTempUNO
));
2325 if( pTempUNO
== NULL
)
2328 Reference
<XAccessibleContext
> pRContext
= pTempUNO
->getAccessibleContext();
2329 Reference
< XAccessibleComponent
> pRComponent(pRContext
,UNO_QUERY
);
2330 Reference
< XAccessible
> pRParentXAcc
= pRContext
->getAccessibleParent();
2331 Reference
< XAccessibleContext
> pRParentContext
= pRParentXAcc
->getAccessibleContext();
2332 Reference
< XAccessibleComponent
> pRParentComponent(pRParentContext
,UNO_QUERY
);
2333 Reference
< XAccessibleSelection
> pRParentSelection(pRParentContext
,UNO_QUERY
);
2336 pRComponent
->grabFocus();
2338 if( flagsSelect
& SELFLAG_TAKESELECTION
)
2340 pRParentSelection
->clearAccessibleSelection();
2341 pRParentSelection
->selectAccessibleChild( pRContext
->getAccessibleIndexInParent() );
2344 if( flagsSelect
& SELFLAG_ADDSELECTION
)
2346 pRParentSelection
->selectAccessibleChild( pRContext
->getAccessibleIndexInParent() );
2349 if( flagsSelect
& SELFLAG_REMOVESELECTION
)
2351 pRParentSelection
->deselectAccessibleChild( pRContext
->getAccessibleIndexInParent() );
2354 if( flagsSelect
& SELFLAG_EXTENDSELECTION
)
2356 long indexInParrent
= pRContext
->getAccessibleIndexInParent();
2358 if( pRParentSelection
->isAccessibleChildSelected( indexInParrent
+ 1 ) ||
2359 pRParentSelection
->isAccessibleChildSelected( indexInParrent
- 1 ) )
2361 pRParentSelection
->selectAccessibleChild( indexInParrent
);
2367 pSelectAcc
->Release();
2370 LEAVE_PROTECTED_BLOCK
2374 * Return XAccessible interface pointer when needed
2375 * @param pXAcc, [in, out] the Uno interface of the current object.
2376 * @return S_OK if successful.
2378 STDMETHODIMP
CMAccessible::GetUNOInterface(hyper
* pXAcc
)
2380 // internal IMAccessible - no mutex meeded
2383 return E_INVALIDARG
;
2385 *pXAcc
= reinterpret_cast<hyper
>(m_xAccessible
.get());
2390 * Helper method for Implementation of get_accDefaultAction
2391 * @param pAction, the default action point of the current object.
2392 * @return S_OK if successful.
2394 STDMETHODIMP
CMAccessible::SetDefaultAction(hyper pAction
)
2396 // internal IMAccessible - no mutex meeded
2398 m_xAction
= reinterpret_cast<XAccessibleAction
*>(pAction
);
2403 * This method is called when AT open some UI elements initially
2404 * the UI element takes the default action defined here
2405 * @param varChild, the child id of the defaultaction.
2406 * @param pszDefaultAction,[in/out] the description of the current action.
2407 * @return S_OK if successful.
2409 HRESULT STDMETHODCALLTYPE
CMAccessible::get_accDefaultAction(VARIANT varChild
, BSTR
*pszDefaultAction
)
2413 ENTER_PROTECTED_BLOCK
2416 if(pszDefaultAction
== NULL
)
2418 return E_INVALIDARG
;
2420 if(varChild
.vt
==VT_I4
)
2422 if(varChild
.lVal
==CHILDID_SELF
)
2424 if (!m_xAction
.is())
2425 return DISP_E_MEMBERNOTFOUND
;
2426 SAFE_SYSFREESTRING(*pszDefaultAction
);
2427 *pszDefaultAction
= SysAllocString(m_pszActionDescription
);
2431 long lVal
= varChild
.lVal
;
2432 varChild
.lVal
= CHILDID_SELF
;
2433 IMAccessible
*pChild
= this->GetChildInterface(lVal
);
2436 return pChild
->get_accDefaultAction(varChild
,pszDefaultAction
);
2440 LEAVE_PROTECTED_BLOCK
2444 * AT call this method to operate application
2445 * @param varChild, the child id of the action object.
2446 * @return S_OK if successful.
2448 HRESULT STDMETHODCALLTYPE
CMAccessible::accDoDefaultAction(VARIANT varChild
)
2452 ENTER_PROTECTED_BLOCK
2454 if( varChild
.vt
!= VT_I4
)
2455 return E_INVALIDARG
;
2456 if (!m_xAction
.is())
2458 if (m_xAction
->getAccessibleActionCount() == 0)
2461 if(varChild
.lVal
==CHILDID_SELF
)
2463 if (m_xAction
->getAccessibleActionCount() > 0)
2464 m_xAction
->doAccessibleAction(0);
2468 long lVal
= varChild
.lVal
;
2469 varChild
.lVal
= CHILDID_SELF
;
2470 IMAccessible
*pChild
= this->GetChildInterface(lVal
);
2473 return pChild
->accDoDefaultAction( varChild
);
2475 LEAVE_PROTECTED_BLOCK
2479 * UNO set description information for action to COM.
2480 * @param szAction, the action description of the current object.
2481 * @return S_OK if successful.
2483 STDMETHODIMP
CMAccessible::Put_ActionDescription( const OLECHAR
* szAction
)
2485 // internal IMAccessible - no mutex meeded
2487 ENTER_PROTECTED_BLOCK
2490 if(szAction
== NULL
)
2492 return E_INVALIDARG
;
2494 SAFE_SYSFREESTRING(m_pszActionDescription
);
2495 m_pszActionDescription
= SysAllocString( szAction
);
2498 LEAVE_PROTECTED_BLOCK
2501 BOOL
CMAccessible::GetXInterfaceFromXAccessible(XAccessible
* pXAcc
, XInterface
** ppXI
, int index
)
2503 Reference
< XAccessibleContext
> pRContext
;
2508 QUERYXINTERFACE(AccessibleComponent
)
2511 QUERYXINTERFACE(AccessibleText
)
2513 case XI_EDITABLETEXT
:
2514 QUERYXINTERFACE(AccessibleEditableText
)
2517 QUERYXINTERFACE(AccessibleTable
)
2520 QUERYXINTERFACE(AccessibleSelection
)
2522 case XI_EXTENDEDCOMP
:
2523 QUERYXINTERFACE(AccessibleExtendedComponent
)
2526 QUERYXINTERFACE(AccessibleKeyBinding
)
2529 QUERYXINTERFACE(AccessibleAction
)
2532 QUERYXINTERFACE(AccessibleValue
)
2535 QUERYXINTERFACE(AccessibleHypertext
)
2538 QUERYXINTERFACE(AccessibleHyperlink
)
2541 QUERYXINTERFACE(AccessibleImage
)
2550 template<typename T
> HRESULT
2551 createAggInstance(CMAccessible
&rOuter
, void ** ppvObject
)
2553 // Note: CComAggObject has special handling for IUnknown - must
2554 // query for that when creating it! Otherwise we get a T member of it
2555 // which will redirect QueryInterface back to CMAccessible infinitely.
2556 // (CComAggObject has its own ref-count too which is not a problem
2557 // since it is inserted in m_containedObjects.)
2558 return CComCreator
< CComAggObject
<T
> >::CreateInstance(
2559 rOuter
.GetControllingUnknown(), IID_IUnknown
, ppvObject
);
2562 typedef HRESULT (AggCreatorFunc
)(CMAccessible
&, void **);
2567 AggCreatorFunc
* pfnCreateInstance
;
2571 static AggMapEntry g_CMAccessible_AggMap
[] = {
2572 { &IID_IAccessibleComponent
, &createAggInstance
<CAccComponent
>, XI_COMPONENT
},
2573 { &IID_IAccessibleText
, &createAggInstance
<CAccText
>, XI_TEXT
},
2574 { &IID_IAccessibleEditableText
, &createAggInstance
<CAccEditableText
>, XI_EDITABLETEXT
},
2575 { &IID_IAccessibleImage
, &createAggInstance
<CAccImage
>, XI_IMAGE
},
2576 { &IID_IAccessibleTable
, &createAggInstance
<CAccTable
>, XI_TABLE
},
2577 { &IID_IAccessibleAction
, &createAggInstance
<CAccAction
>, XI_ACTION
},
2578 { &IID_IAccessibleValue
, &createAggInstance
<CAccValue
>, XI_VALUE
},
2579 { &IID_IAccessibleHypertext
, &createAggInstance
<CAccHypertext
>, XI_HYPERTEXT
},
2580 { &IID_IAccessibleHyperlink
, &createAggInstance
<CAccHyperLink
>, XI_HYPERLINK
},
2585 HRESULT WINAPI
CMAccessible::SmartQI(void* /*pv*/, REFIID iid
, void** ppvObject
)
2587 ENTER_PROTECTED_BLOCK
2590 if (InlineIsEqualGUID(iid
,IID_IAccIdentity
) ||
2591 InlineIsEqualGUID(iid
,IID_IStdMarshalInfo
) ||
2592 InlineIsEqualGUID(iid
,IID_IMarshal
) ||
2593 InlineIsEqualGUID(iid
,IID_IExternalConnection
)||
2594 InlineIsEqualGUID(iid
,IID_IOleWindow
))
2599 AggMapEntry
* pMap
= &g_CMAccessible_AggMap
[0];
2600 while(pMap
&& pMap
->piid
)
2602 if (InlineIsEqualGUID(iid
, *pMap
->piid
))
2606 XInterface
* pXI
= NULL
;
2607 BOOL bFound
= GetXInterfaceFromXAccessible(m_xAccessible
.get(),
2608 &pXI
, pMap
->XIFIndex
);
2614 XGUIDToComObjHash::iterator pIndTemp
= m_containedObjects
.find( iid
);
2615 if ( pIndTemp
!= m_containedObjects
.end() )
2617 return pIndTemp
->second
.p
->QueryInterface( iid
, ppvObject
);
2621 HRESULT hr
= pMap
->pfnCreateInstance(*this, ppvObject
);
2625 m_containedObjects
.insert(XGUIDToComObjHash::value_type(*pMap
->piid
,(IUnknown
*)*ppvObject
));
2626 IUNOXWrapper
* wrapper
= NULL
;
2627 ((IUnknown
*)*ppvObject
)->QueryInterface(IID_IUNOXWrapper
, (void**)&wrapper
);
2630 wrapper
->put_XInterface(
2631 reinterpret_cast<hyper
>(m_xAccessible
.get()));
2643 LEAVE_PROTECTED_BLOCK
2647 CMAccessible::get_IAccessibleFromXAccessible(XAccessible
* pXAcc
, IAccessible
**ppIA
)
2650 ENTER_PROTECTED_BLOCK
2655 return E_INVALIDARG
;
2659 isGet
= g_pAgent
->GetIAccessibleFromXAccessible(pXAcc
, ppIA
);
2666 LEAVE_PROTECTED_BLOCK
2669 void CMAccessible::get_OLECHARFromAny(Any
& pAny
, OLECHAR
* pChar
)
2675 switch(pAny
.getValueTypeClass())
2677 case TypeClass_CHAR
:
2681 swprintf( pChar
, L
"%d", val
);
2684 case TypeClass_BOOLEAN
:
2688 swprintf( pChar
, L
"%d", val
);
2691 case TypeClass_BYTE
:
2695 swprintf( pChar
, L
"%d", val
);
2698 case TypeClass_SHORT
:
2702 swprintf( pChar
, L
"%d", val
);
2705 case TypeClass_UNSIGNED_SHORT
:
2709 swprintf( pChar
, L
"%d", val
);
2712 case TypeClass_LONG
:
2716 swprintf( pChar
, L
"%ld", val
);
2719 case TypeClass_UNSIGNED_LONG
:
2723 swprintf( pChar
, L
"%ld", val
);
2726 case TypeClass_FLOAT
:
2730 swprintf( pChar
, L
"%.3f", val
);
2733 case TypeClass_DOUBLE
:
2737 swprintf( pChar
, L
"%.6lf", val
);
2740 case TypeClass_STRING
:
2742 ::rtl::OUString val
;
2744 wcscpy(pChar
, val
.getStr());
2747 case TypeClass_SEQUENCE
:
2749 if(pAny
.getValueType() == cppu::UnoType
<Sequence
< ::rtl::OUString
>>::get())
2751 Sequence
< ::rtl::OUString
> val
;
2754 ::rtl::OUString pString
;
2756 int count
= val
.getLength();
2758 for( int iIndex
= 0;iIndex
< count
;iIndex
++ )
2760 pString
+= val
[iIndex
];
2762 wcscpy(pChar
, pString
.getStr());
2764 else if (pAny
.getValueType() == cppu::UnoType
<Sequence
< css::style::TabStop
>>::get())
2766 Sequence
< css::style::TabStop
> val
;
2768 int count
= val
.getLength();
2770 for( int iIndex
= 0;iIndex
< count
;iIndex
++ )
2772 OLECHAR pAttrs
[512] = {NULL
};
2774 OLECHAR pAttrsPosition
[512] = {NULL
};
2775 OLECHAR pAttrsDescimalChar
[512] = {NULL
};
2776 OLECHAR pAttrsFillChar
[512] = {NULL
};
2778 css::style::TabStop sigleVal
= val
[iIndex
];
2780 swprintf( pAttrsPosition
, L
"Position=%ld,TabAlign=%ld",
2781 sigleVal
.Position
, sigleVal
.Alignment
);
2783 if(sigleVal
.DecimalChar
==';' || sigleVal
.DecimalChar
== ':' || sigleVal
.DecimalChar
== ',' ||
2784 sigleVal
.DecimalChar
== '=' || sigleVal
.DecimalChar
== '\\')
2785 swprintf( pAttrsDescimalChar
, L
"DecimalChar=\\%c",sigleVal
.DecimalChar
);
2787 swprintf( pAttrsDescimalChar
, L
"DecimalChar=%c",sigleVal
.DecimalChar
);
2789 if(sigleVal
.FillChar
==';' || sigleVal
.FillChar
== ':' || sigleVal
.FillChar
== ',' ||
2790 sigleVal
.FillChar
== '=' || sigleVal
.FillChar
== '\\')
2791 swprintf( pAttrsFillChar
, L
"FillChar=\\%c",sigleVal
.FillChar
);
2793 swprintf( pAttrsFillChar
, L
"FillChar=%c",sigleVal
.FillChar
);
2795 swprintf( pAttrs
, L
"%s,%s,%s,",pAttrsPosition
,pAttrsDescimalChar
,pAttrsFillChar
);
2797 wcscat(pChar
,pAttrs
);
2802 case TypeClass_ENUM
:
2804 if (pAny
.getValueType() == cppu::UnoType
<css::awt::FontSlant
>::get())
2806 css::awt::FontSlant val
;
2808 swprintf( pChar
, L
"%d", val
);
2812 case TypeClass_STRUCT
:
2814 if (pAny
.getValueType() == cppu::UnoType
<css::style::LineSpacing
>::get())
2816 css::style::LineSpacing val
;
2818 swprintf( pChar
, L
"Mode=%ld,Height=%ld,", val
.Mode
, val
.Height
);
2820 else if (pAny
.getValueType() == cppu::UnoType
<css::accessibility::TextSegment
>::get())
2822 css::accessibility::TextSegment val
;
2824 ::rtl::OUString
realVal(val
.SegmentText
);
2825 wcscpy(pChar
, realVal
.getStr());
2829 case TypeClass_VOID
:
2830 case TypeClass_HYPER
:
2831 case TypeClass_UNSIGNED_HYPER
:
2832 case TypeClass_TYPE
:
2834 case TypeClass_TYPEDEF
:
2835 case TypeClass_EXCEPTION
:
2836 case TypeClass_INTERFACE
:
2837 case TypeClass_SERVICE
:
2838 case TypeClass_MODULE
:
2839 case TypeClass_INTERFACE_METHOD
:
2840 case TypeClass_INTERFACE_ATTRIBUTE
:
2841 case TypeClass_UNKNOWN
:
2842 case TypeClass_PROPERTY
:
2843 case TypeClass_CONSTANT
:
2844 case TypeClass_CONSTANTS
:
2845 case TypeClass_SINGLETON
:
2846 case TypeClass_MAKE_FIXED_SIZE
:
2853 void CMAccessible::get_OLECHAR4Numbering(const Any
& pAny
, short numberingLevel
,const OUString
& numberingPrefix
,OLECHAR
* pChar
)
2857 Reference
< css::container::XIndexReplace
> pXIndex
;
2858 if((pAny
>>=pXIndex
) && (numberingLevel
!=-1))//numbering level is -1,means invalid value
2860 Any aAny
= pXIndex
->getByIndex(numberingLevel
);
2861 Sequence
< css::beans::PropertyValue
> aProps
;
2863 const css::beans::PropertyValue
* pPropArray
= aProps
.getConstArray();
2864 sal_Int32 nCount
= aProps
.getLength();
2865 swprintf(pChar
,L
"Numbering:NumberingLevel=%d,",numberingLevel
);
2866 for( sal_Int32 i
=0; i
<nCount
; i
++ )
2868 css::beans::PropertyValue rProp
= pPropArray
[i
];
2869 if( (rProp
.Name
== "BulletChar" ) ||
2870 (rProp
.Name
== "GraphicURL" ) ||
2871 (rProp
.Name
== "NumberingType" ))
2873 OLECHAR propStr
[512] = {NULL
};
2874 swprintf(propStr
,L
"%s=",rProp
.Name
.getStr());
2875 OLECHAR pTemp
[256] = {NULL
};
2876 CMAccessible::get_OLECHARFromAny(rProp
.Value
,pTemp
);
2877 if(rProp
.Name
== "GraphicURL")
2879 OLECHAR
* pOccur
= wcschr(pTemp
,':');
2883 wcscat(propStr
,pTemp
);
2884 wcscat(pChar
,propStr
);
2887 if(rProp
.Name
== "NumberingType")
2889 if(numberingPrefix
.getLength()!=0)
2891 swprintf(pTemp
,L
"NumberingPrefix=%s,",numberingPrefix
.getStr());
2892 wcscat(pChar
,pTemp
);
2899 //Because now have three types numbering level:
2900 //1.real numbering list,numbering level>=0 and numbering Rule !=NULL;
2901 //2.common paragraph, numbering level >=0, and numbering Rule == NULL;
2902 //3.TOC paragraph, numbering level >0, and numbering Rule ==NULL;
2903 // IAText:numberinglevel base on 0, but TOC's level base on 1,
2904 // so NumberingLevel value will be decreased 1 in bridge code.
2905 else if(numberingLevel
>0)
2907 swprintf(pChar
,L
"Numbering:NumberingLevel=%d,NumberingType=4,NumberingPrefix=,",numberingLevel
-1);
2911 swprintf(pChar
,L
"Numbering:");
2915 void CMAccessible::ConvertAnyToVariant(const css::uno::Any
&rAnyVal
, VARIANT
*pvData
)
2917 if(rAnyVal
.hasValue())
2919 // Clear VARIANT variable.
2920 VariantClear(pvData
);
2922 // Set value according to value type.
2923 switch(rAnyVal
.getValueTypeClass())
2925 case TypeClass_CHAR
:
2926 pvData
->vt
= VT_UI1
;
2927 memcpy(&pvData
->bVal
, rAnyVal
.getValue(), sizeof(sal_Char
));
2930 case TypeClass_BOOLEAN
:
2931 pvData
->vt
= VT_BOOL
;
2932 memcpy(&pvData
->boolVal
, rAnyVal
.getValue(), sizeof(sal_Bool
));
2935 case TypeClass_BYTE
:
2936 pvData
->vt
= VT_UI1
;
2937 memcpy(&pvData
->bVal
, rAnyVal
.getValue(), sizeof(sal_Int8
));
2940 case TypeClass_SHORT
:
2942 memcpy(&pvData
->iVal
, rAnyVal
.getValue(), sizeof(sal_Int16
));
2945 case TypeClass_UNSIGNED_SHORT
:
2947 memcpy(&pvData
->iVal
, rAnyVal
.getValue(), sizeof(sal_uInt16
));
2950 case TypeClass_LONG
:
2952 memcpy(&pvData
->lVal
, rAnyVal
.getValue(), sizeof(sal_Int32
));
2955 case TypeClass_UNSIGNED_LONG
:
2957 memcpy(&pvData
->lVal
, rAnyVal
.getValue(), sizeof(sal_uInt32
));
2960 case TypeClass_FLOAT
:
2962 memcpy(&pvData
->fltVal
, rAnyVal
.getValue(), sizeof(float));
2965 case TypeClass_DOUBLE
:
2967 memcpy(&pvData
->dblVal
, rAnyVal
.getValue(), sizeof(double));
2970 case TypeClass_STRING
:
2972 pvData
->vt
= VT_BSTR
;
2973 ::rtl::OUString val
;
2975 pvData
->bstrVal
= SysAllocString((OLECHAR
*)val
.getStr());
2979 case TypeClass_VOID
:
2980 case TypeClass_HYPER
:
2981 case TypeClass_UNSIGNED_HYPER
:
2982 case TypeClass_TYPE
:
2984 case TypeClass_ENUM
:
2985 case TypeClass_TYPEDEF
:
2986 case TypeClass_STRUCT
:
2987 case TypeClass_EXCEPTION
:
2988 case TypeClass_SEQUENCE
:
2989 case TypeClass_INTERFACE
:
2991 Reference
< XAccessible
> pXAcc
;
2992 if(rAnyVal
>>= pXAcc
)
2996 IAccessible
* pIAcc
= NULL
;
2997 get_IAccessibleFromXAccessible(pXAcc
.get(), &pIAcc
);
3000 Reference
< XAccessibleContext
> pXAccContext
= pXAcc
->getAccessibleContext();
3001 g_pAgent
->InsertAccObj(pXAcc
.get(),pXAccContext
->getAccessibleParent().get());
3002 get_IAccessibleFromXAccessible(pXAcc
.get(), &pIAcc
);
3008 pvData
->vt
= VT_UNKNOWN
;
3009 pvData
->pdispVal
= (IAccessible2
*)pIAcc
;
3016 case TypeClass_SERVICE
:
3017 case TypeClass_MODULE
:
3018 case TypeClass_INTERFACE_METHOD
:
3019 case TypeClass_INTERFACE_ATTRIBUTE
:
3020 case TypeClass_UNKNOWN
:
3021 case TypeClass_PROPERTY
:
3022 case TypeClass_CONSTANT
:
3023 case TypeClass_CONSTANTS
:
3024 case TypeClass_SINGLETON
:
3025 case TypeClass_MAKE_FIXED_SIZE
:
3026 // Output the type string, if there is other uno value type.
3027 pvData
->vt
= VT_BSTR
;
3028 pvData
->bstrVal
= SysAllocString(rAnyVal
.getValueTypeName().getStr());
3037 VariantClear(pvData
);
3041 STDMETHODIMP
CMAccessible::Get_XAccChildID(long* childID
)
3043 // internal IMAccessible - no mutex meeded
3049 *childID
= m_dChildID
;
3053 STDMETHODIMP
CMAccessible:: get_states(AccessibleStates __RPC_FAR
*states
)
3057 ENTER_PROTECTED_BLOCK
3060 if (!m_xContext
.is())
3063 Reference
<XAccessibleStateSet
> const pRStateSet
=
3064 m_xContext
.get()->getAccessibleStateSet();
3065 if(!pRStateSet
.is())
3069 Sequence
<short> pStates
= pRStateSet
->getStates();
3072 long count
= pStates
.getLength() ;
3074 for( int i
= 0; i
< count
; i
++ )
3076 for( std::size_t j
= 0; j
< SAL_N_ELEMENTS(UNO_STATES
); j
++ )
3078 if( pStates
[i
] == UNO_STATES
[j
] )
3080 *states
|= IA2_STATES
[j
];
3088 LEAVE_PROTECTED_BLOCK
3091 // return the UNO roles
3092 STDMETHODIMP
CMAccessible:: get_extendedRole( BSTR __RPC_FAR
* )
3097 STDMETHODIMP
CMAccessible:: get_localizedExtendedRole( BSTR __RPC_FAR
* )
3102 STDMETHODIMP
CMAccessible:: get_nExtendedStates( long __RPC_FAR
* )
3108 STDMETHODIMP
CMAccessible:: get_localizedExtendedStates( long, BSTR __RPC_FAR
*__RPC_FAR
*, long __RPC_FAR
*)
3114 STDMETHODIMP
CMAccessible:: get_indexInParent( long __RPC_FAR
*accParentIndex
)
3116 ENTER_PROTECTED_BLOCK
3119 if(accParentIndex
== NULL
)
3120 return E_INVALIDARG
;
3122 if (!m_xContext
.is())
3125 *accParentIndex
= m_xContext
.get()->getAccessibleIndexInParent();
3129 LEAVE_PROTECTED_BLOCK
3131 STDMETHODIMP
CMAccessible:: get_locale( IA2Locale __RPC_FAR
*locale
)
3133 ENTER_PROTECTED_BLOCK
3136 return E_INVALIDARG
;
3138 if (!m_xContext
.is())
3141 css::lang::Locale unoLoc
= m_xContext
.get()->getLocale();
3142 locale
->language
= SysAllocString((OLECHAR
*)unoLoc
.Language
.getStr());
3143 locale
->country
= SysAllocString((OLECHAR
*)unoLoc
.Country
.getStr());
3144 locale
->variant
= SysAllocString((OLECHAR
*)unoLoc
.Variant
.getStr());
3148 LEAVE_PROTECTED_BLOCK
3151 DWORD
GetMSAAStateFromUNO(short xState
)
3153 DWORD IState
= STATE_SYSTEM_UNAVAILABLE
;
3156 case /*AccessibleStateType::*/AccessibleStateType::BUSY
:
3157 IState
= STATE_SYSTEM_BUSY
;
3159 case /*AccessibleStateType::*/AccessibleStateType::CHECKED
:
3160 IState
= STATE_SYSTEM_CHECKED
;
3162 case /*AccessibleStateType::*/AccessibleStateType::DEFUNC
:
3163 IState
= STATE_SYSTEM_UNAVAILABLE
;
3165 case /*AccessibleStateType::*/AccessibleStateType::EXPANDED
:
3166 IState
= STATE_SYSTEM_EXPANDED
;
3168 case /*AccessibleStateType::*/AccessibleStateType::FOCUSABLE
:
3169 IState
= STATE_SYSTEM_FOCUSABLE
;
3171 case /*AccessibleStateType::*/AccessibleStateType::FOCUSED
:
3172 IState
= STATE_SYSTEM_FOCUSED
;
3174 case /*AccessibleStateType::*/AccessibleStateType::INDETERMINATE
:
3175 IState
= STATE_SYSTEM_MIXED
;
3177 case /*AccessibleStateType::*/AccessibleStateType::MULTI_SELECTABLE
:
3178 IState
= STATE_SYSTEM_MULTISELECTABLE
;
3180 case /*AccessibleStateType::*/AccessibleStateType::PRESSED
:
3181 IState
= STATE_SYSTEM_PRESSED
;
3183 case /*AccessibleStateType::*/AccessibleStateType::RESIZABLE
:
3184 IState
= STATE_SYSTEM_SIZEABLE
;
3186 case /*AccessibleStateType::*/AccessibleStateType::SELECTABLE
:
3187 IState
= STATE_SYSTEM_SELECTABLE
;
3189 case /*AccessibleStateType::*/AccessibleStateType::SELECTED
:
3190 IState
= STATE_SYSTEM_SELECTED
;
3192 case /*AccessibleStateType::*/AccessibleStateType::ARMED
:
3193 IState
= STATE_SYSTEM_FOCUSED
;
3195 case /*AccessibleStateType::*/AccessibleStateType::EXPANDABLE
:
3196 IState
= STATE_SYSTEM_COLLAPSED
;
3204 STDMETHODIMP
CMAccessible:: get_appName( BSTR __RPC_FAR
*name
)
3208 ENTER_PROTECTED_BLOCK
3211 return E_INVALIDARG
;
3213 *name
= SysAllocString(OLESTR("Hannover"));
3215 LEAVE_PROTECTED_BLOCK
3217 STDMETHODIMP
CMAccessible:: get_appVersion(BSTR __RPC_FAR
*version
)
3221 ENTER_PROTECTED_BLOCK
3224 return E_INVALIDARG
;
3225 *version
=SysAllocString(OLESTR("3.0"));
3227 LEAVE_PROTECTED_BLOCK
3229 STDMETHODIMP
CMAccessible:: get_toolkitName(BSTR __RPC_FAR
*name
)
3233 ENTER_PROTECTED_BLOCK
3236 return E_INVALIDARG
;
3237 *name
= SysAllocString(OLESTR(" "));
3239 LEAVE_PROTECTED_BLOCK
3241 STDMETHODIMP
CMAccessible:: get_toolkitVersion(BSTR __RPC_FAR
*version
)
3245 ENTER_PROTECTED_BLOCK
3248 return E_INVALIDARG
;
3249 *version
= SysAllocString(OLESTR(" "));
3251 LEAVE_PROTECTED_BLOCK
3255 STDMETHODIMP
CMAccessible::get_attributes(/*[out]*/ BSTR
*pAttr
)
3259 ENTER_PROTECTED_BLOCK
3262 if (!m_xAccessible
.is())
3265 Reference
<XAccessibleContext
> pRContext
= m_xAccessible
->getAccessibleContext();
3266 if( !pRContext
.is() )
3270 Reference
<XAccessibleExtendedAttributes
> pRXI(pRContext
,UNO_QUERY
);
3275 css::uno::Reference
<css::accessibility::XAccessibleExtendedAttributes
> pRXAttr
;
3276 pRXAttr
= pRXI
.get();
3277 css::uno::Any anyVal
= pRXAttr
->getExtendedAttributes();
3279 ::rtl::OUString val
;
3283 SAFE_SYSFREESTRING(*pAttr
);
3284 *pAttr
= SysAllocString((OLECHAR
*)val
.getStr());
3288 LEAVE_PROTECTED_BLOCK
3291 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */