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 .
22 #include "MAccessible.h"
25 #include "AccAction.h"
26 #include "AccRelation.h"
27 #include "AccComponent.h"
29 #include "AccEditableText.h"
33 #include "AccHypertext.h"
34 #include "AccHyperLink.h"
36 #include <vcl/svapp.hxx>
38 #include <com/sun/star/accessibility/XAccessibleText.hpp>
39 #include <com/sun/star/accessibility/XAccessibleEditableText.hpp>
40 #include <com/sun/star/accessibility/XAccessibleImage.hpp>
41 #include <com/sun/star/accessibility/XAccessibleTable.hpp>
42 #include <com/sun/star/accessibility/XAccessibleExtendedComponent.hpp>
43 #include <com/sun/star/accessibility/XAccessibleAction.hpp>
44 #include <com/sun/star/accessibility/XAccessibleKeyBinding.hpp>
45 #include <com/sun/star/accessibility/XAccessibleHyperText.hpp>
46 #include <com/sun/star/accessibility/XAccessibleHyperlink.hpp>
47 #include <com/sun/star/accessibility/XAccessibleRelationSet.hpp>
48 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
49 #include <com/sun/star/accessibility/AccessibleRole.hpp>
50 #include <com/sun/star/accessibility/XAccessibleGroupPosition.hpp>
51 #include <com/sun/star/accessibility/XAccessibleValue.hpp>
52 #include <com/sun/star/accessibility/XAccessibleExtendedAttributes.hpp>
53 #include <com/sun/star/style/LineSpacing.hpp>
54 #include <com/sun/star/style/TabStop.hpp>
55 #include <com/sun/star/container/XIndexReplace.hpp>
58 using namespace com::sun::star::uno
;
59 using namespace com::sun::star::accessibility
;
60 using namespace com::sun::star::accessibility::AccessibleStateType
;
62 enum XInterfaceIndex
{
66 XI_EDITABLETEXT
= 0x04,
69 XI_EXTENDEDCOMP
= 0x07,
79 // IA2 states mapping, and name
80 // maintenance the consistency, change one array, change the three all
83 IA2_STATE_ACTIVE
, // = 0x1;
84 IA2_STATE_ARMED
, // = 0x2;
85 IA2_STATE_DEFUNCT
, // = 0x4;
86 IA2_STATE_EDITABLE
, // = 0x8;
87 IA2_STATE_HORIZONTAL
, // = 0x10;
88 IA2_STATE_ICONIFIED
, // = 0x20;
89 IA2_STATE_INVALID_ENTRY
, // = 0x80;
90 IA2_STATE_MANAGES_DESCENDANTS
, // = 0x100;
91 IA2_STATE_MODAL
, // = 0x200;
92 IA2_STATE_MULTI_LINE
, // = 0x400;
93 IA2_STATE_OPAQUE
, // = 0x800;
94 IA2_STATE_REQUIRED
, // = 0x2000;
95 IA2_STATE_SELECTABLE_TEXT
, // = 0x3000;
96 IA2_STATE_SINGLE_LINE
, // = 0x4000;
97 IA2_STATE_STALE
, // = 0x8000;
98 IA2_STATE_SUPPORTS_AUTOCOMPLETION
, // = 0x10000;
99 IA2_STATE_TRANSIENT
, //= 0x20000;
100 IA2_STATE_VERTICAL
// = 0x40000;
109 ACTIVE
, // = (sal_Int16)1;
110 ARMED
, // = (sal_Int16)2;
111 DEFUNC
, // = (sal_Int16)5;
112 EDITABLE
, // = (sal_Int16)6;
113 HORIZONTAL
, // = (sal_Int16)12;
114 ICONIFIED
, // = (sal_Int16)13;
115 -1, //IA2_STATE_INVALID_ENTRY
116 MANAGES_DESCENDANTS
, // = (sal_Int16)15;
117 MODAL
, // = (sal_Int16)16;
118 MULTI_LINE
, // = (sal_Int16)17;
119 OPAQUE
, // = (sal_Int16)19;
120 -1, //IA2_STATE_REQUIRED
121 -1, //IA2_STATE_SELECTABLE_TEXT
122 SINGLE_LINE
, // = (sal_Int16)26;
123 STALE
, // = (sal_Int16)27;
124 -1, //IA2_STATE_SUPPORTS_AUTOCOMPLETION
125 TRANSIENT
, //IA2_STATE_TRANSIENT
126 VERTICAL
// = (sal_Int16)29;
131 BSTR IA2_STATES_NAME
[] =
140 _T("Manages Descendants"),
145 _T("Selectable Text"),
148 _T("Supports Autocompletion"),
153 // IA2 states mapping, and name
154 // maintenance the consistency. change one, change them all
156 BSTR UNO_ALL_STATES
[] =
158 _T("INVALID"), // INVALID ( 0 )
159 _T("ACTIVE"), // ACTIVE ( 1 )
160 _T("ARMED"), // ARMED ( 2 )
161 _T("BUSY"), // BUSY ( 3 )
162 _T("CHECKED"), // CHECKED ( 4 )
163 _T("DEFUNC"), // DEFUNC ( 5 )
164 _T("EDITABLE"), // EDITABLE ( 6 )
165 _T("ENABLED"), // ENABLED ( 7 )
166 _T("EXPANDABLE"), // EXPANDABLE ( 8 )
167 _T("EXPANDED"), // EXPANDED ( 9 )
168 _T("FOCUSABLE"), // FOCUSABLE ( 10 )
169 _T("FOCUSED"), // FOCUSED ( 11 )
170 _T("HORIZONTAL"), // HORIZONTAL ( 12 )
171 _T("ICONIFIED"), // ICONIFIED ( 13 )
172 _T("INDETERMINATE"), // INDETERMINATE ( 14 )
173 _T("MANAGES_DESCENDANTS"),// MANAGES_DESCENDANTS ( 15 )
174 _T("MODAL"), // MODAL ( 16 )
175 _T("MULTI_LINE"), // MULTI_LINE ( 17 )
176 _T("MULTI_SELECTABLE"), // MULTI_SELECTABLE ( 18 )
177 _T("OPAQUE"), // OPAQUE ( 19 )
178 _T("PRESSED"), // PRESSED ( 20 )
179 _T("RESIZABLE"), // RESIZABLE ( 21 )
180 _T("SELECTABLE"), // SELECTABLE ( 22 )
181 _T("SELECTED"), // SELECTED ( 23 )
182 _T("SENSITIVE"), // SENSITIVE ( 24 )
183 _T("SHOWING"), // SHOWING ( 25 )
184 _T("SINGLE_LINE"), // SINGLE_LINE ( 26 )
185 _T("STALE"), // STALE ( 27 )
186 _T("TRANSIENT"), // TRANSIENT ( 28 )
187 _T("VERTICAL"), // VERTICAL ( 29 )
188 _T("VISIBLE"), // VISIBLE ( 30 )
189 _T("MOVEABLE"), // MOVEABLE ( 31 )
190 _T("OFFSCREEN"), // OFFSCREEN ( 32 )
191 _T("COLLAPSE"), // COLLAPSE ( 33 )
192 _T("DEFAULT") // DEFAULT ( 34 )
196 using namespace com::sun::star::accessibility::AccessibleRole
;
200 #define QUERYXINTERFACE(ainterface) \
204 pRContext = pXAcc->getAccessibleContext(); \
205 if( !pRContext.is() ) \
209 Reference<X##ainterface> pRXI(pRContext,UNO_QUERY);\
214 *ppXI = (XInterface*)pRXI.get(); \
218 #define ISDESTROY() \
223 AccObjectManagerAgent
* CMAccessible::g_pAgent
= NULL
;
225 CMAccessible::CMAccessible():
229 m_dFocusChildID(UACC_NO_FOCUS
),
234 m_pszDescription(NULL
),
236 m_pszActionDescription(NULL
),
237 m_bRequiresSave(FALSE
)
239 m_sLocation
.m_dLeft
=0;
240 m_sLocation
.m_dTop
= 0;
241 m_sLocation
.m_dWidth
=0;
242 m_sLocation
.m_dHeight
=0;
243 CEnumVariant::Create(&m_pEnumVar
);
244 m_containedObjects
.clear();
247 CMAccessible::~CMAccessible()
253 SAFE_SYSFREESTRING(m_pszName
);
258 SAFE_SYSFREESTRING(m_pszValue
);
261 if(m_pszDescription
!=NULL
)
263 SAFE_SYSFREESTRING(m_pszDescription
);
264 m_pszDescription
=NULL
;
267 if(m_pszActionDescription
!=NULL
)
269 SAFE_SYSFREESTRING(m_pszActionDescription
);
270 m_pszActionDescription
=NULL
;
275 m_pIParent
->Release();
278 m_pEnumVar
->Release();
279 m_containedObjects
.clear();
283 * Returns the Parent IAccessible interface pointer to AT.
284 * It should add reference, and the client should release the component.
285 * It should return E_FAIL when the parent point is null.
286 * @param ppdispParent [in,out] used to return the parent interface point.
287 * when the point is null, should return null.
288 * @return S_OK if successful and E_FAIL if the m_pIParent is NULL.
290 STDMETHODIMP
CMAccessible::get_accParent(IDispatch
**ppdispParent
)
294 ENTER_PROTECTED_BLOCK
297 if(ppdispParent
== NULL
)
304 *ppdispParent
= m_pIParent
;
305 (*ppdispParent
)->AddRef();
310 HRESULT hr
= AccessibleObjectFromWindow(m_hwnd
, OBJID_WINDOW
, IID_IAccessible
, (void**)ppdispParent
);
311 if( ! SUCCEEDED( hr
) || ! ppdispParent
)
319 LEAVE_PROTECTED_BLOCK
323 * Returns child count of current COM object.
324 * @param pcountChildren [in,out] used to return the children count.
325 * @return S_OK if successful.
327 STDMETHODIMP
CMAccessible::get_accChildCount(long *pcountChildren
)
331 ENTER_PROTECTED_BLOCK
334 if(pcountChildren
== NULL
)
339 if (!m_xAccessible
.is())
342 Reference
<XAccessibleContext
> const pRContext
=
343 m_xAccessible
->getAccessibleContext();
346 *pcountChildren
= pRContext
->getAccessibleChildCount();
351 LEAVE_PROTECTED_BLOCK
355 * Returns child interface pointer for AT according to input child ID.
356 * @param varChild, vt member of varChild must be VT_I4,and lVal member stores the child ID,
357 * the child ID specify child index from 0 to children count, 0 stands for object self.
358 * @param ppdispChild, [in,out] use to return the child interface point.
359 * @return S_OK if successful and S_FALSE if failure.
361 STDMETHODIMP
CMAccessible::get_accChild(VARIANT varChild
, IDispatch
**ppdispChild
)
365 ENTER_PROTECTED_BLOCK
368 if(ppdispChild
== NULL
)
372 if(varChild
.vt
==VT_I4
)
374 //get child interface pointer due to child ID
375 if(varChild
.lVal
==CHILDID_SELF
)
381 *ppdispChild
= GetChildInterface(varChild
.lVal
);
382 if((*ppdispChild
) == NULL
)
384 (*ppdispChild
)->AddRef();
389 LEAVE_PROTECTED_BLOCK
393 * Returns the accessible name of the current COM object self or its one child to AT.
394 * @param varChild, vt member of varChild must be VT_I4,and lVal member stores the child ID,
395 * the child ID specify child index from 0 to children count, 0 stands for object self.
396 * @param pszName, [in,out] use to return the name of the proper object.
397 * @return S_OK if successful and S_FALSE if failure.
399 STDMETHODIMP
CMAccessible::get_accName(VARIANT varChild
, BSTR
*pszName
)
403 ENTER_PROTECTED_BLOCK
410 if(varChild
.vt
==VT_I4
)
412 if(varChild
.lVal
==CHILDID_SELF
)
414 SAFE_SYSFREESTRING(*pszName
);
415 *pszName
= SysAllocString(m_pszName
);
419 long lVal
= varChild
.lVal
;
420 varChild
.lVal
= CHILDID_SELF
;
421 IMAccessible
*pChild
= this->GetChildInterface(lVal
);
424 return pChild
->get_accName(varChild
,pszName
);
428 LEAVE_PROTECTED_BLOCK
432 * Returns the accessible value of the current COM object self or its one child to AT.
433 * @param varChild, vt member of varChild must be VT_I4,and lVal member stores the child ID,
434 * the child ID specify child index from 0 to children count, 0 stands for object self.
435 * @param pszValue, [in,out] use to return the value of the proper object.
436 * @return S_OK if successful and S_FALSE if failure.
438 STDMETHODIMP
CMAccessible::get_accValue(VARIANT varChild
, BSTR
*pszValue
)
442 ENTER_PROTECTED_BLOCK
445 if( pszValue
== NULL
)
449 if( varChild
.vt
==VT_I4
)
451 if(varChild
.lVal
==CHILDID_SELF
)
453 if(m_dState
& STATE_SYSTEM_PROTECTED
)
454 return E_ACCESSDENIED
;
456 if ( m_pszValue
!=NULL
&& wcslen(m_pszValue
) == 0 )
459 SAFE_SYSFREESTRING(*pszValue
);
460 *pszValue
= SysAllocString(m_pszValue
);
464 long lVal
= varChild
.lVal
;
465 varChild
.lVal
= CHILDID_SELF
;
466 IMAccessible
*pChild
= this->GetChildInterface(lVal
);
469 return pChild
->get_accValue(varChild
,pszValue
);
473 LEAVE_PROTECTED_BLOCK
477 * Returns the accessible description of the current COM object self or its one child to AT.
478 * @param varChild, vt member of varChild must be VT_I4,and lVal member stores the child ID,
479 * the child ID specify child index from 0 to children count, 0 stands for object self.
480 * @param pszDescription, [in,out] use to return the description of the proper object.
481 * @return S_OK if successful and E_FAIL if failure.
483 STDMETHODIMP
CMAccessible::get_accDescription(VARIANT varChild
, BSTR
*pszDescription
)
487 ENTER_PROTECTED_BLOCK
490 if(pszDescription
== NULL
)
494 if(varChild
.vt
==VT_I4
)
496 if(varChild
.lVal
==CHILDID_SELF
)
498 SAFE_SYSFREESTRING(*pszDescription
);
499 *pszDescription
= SysAllocString(m_pszDescription
);
503 long lVal
= varChild
.lVal
;
504 varChild
.lVal
= CHILDID_SELF
;
505 IMAccessible
*pChild
= this->GetChildInterface(lVal
);
508 return pChild
->get_accDescription(varChild
,pszDescription
);
512 LEAVE_PROTECTED_BLOCK
516 * Returns the accessible role of the current COM object self or its one child to AT.
517 * @param varChild, vt member of varChild must be VT_I4,and lVal member stores the child ID,
518 * the child ID specify child index from 0 to children count, 0 stands for object self.
519 * @param pvarRole, [in,out] use to return the role of the proper object.
520 * @return S_OK if successful and S_FALSE if failure.
522 STDMETHODIMP
CMAccessible::get_accRole(VARIANT varChild
, VARIANT
*pvarRole
)
526 ENTER_PROTECTED_BLOCK
533 if(varChild
.vt
== VT_I4
)
536 if(varChild
.lVal
== CHILDID_SELF
)
538 if( m_iRole
< IA2_ROLE_CAPTION
)
540 VariantInit(pvarRole
);
541 pvarRole
->vt
= VT_I4
;
542 pvarRole
->lVal
= m_iRole
;
546 VariantInit(pvarRole
);
547 pvarRole
->vt
= VT_I4
;
548 pvarRole
->lVal
= ROLE_SYSTEM_CLIENT
;
554 long lVal
= varChild
.lVal
;
555 varChild
.lVal
= CHILDID_SELF
;
556 IMAccessible
*pChild
= this->GetChildInterface(lVal
);
559 return pChild
->get_accRole(varChild
,pvarRole
);
563 LEAVE_PROTECTED_BLOCK
567 * Returns the accessible state of the current COM object self or its one child to AT.
568 * @param varChild, vt member of varChild must be VT_I4,and lVal member stores the child ID,
569 * the child ID specify child index from 0 to children count, 0 stands for object self.
570 * @param pvarState, [in,out] use to return the state of the proper object.
571 * @return S_OK if successful and S_FALSE if failure.
573 STDMETHODIMP
CMAccessible::get_accState(VARIANT varChild
, VARIANT
*pvarState
)
577 ENTER_PROTECTED_BLOCK
580 if(pvarState
== NULL
)
584 if(varChild
.vt
==VT_I4
)
586 if(varChild
.lVal
== CHILDID_SELF
)
588 if (m_xAccessible
.is())
590 Reference
<XAccessibleContext
> const pContext
=
591 m_xAccessible
->getAccessibleContext();
594 // add the STATE_SYSTEM_LINKED state
595 Reference
< XAccessibleHypertext
> pRHypertext(pContext
,UNO_QUERY
);
598 if( pRHypertext
->getHyperLinkCount() > 0 )
599 m_dState
|= STATE_SYSTEM_LINKED
;
601 m_dState
&= ~STATE_SYSTEM_LINKED
;
604 m_dState
&= ~STATE_SYSTEM_LINKED
;
608 VariantInit(pvarState
);
609 pvarState
->vt
= VT_I4
;
610 pvarState
->lVal
= m_dState
;
614 long lVal
= varChild
.lVal
;
615 varChild
.lVal
= CHILDID_SELF
;
616 IMAccessible
*pChild
= this->GetChildInterface(lVal
);
619 return pChild
->get_accState(varChild
,pvarState
);
623 LEAVE_PROTECTED_BLOCK
627 * Returns the accessible helpString of the current COM object self or its one child to AT.
628 * @param varChild, vt member of varChild must be VT_I4,and lVal member stores the child ID,
629 * the child ID specify child index from 0 to children count, 0 stands for object self.
630 * @param pszHelp, [in,out] use to return the helpString of the proper object.
631 * @return S_OK if successful and E_FAIL if failure.
633 STDMETHODIMP
CMAccessible::get_accHelp(VARIANT
, BSTR
*)
639 * Returns the accessible HelpTopic of the current COM object self or its one child to AT.
640 * @param varChild, vt member of varChild must be VT_I4,and lVal member stores the child ID,
641 * the child ID specify child index from 0 to children count, 0 stands for object self.
642 * @param pszHelpFile, [in,out] use to return the HelpTopic of the proper object.
643 * @param pidTopic, use to return the HelpTopic ID of the proper object.
644 * @return S_OK if successful and E_FAIL if failure.
645 * Not implemented yet
647 STDMETHODIMP
CMAccessible::get_accHelpTopic(BSTR
*, VARIANT
, long *)
652 static void GetMnemonicChar( const ::rtl::OUString
& aStr
, WCHAR
* wStr
)
654 int nLen
= aStr
.pData
->length
;
656 WCHAR
* text
= aStr
.pData
->buffer
;
660 if ( text
[i
] == L
'~' )
661 if ( text
[i
+1] != L
'~' )
671 * Returns the accessible keyboard shortcut of the current COM object self or its one child to AT.
672 * @param varChild, vt member of varChild must be VT_I4,and lVal member stores the child ID,
673 * the child ID specify child index from 0 to children count, 0 stands for object self.
674 * @param pszKeyboardShortcut, [in,out] use to return the kbshortcut of the proper object.
675 * @return S_OK if successful and E_FAIL if failure.
677 STDMETHODIMP
CMAccessible::get_accKeyboardShortcut(VARIANT varChild
, BSTR
*pszKeyboardShortcut
)
681 ENTER_PROTECTED_BLOCK
685 if(pszKeyboardShortcut
== NULL
)
690 if(varChild
.vt
==VT_I4
)
692 if(varChild
.lVal
== CHILDID_SELF
)
694 if (m_xAccessible
.is())
696 Reference
<XAccessibleContext
> const pRContext
=
697 m_xAccessible
->getAccessibleContext();
698 if( !pRContext
.is() )
701 Reference
<XAccessibleAction
> pRXI(pRContext
,UNO_QUERY
);
703 OLECHAR wString
[64]={0};
705 if( pRXI
.is() && pRXI
->getAccessibleActionCount() >= 1)
707 Reference
< XAccessibleKeyBinding
> binding
= pRXI
->getAccessibleActionKeyBinding(0);
710 long nCount
= binding
->getAccessibleKeyBindingCount();
713 CAccAction::GetkeyBindingStrByXkeyBinding( binding
->getAccessibleKeyBinding(0),wString
);
719 Reference
<XAccessibleRelationSet
> pRrelationSet
= pRContext
->getAccessibleRelationSet();
720 if(!pRrelationSet
.is())
725 long nRelCount
= pRrelationSet
->getRelationCount();
727 // Modified by Steve Yin, for SODC_1552
728 if( /*nRelCount <= 0 &&*/ m_iRole
== ROLE_SYSTEM_TEXT
)
730 VARIANT varParentRole
;
731 VariantInit( &varParentRole
);
733 m_pIParent
->get_accRole(varChild
, &varParentRole
);
735 if( m_pIParent
&& varParentRole
.lVal
== ROLE_SYSTEM_COMBOBOX
) // edit in comoboBox
737 m_pIParent
->get_accKeyboardShortcut(varChild
, pszKeyboardShortcut
);
742 AccessibleRelation
*paccRelation
= NULL
;
743 AccessibleRelation accRelation
;
744 for(int i
=0; i
<nRelCount
; i
++)
746 if( pRrelationSet
->getRelation(i
).RelationType
== 6 )
748 accRelation
= pRrelationSet
->getRelation(i
);
749 paccRelation
= &accRelation
;
753 if(paccRelation
== NULL
)
756 Sequence
< Reference
< XInterface
> > xTargets
= paccRelation
->TargetSet
;
757 Reference
<XInterface
> pRAcc
= xTargets
[0];
759 XAccessible
* pXAcc
= (XAccessible
*)pRAcc
.get();
761 Reference
<XAccessibleContext
> pRLebelContext
= pXAcc
->getAccessibleContext();
762 if(!pRLebelContext
.is())
765 pRrelationSet
= pRLebelContext
->getAccessibleRelationSet();
766 nRelCount
= pRrelationSet
->getRelationCount();
769 for(int j
=0; j
<nRelCount
; j
++)
771 if( pRrelationSet
->getRelation(j
).RelationType
== 5 )
773 accRelation
= pRrelationSet
->getRelation(j
);
774 paccRelation
= &accRelation
;
780 xTargets
= paccRelation
->TargetSet
;
782 if (m_xAccessible
.get() != (XAccessible
*)pRAcc
.get())
786 Reference
<XAccessibleExtendedComponent
> pRXIE(pRLebelContext
,UNO_QUERY
);
790 ::rtl::OUString ouStr
= pRXIE
->getTitledBorderText();
791 WCHAR key
[2] = {NULL
};
792 GetMnemonicChar(ouStr
, key
);
795 wcscat(wString
, L
"Alt+");
796 wcscat(wString
, key
);
802 SAFE_SYSFREESTRING(*pszKeyboardShortcut
);
803 *pszKeyboardShortcut
= SysAllocString(wString
);
813 long lVal
= varChild
.lVal
;
814 varChild
.lVal
= CHILDID_SELF
;
815 IMAccessible
*pChild
= this->GetChildInterface(lVal
);
819 return pChild
->get_accKeyboardShortcut(varChild
,pszKeyboardShortcut
);
823 LEAVE_PROTECTED_BLOCK
827 * Returns the current focused child to AT.
828 * @param pvarChild, [in,out] vt member of pvarChild must be VT_I4,and lVal member stores the child ID,
829 * the child ID specify child index from 0 to children count, 0 stands for object self.
830 * @return S_OK if successful and E_FAIL if failure.
832 STDMETHODIMP
CMAccessible::get_accFocus(VARIANT
*pvarChild
)
836 ENTER_PROTECTED_BLOCK
839 if(pvarChild
== NULL
)
843 if( m_dFocusChildID
==UACC_NO_FOCUS
)
845 pvarChild
->vt
= VT_EMPTY
;//no focus on the object and its children
848 //if the descendant of current object has focus indicated by m_dFocusChildID, return the IDispatch of this focused object
851 IMAccessible
* pIMAcc
= NULL
;
852 g_pAgent
->GetIAccessibleFromResID(m_dFocusChildID
,&pIMAcc
);
854 pvarChild
->vt
= VT_DISPATCH
;
855 pvarChild
->pdispVal
= pIMAcc
;
860 LEAVE_PROTECTED_BLOCK
864 * Returns the selection of the current COM object to AT.
865 * @param pvarChildren,[in,out]
866 * if selection num is 0,return VT_EMPTY for vt,
867 * if selection num is 1,return VT_I4 for vt,and child index for lVal
868 * if selection num >1,return VT_UNKNOWN for vt, and IEnumVariant* for punkVal
869 * @return S_OK if successful and S_FALSE if failure.
871 STDMETHODIMP
CMAccessible::get_accSelection(VARIANT
*pvarChildren
)
875 ENTER_PROTECTED_BLOCK
878 if(pvarChildren
== NULL
)
882 switch(m_pEnumVar
->GetCountOfElements())
885 pvarChildren
->vt
= VT_EMPTY
;
890 VariantInit(&varTmp
[0]);
891 m_pEnumVar
->Next(1,varTmp
,&count
);
894 pvarChildren
->vt
= VT_I4
;
895 pvarChildren
->lVal
= varTmp
[0].lVal
;
896 VariantClear(&varTmp
[0]);
900 pvarChildren
->vt
= VT_UNKNOWN
;
901 m_pEnumVar
->AddRef();
902 pvarChildren
->punkVal
= m_pEnumVar
;
907 LEAVE_PROTECTED_BLOCK
911 * Returns the location of the current COM object self or its one child to AT.
912 * @param varChild, vt member of varChild must be VT_I4,and lVal member stores the child ID,
913 * the child ID specify child index from 0 to children count, 0 stands for object self.
914 * @param pxLeft, [in,out] use to return the x-coordination of the proper object.
915 * @param pyTop, [in,out] use to return the y-coordination of the proper object.
916 * @param pcxWidth, [in,out] use to return the x-coordination width of the proper object.
917 * @param pcyHeight, [in,out] use to return the y-coordination height of the proper object.
918 * @return S_OK if successful and S_FALSE if failure.
920 STDMETHODIMP
CMAccessible::accLocation(long *pxLeft
, long *pyTop
, long *pcxWidth
, long *pcyHeight
, VARIANT varChild
)
924 ENTER_PROTECTED_BLOCK
927 if(pxLeft
== NULL
|| pyTop
== NULL
|| pcxWidth
== NULL
|| pcyHeight
== NULL
)
932 if(varChild
.vt
==VT_I4
)
934 if(varChild
.lVal
==CHILDID_SELF
)
937 if (m_xAccessible
.is())
939 Reference
<XAccessibleContext
> const pRContext
=
940 m_xAccessible
->getAccessibleContext();
941 if( !pRContext
.is() )
943 Reference
< XAccessibleComponent
> pRComponent(pRContext
,UNO_QUERY
);
944 if( !pRComponent
.is() )
947 ::com::sun::star::awt::Point pCPoint
= pRComponent
->getLocationOnScreen();
948 ::com::sun::star::awt::Size pCSize
= pRComponent
->getSize();
951 *pcxWidth
= pCSize
.Width
;
952 *pcyHeight
= pCSize
.Height
;
957 *pxLeft
= m_sLocation
.m_dLeft
;
958 *pyTop
= m_sLocation
.m_dTop
;
959 *pcxWidth
= m_sLocation
.m_dWidth
;
960 *pcyHeight
= m_sLocation
.m_dHeight
;
968 LEAVE_PROTECTED_BLOCK
972 * Returns the current focused child to AT.
973 * @param navDir, the direction flag of the navigation.
974 * @param varStart, the start child id of this navigation action.
975 * @param pvarEndUpAt, [in,out] the end up child of this navigation action.
976 * @return S_OK if successful and E_FAIL if failure.
978 STDMETHODIMP
CMAccessible::accNavigate(long navDir
, VARIANT varStart
, VARIANT
*pvarEndUpAt
)
982 ENTER_PROTECTED_BLOCK
985 if(pvarEndUpAt
== NULL
)
989 HRESULT ret
= E_FAIL
;
992 case NAVDIR_FIRSTCHILD
:
993 ret
= GetFirstChild(varStart
,pvarEndUpAt
);
995 case NAVDIR_LASTCHILD
:
996 ret
= GetLastChild(varStart
,pvarEndUpAt
);
999 ret
= GetNextSibling(varStart
,pvarEndUpAt
);
1001 case NAVDIR_PREVIOUS
:
1002 ret
= GetPreSibling(varStart
,pvarEndUpAt
);
1004 case NAVDIR_DOWN
://do not implement temporarily
1006 case NAVDIR_UP
://do not implement temporarily
1008 case NAVDIR_LEFT
://do not implement temporarily
1010 case NAVDIR_RIGHT
://do not implement temporarily
1017 LEAVE_PROTECTED_BLOCK
1020 STDMETHODIMP
CMAccessible::accHitTest(long xLeft
, long yTop
, VARIANT
*pvarChild
)
1024 ENTER_PROTECTED_BLOCK
1027 if(pvarChild
== NULL
)
1029 return E_INVALIDARG
;
1033 VariantInit(&varSelf
);
1035 varSelf
.lVal
= CHILDID_SELF
;
1036 accLocation(&x
,&y
,&w
,&h
,varSelf
);
1037 if( (x
< xLeft
&& (x
+ w
) >xLeft
) && (y
< yTop
&& (y
+ h
) >yTop
) )
1040 pvarChild
->vt
= VT_EMPTY
;
1041 Reference
< XAccessibleContext
> pRContext
= GetContextByXAcc(m_xAccessible
.get());
1042 nCount
= pRContext
->getAccessibleChildCount();
1045 IMAccessible
* child
= NULL
;
1046 for( i
= 0; i
<nCount
; i
++)
1049 child
= GetChildInterface(i
+ 1);
1050 if(child
&& child
->accHitTest(xLeft
,yTop
,pvarChild
) == S_OK
)
1054 if(pvarChild
->vt
== VT_DISPATCH
)
1059 pvarChild
->vt
= VT_DISPATCH
;
1060 pvarChild
->pdispVal
= child
;
1065 pvarChild
->vt
= VT_I4
;
1066 pvarChild
->lVal
= CHILDID_SELF
;
1072 LEAVE_PROTECTED_BLOCK
1076 * Get The other Interface from CMAccessible.
1077 * @param guidService, must be IID_IAccessible here.
1078 * @param riid, the IID interface .
1079 * @return S_OK if successful and S_FALSE if failure.
1081 STDMETHODIMP
CMAccessible::QueryService(REFGUID guidService
, REFIID riid
, void** ppvObject
)
1083 if( InlineIsEqualGUID(guidService
, IID_IAccessible
) )
1084 return QueryInterface(riid
, ppvObject
);
1089 * Set the accessible name of the current COM object self or its one child from UNO.
1090 * @param varChild, vt member of varChild must be VT_I4,and lVal member stores the child ID,
1091 * the child ID specify child index from 0 to children count, 0 stands for object self.
1092 * @param szName, the name used to set the name of the proper object.
1093 * @return S_OK if successful and E_FAIL if failure.
1095 STDMETHODIMP
CMAccessible::put_accName(VARIANT varChild
, BSTR szName
)
1099 ENTER_PROTECTED_BLOCK
1101 if(varChild
.vt
==VT_I4
)
1103 if(varChild
.lVal
==CHILDID_SELF
)
1105 SAFE_SYSFREESTRING(m_pszName
);
1106 m_pszName
=SysAllocString(szName
);
1110 long lVal
= varChild
.lVal
;
1111 varChild
.lVal
= CHILDID_SELF
;
1112 IMAccessible
*pChild
= this->GetChildInterface(lVal
);
1115 return pChild
->put_accName(varChild
,szName
);
1119 LEAVE_PROTECTED_BLOCK
1123 * Set the accessible value of the current COM object self or its one child from UNO.
1124 * @param varChild, vt member of varChild must be VT_I4,and lVal member stores the child ID,
1125 * the child ID specify child index from 0 to children count, 0 stands for object self.
1126 * @param szValue, the value used to set the value of the proper object.
1127 * @return S_OK if successful and E_FAIL if failure.
1129 STDMETHODIMP
CMAccessible::put_accValue(VARIANT varChild
, BSTR szValue
)
1133 ENTER_PROTECTED_BLOCK
1135 if(varChild
.vt
==VT_I4
)
1137 if(varChild
.lVal
==CHILDID_SELF
)
1139 SysAllocString(m_pszValue
);
1140 m_pszValue
=SysAllocString(szValue
);
1144 long lVal
= varChild
.lVal
;
1145 varChild
.lVal
= CHILDID_SELF
;
1146 IMAccessible
*pChild
= this->GetChildInterface(lVal
);
1149 return pChild
->put_accValue(varChild
,szValue
);
1153 LEAVE_PROTECTED_BLOCK
1157 * Set the accessible name of the current COM object self from UNO.
1158 * @param pszName, the name value used to set the name of the current object.
1159 * @return S_OK if successful and E_FAIL if failure.
1161 STDMETHODIMP
CMAccessible::Put_XAccName(const OLECHAR __RPC_FAR
*pszName
)
1163 // internal IMAccessible - no mutex meeded
1165 ENTER_PROTECTED_BLOCK
1170 return E_INVALIDARG
;
1173 SAFE_SYSFREESTRING(m_pszName
);//??
1174 m_pszName
= SysAllocString(pszName
);
1179 LEAVE_PROTECTED_BLOCK
1183 * Set the accessible role of the current COM object self from UNO.
1184 * @param pRole, the role value used to set the role of the current object.
1185 * @return S_OK if successful and E_FAIL if failure.
1187 STDMETHODIMP
CMAccessible::Put_XAccRole(unsigned short pRole
)
1189 // internal IMAccessible - no mutex meeded
1196 * Add one state into the current state set for the current COM object from UNO.
1197 * @param pXSate, the state used to set the name of the current object.
1198 * @return S_OK if successful and E_FAIL if failure.
1200 STDMETHODIMP
CMAccessible::DecreaseState(DWORD pXSate
)
1202 // internal IMAccessible - no mutex meeded
1204 m_dState
&= (~pXSate
);
1209 * Delete one state into the current state set for the current COM object from UNO.
1210 * @param pXSate, the state used to set the name of the current object.
1211 * @return S_OK if successful and E_FAIL if failure.
1213 STDMETHODIMP
CMAccessible::IncreaseState(DWORD pXSate
)
1215 // internal IMAccessible - no mutex meeded
1222 * Set state into the current state set for the current COM object from UNO.
1223 * @param pXSate, the state used to set the name of the current object.
1224 * @return S_OK if successful and E_FAIL if failure.
1226 STDMETHODIMP
CMAccessible::SetState(DWORD pXSate
)
1228 // internal IMAccessible - no mutex meeded
1237 * Set the accessible description of the current COM object self from UNO.
1238 * @param pszDescription, the name used to set the description of the current object.
1239 * @return S_OK if successful and E_FAIL if failure.
1241 STDMETHODIMP
CMAccessible::Put_XAccDescription(const OLECHAR __RPC_FAR
*pszDescription
)
1243 // internal IMAccessible - no mutex meeded
1245 ENTER_PROTECTED_BLOCK
1248 if(pszDescription
== NULL
)
1250 return E_INVALIDARG
;
1253 SAFE_SYSFREESTRING(m_pszDescription
);
1254 m_pszDescription
= SysAllocString(pszDescription
);
1256 if(m_pszDescription
==NULL
)
1260 LEAVE_PROTECTED_BLOCK
1264 * Set the accessible value of the current COM object self from UNO.
1265 * @param pszAccValue, the name used to set the value of the current object.
1266 * @return S_OK if successful and E_FAIL if failure.
1268 STDMETHODIMP
CMAccessible::Put_XAccValue(const OLECHAR __RPC_FAR
*pszAccValue
)
1270 // internal IMAccessible - no mutex meeded
1272 ENTER_PROTECTED_BLOCK
1275 if(pszAccValue
== NULL
)
1277 return E_INVALIDARG
;
1279 SAFE_SYSFREESTRING(m_pszValue
);
1280 m_pszValue
= SysAllocString(pszAccValue
);
1281 if(m_pszValue
==NULL
)
1285 LEAVE_PROTECTED_BLOCK
1289 * Set the HWND value of the current COM object self from UNO. It should set the parent IAccessible
1290 * Object through the method AccessibleObjectFromWindow(...).
1291 * @param hwnd, the HWND used to set the value of the current object.
1292 * @return S_OK if successful and E_FAIL if failure.
1294 STDMETHODIMP
CMAccessible::Put_XAccWindowHandle(HWND hwnd
)
1296 // internal IMAccessible - no mutex meeded
1298 ENTER_PROTECTED_BLOCK
1303 LEAVE_PROTECTED_BLOCK
1307 * Set accessible focus by specifying child ID
1308 * @param dChildID, the child id identifies the focus child.
1309 * @return S_OK if successful and E_FAIL if failure.
1311 STDMETHODIMP
CMAccessible::Put_XAccFocus(long dChildID
)
1313 // internal IMAccessible - no mutex meeded
1315 ENTER_PROTECTED_BLOCK
1318 if(dChildID
==CHILDID_SELF
)
1322 m_pIParent
->Put_XAccFocus(m_dChildID
);
1327 m_dFocusChildID
= dChildID
;
1328 //traverse all ancestors to set the focused child ID so that when the get_accFocus is called on
1329 //any of the ancestors, this id can be used to get the IAccessible of focused object.
1332 m_pIParent
->Put_XAccFocus(dChildID
);
1337 LEAVE_PROTECTED_BLOCK
1341 *Set accessible object location for the current COM object
1342 * @param sLocation, the location of the current object.
1343 * @return S_OK if successful and E_FAIL if failure.
1345 STDMETHODIMP
CMAccessible::Put_XAccLocation(const Location sLocation
)
1347 // internal IMAccessible - no mutex meeded
1349 this->m_sLocation
= sLocation
;
1354 * Set accessible parent object for the current COM object if
1355 * the current object is a child of some COM object
1356 * @param pIParent, the parent of the current object.
1357 * @return S_OK if successful and E_FAIL if failure.
1359 STDMETHODIMP
CMAccessible::Put_XAccParent(IMAccessible __RPC_FAR
*pIParent
)
1361 // internal IMAccessible - no mutex meeded
1363 this->m_pIParent
= pIParent
;
1366 m_pIParent
->AddRef();
1372 * Set unique child id to COM
1373 * @param dChildID, the id of the current object.
1374 * @return S_OK if successful and E_FAIL if failure.
1376 STDMETHODIMP
CMAccessible::Put_XAccChildID(long dChildID
)
1378 // internal IMAccessible - no mutex meeded
1380 this->m_dChildID
= dChildID
;
1385 * Set AccObjectManagerAgent object pointer to COM
1386 * @param pAgent, the AccObjectManagerAgent point.
1387 * @return S_OK if successful and E_FAIL if failure.
1389 STDMETHODIMP
CMAccessible::Put_XAccAgent(hyper pAgent
)
1391 // internal IMAccessible - no mutex meeded
1393 g_pAgent
= reinterpret_cast<AccObjectManagerAgent
*>(pAgent
);
1398 * When a UNO control disposing, it disposes its listeners,
1399 * then notify AccObject in bridge management, then notify
1400 * COM that the XAccessible is invalid,so set m_xAccessible as NULL
1401 * @param isDestroy, true is it need to be destroyed.
1402 * @return S_OK if successful and E_FAIL if failure.
1404 STDMETHODIMP
CMAccessible::NotifyDestroy(BOOL isDestroy
)
1406 // internal IMAccessible - no mutex meeded
1408 m_isDestroy
= isDestroy
;
1409 m_xAccessible
.clear();
1414 *private methods that help implement public functions
1418 * Return child interface pointer by child ID,note: need to call AddRef()
1419 * @param lChildID, specify child index,which AT(such as Inspect32) gives.
1420 * @return IMAccessible*, pointer to the corresponding child object.
1422 IMAccessible
* CMAccessible::GetChildInterface(long dChildID
)//for test
1428 IMAccessible
* pIMAcc
= NULL
;
1429 g_pAgent
->GetIAccessibleFromResID(dChildID
,&pIMAcc
);
1436 if (!m_xAccessible
.is())
1439 Reference
<XAccessibleContext
> const pRContext
=
1440 m_xAccessible
->getAccessibleContext();
1441 if( !pRContext
.is() )
1444 if(dChildID
<1 || dChildID
>pRContext
->getAccessibleChildCount())
1447 IAccessible
* pChild
= NULL
;
1448 Reference
< XAccessible
> pXChild
= pRContext
->getAccessibleChild(dChildID
-1);
1449 BOOL isGet
= get_IAccessibleFromXAccessible(pXChild
.get(), &pChild
);
1453 g_pAgent
->InsertAccObj(pXChild
.get(), m_xAccessible
.get(),
1454 reinterpret_cast<sal_Int64
>(m_hwnd
));
1455 isGet
= get_IAccessibleFromXAccessible(pXChild
.get(), &pChild
);
1460 IMAccessible
* pIMAcc
= (IMAccessible
*)pChild
;
1469 * For List, tree and table,these roles belong to manage_descendant in UNO,
1470 * need to process specifically when navigate
1471 * @return BOOL, if it is descendantmanager, return true.
1473 BOOL
CMAccessible::IsDescendantManage()
1476 return (m_iRole
==ROLE_SYSTEM_LIST
)||(m_iRole
==ROLE_SYSTEM_OUTLINE
)||(m_iRole
==ROLE_SYSTEM_TABLE
);
1480 * for descendantmanager circumstance,provide child interface when navigate
1481 * @param varCur, the current child.
1482 * @param flags, the navigation direction.
1483 * @return IMAccessible*, the child of the end up node.
1485 IMAccessible
* CMAccessible::GetNavigateChildForDM(VARIANT varCur
, short flags
)
1488 XAccessibleContext
* pXContext
= GetContextByXAcc(m_xAccessible
.get());
1494 int count
= pXContext
->getAccessibleChildCount();
1500 IMAccessible
* pCurChild
= NULL
;
1501 XAccessible
* pChildXAcc
= NULL
;
1502 Reference
<XAccessible
> pRChildXAcc
;
1503 XAccessibleContext
* pChildContext
= NULL
;
1504 int index
= 0,delta
=0;
1508 pRChildXAcc
= pXContext
->getAccessibleChild(0);
1511 pRChildXAcc
= pXContext
->getAccessibleChild(count
-1);
1515 pCurChild
= GetChildInterface(varCur
.lVal
);
1520 pCurChild
->GetUNOInterface(reinterpret_cast<hyper
*>(&pChildXAcc
));
1521 if(pChildXAcc
==NULL
)
1525 pChildContext
= GetContextByXAcc(pChildXAcc
);
1526 if(pChildContext
== NULL
)
1530 delta
= (flags
==DM_NEXTCHILD
)?1:-1;
1531 //currently, getAccessibleIndexInParent is error in UNO for
1532 //some kind of List,such as ValueSet, the index will be less 1 than
1533 //what should be, need to fix UNO code
1534 index
= pChildContext
->getAccessibleIndexInParent()+delta
;
1535 if((index
>=0)&&(index
<=count
-1))
1537 pRChildXAcc
= pXContext
->getAccessibleChild(index
);
1544 if(!pRChildXAcc
.is())
1548 pChildXAcc
= pRChildXAcc
.get();
1549 g_pAgent
->InsertAccObj(pChildXAcc
, m_xAccessible
.get());
1550 return g_pAgent
->GetIMAccByXAcc(pChildXAcc
);
1554 *the following 4 private methods are for accNavigate implementation
1558 * Return first child for parent container, process differently according
1559 * to whether it is descendant manage
1560 * @param varStart, the start child id of this navigation action.
1561 * @param pvarEndUpAt, [in,out] the end up child of this navigation action.
1562 * @return S_OK if successful and E_FAIL if failure.
1564 HRESULT
CMAccessible::GetFirstChild(VARIANT varStart
,VARIANT
* pvarEndUpAt
)
1567 ENTER_PROTECTED_BLOCK
1570 if(pvarEndUpAt
== NULL
)
1572 return E_INVALIDARG
;
1574 if(varStart
.vt
!= VT_I4
)
1576 pvarEndUpAt
->vt
= VT_EMPTY
;
1577 return E_INVALIDARG
;
1580 pvarEndUpAt
->pdispVal
= GetNavigateChildForDM(varStart
, DM_FIRSTCHILD
);
1581 if(pvarEndUpAt
->pdispVal
)
1583 pvarEndUpAt
->pdispVal
->AddRef();
1584 pvarEndUpAt
->vt
= VT_DISPATCH
;
1588 pvarEndUpAt
->vt
= VT_EMPTY
;
1591 LEAVE_PROTECTED_BLOCK
1595 * Return last child for parent container, process differently according
1596 * to whether it is descendant manage
1597 * @param varStart, the start child id of this navigation action.
1598 * @param pvarEndUpAt, [in,out] the end up child of this navigation action.
1599 * @return S_OK if successful and E_FAIL if failure.
1601 HRESULT
CMAccessible::GetLastChild(VARIANT varStart
,VARIANT
* pvarEndUpAt
)
1604 ENTER_PROTECTED_BLOCK
1607 if(pvarEndUpAt
== NULL
)
1609 return E_INVALIDARG
;
1611 if(varStart
.vt
!= VT_I4
)
1613 pvarEndUpAt
->vt
= VT_EMPTY
;
1614 return E_INVALIDARG
;
1617 pvarEndUpAt
->pdispVal
= GetNavigateChildForDM(varStart
, DM_LASTCHILD
);
1618 if(pvarEndUpAt
->pdispVal
)
1620 pvarEndUpAt
->pdispVal
->AddRef();
1621 pvarEndUpAt
->vt
= VT_DISPATCH
;
1624 pvarEndUpAt
->vt
= VT_EMPTY
;
1627 LEAVE_PROTECTED_BLOCK
1631 * The method GetNextSibling is general, whatever it is descendant manage or not
1632 * Get the next sibling object.
1633 * @param varStart, the start child id of this navigation action.
1634 * @param pvarEndUpAt, [in,out] the end up child of this navigation action.
1635 * @return S_OK if successful and E_FAIL if failure.
1637 HRESULT
CMAccessible::GetNextSibling(VARIANT varStart
,VARIANT
* pvarEndUpAt
)
1640 ENTER_PROTECTED_BLOCK
1642 if(varStart
.vt
!= VT_I4
)
1644 pvarEndUpAt
->vt
= VT_EMPTY
;
1645 return E_INVALIDARG
;
1648 Reference
<XAccessibleContext
> const pRContext
=
1649 GetContextByXAcc(m_xAccessible
.get());
1652 varStart
.iVal
= sal_Int16(pRContext
->getAccessibleIndexInParent() + 2);
1654 if( m_pIParent
->get_accChild(varStart
,&pvarEndUpAt
->pdispVal
) == S_OK
)
1656 pvarEndUpAt
->vt
= VT_DISPATCH
;
1660 pvarEndUpAt
->vt
= VT_EMPTY
;
1663 LEAVE_PROTECTED_BLOCK
1667 *the method GetPreSibling is general, whatever it is descendant manage or not
1668 * @param varStart, the start child id of this navigation action.
1669 * @param pvarEndUpAt, [in,out] the end up child of this navigation action.
1670 * @return S_OK if successful and E_FAIL if failure.
1672 HRESULT
CMAccessible::GetPreSibling(VARIANT varStart
,VARIANT
* pvarEndUpAt
)
1675 ENTER_PROTECTED_BLOCK
1678 if(pvarEndUpAt
== NULL
)
1680 return E_INVALIDARG
;
1682 if(varStart
.vt
!= VT_I4
)
1684 pvarEndUpAt
->vt
= VT_EMPTY
;
1685 return E_INVALIDARG
;
1688 Reference
<XAccessibleContext
> const pRContext
=
1689 GetContextByXAcc(m_xAccessible
.get());
1692 varStart
.iVal
= sal_Int16(pRContext
->getAccessibleIndexInParent());
1693 if(m_pIParent
&& varStart
.iVal
> 0)
1694 if( m_pIParent
->get_accChild(varStart
,&pvarEndUpAt
->pdispVal
) == S_OK
)
1696 pvarEndUpAt
->vt
= VT_DISPATCH
;
1700 pvarEndUpAt
->vt
= VT_EMPTY
;
1703 LEAVE_PROTECTED_BLOCK
1707 * For IAccessible2 implementation methods
1709 STDMETHODIMP
CMAccessible::get_nRelations( long __RPC_FAR
*nRelations
)
1713 ENTER_PROTECTED_BLOCK
1717 if(nRelations
== NULL
)
1719 return E_INVALIDARG
;
1724 if (!m_xContext
.is())
1726 Reference
<XAccessibleRelationSet
> pRrelationSet
=
1727 m_xContext
.get()->getAccessibleRelationSet();
1728 if(!pRrelationSet
.is())
1734 *nRelations
= pRrelationSet
->getRelationCount();
1737 LEAVE_PROTECTED_BLOCK
1740 STDMETHODIMP
CMAccessible::get_relation( long relationIndex
, IAccessibleRelation __RPC_FAR
*__RPC_FAR
*relation
)
1744 ENTER_PROTECTED_BLOCK
1747 if(relation
== NULL
)
1749 return E_INVALIDARG
;
1752 if (!m_xContext
.is())
1757 get_nRelations(&nMax
);
1759 *relation
= (IAccessibleRelation
*)::CoTaskMemAlloc(sizeof(IAccessibleRelation
));
1761 // #CHECK Memory Allocation#
1762 if(*relation
== NULL
)
1767 if( relationIndex
< nMax
)
1769 Reference
<XAccessibleRelationSet
> const pRrelationSet
=
1770 m_xContext
.get()->getAccessibleRelationSet();
1771 if(!pRrelationSet
.is())
1777 IAccessibleRelation
* pRelation
= NULL
;
1778 HRESULT hr
= createInstance
<CAccRelation
>(IID_IAccessibleRelation
,
1782 IUNOXWrapper
* wrapper
= NULL
;
1783 hr
= pRelation
->QueryInterface(IID_IUNOXWrapper
, (void**)&wrapper
);
1786 AccessibleRelation accRelation
= pRrelationSet
->getRelation(relationIndex
);
1787 wrapper
->put_XSubInterface(
1788 reinterpret_cast<hyper
>(&accRelation
));
1790 *relation
= pRelation
;
1799 LEAVE_PROTECTED_BLOCK
1802 STDMETHODIMP
CMAccessible::get_relations( long, IAccessibleRelation __RPC_FAR
*__RPC_FAR
*relation
, long __RPC_FAR
*nRelations
)
1806 ENTER_PROTECTED_BLOCK
1810 if(relation
== NULL
|| nRelations
== NULL
)
1812 return E_INVALIDARG
;
1814 // #CHECK XInterface#
1816 if (!m_xContext
.is())
1819 Reference
<XAccessibleRelationSet
> const pRrelationSet
=
1820 m_xContext
.get()->getAccessibleRelationSet();
1821 if(!pRrelationSet
.is())
1827 long nCount
= pRrelationSet
->getRelationCount();
1829 *relation
= (IAccessibleRelation
*)::CoTaskMemAlloc(nCount
*sizeof(IAccessibleRelation
));
1831 // #CHECK Memory Allocation#
1832 if(*relation
== NULL
)
1837 for(int i
=0; i
<nCount
; i
++)
1839 IAccessibleRelation
* pRelation
= NULL
;
1840 HRESULT hr
= createInstance
<CAccRelation
>(IID_IAccessibleRelation
,
1844 IUNOXWrapper
* wrapper
= NULL
;
1845 hr
= pRelation
->QueryInterface(IID_IUNOXWrapper
, (void**)&wrapper
);
1848 AccessibleRelation accRelation
= pRrelationSet
->getRelation(i
);
1849 wrapper
->put_XSubInterface(
1850 reinterpret_cast<hyper
>(&accRelation
));
1853 (relation
)[i
] = pRelation
;
1857 *nRelations
= nCount
;
1860 LEAVE_PROTECTED_BLOCK
1863 STDMETHODIMP
CMAccessible::role(long __RPC_FAR
*role
)
1867 ENTER_PROTECTED_BLOCK
1873 LEAVE_PROTECTED_BLOCK
1877 STDMETHODIMP
CMAccessible:: get_nActions(long __RPC_FAR
*nActions
)
1885 if(nActions
== NULL
)
1887 return E_INVALIDARG
;
1890 IAccessibleAction
* pAcc
= NULL
;
1891 HRESULT hr
= QueryInterface(IID_IAccessibleAction
, (void**)&pAcc
);
1894 pAcc
->nActions(nActions
);
1908 STDMETHODIMP
CMAccessible:: scrollToPoint(enum IA2CoordinateType
, long, long)
1913 STDMETHODIMP
CMAccessible:: scrollTo(enum IA2ScrollType
)
1918 static XAccessible
* getTheParentOfMember(XAccessible
* pXAcc
)
1925 Reference
<XAccessibleContext
> pRContext
= pXAcc
->getAccessibleContext();
1926 Reference
<XAccessibleRelationSet
> pRrelationSet
= pRContext
->getAccessibleRelationSet();
1927 long nRelations
= pRrelationSet
->getRelationCount();
1928 for(int i
=0 ; i
<nRelations
; i
++)
1930 AccessibleRelation accRelation
= pRrelationSet
->getRelation(i
);
1931 if(accRelation
.RelationType
== 7)
1933 Sequence
< Reference
< XInterface
> > xTargets
= accRelation
.TargetSet
;
1934 return (XAccessible
*)xTargets
[0].get();
1940 STDMETHODIMP
CMAccessible:: get_groupPosition(long __RPC_FAR
*groupLevel
,long __RPC_FAR
*similarItemsInGroup
,long __RPC_FAR
*positionInGroup
)
1944 ENTER_PROTECTED_BLOCK
1947 if(groupLevel
== NULL
|| similarItemsInGroup
== NULL
|| positionInGroup
== NULL
)
1949 return E_INVALIDARG
;
1952 if (!m_xAccessible
.is())
1955 Reference
<XAccessibleContext
> const pRContext
=
1956 m_xAccessible
->getAccessibleContext();
1959 long Role
= pRContext
->getAccessibleRole();
1962 *similarItemsInGroup
= 0;
1963 *positionInGroup
= 0;
1965 if (Role
!= AccessibleRole::DOCUMENT
&& Role
!= AccessibleRole::DOCUMENT_PRESENTATION
&&
1966 Role
!= AccessibleRole::DOCUMENT_SPREADSHEET
&& Role
!= AccessibleRole::DOCUMENT_TEXT
)
1968 Reference
< XAccessibleGroupPosition
> xGroupPosition( pRContext
, UNO_QUERY
);
1969 if ( xGroupPosition
.is() )
1971 Sequence
< sal_Int32
> rSeq
= xGroupPosition
->getGroupPosition( makeAny( pRContext
) );
1972 sal_Int32
* pSeq
= rSeq
.getArray();
1975 *groupLevel
= pSeq
[0];
1976 *similarItemsInGroup
= pSeq
[1];
1977 *positionInGroup
= pSeq
[2];
1984 Reference
< XAccessible
> pParentAcc
= pRContext
->getAccessibleParent();
1985 if( !pParentAcc
.is() )
1990 Reference
<XAccessibleContext
> pRParentContext
= pParentAcc
->getAccessibleContext();
1996 if( Role
== RADIO_BUTTON
)
1998 Reference
<XAccessibleRelationSet
> pRrelationSet
= pRContext
->getAccessibleRelationSet();
1999 long nRel
= pRrelationSet
->getRelationCount();
2000 for(int i
=0 ; i
<nRel
; i
++)
2002 AccessibleRelation accRelation
= pRrelationSet
->getRelation(i
);
2003 if(accRelation
.RelationType
== 7)
2005 Sequence
< Reference
< XInterface
> > xTargets
= accRelation
.TargetSet
;
2007 Reference
<XInterface
> pRAcc
= xTargets
[0];
2008 for(int j
=0; j
<pRParentContext
->getAccessibleChildCount(); j
++)
2010 if( getTheParentOfMember(pRParentContext
->getAccessibleChild(j
).get())
2011 == (XAccessible
*)pRAcc
.get() &&
2012 pRParentContext
->getAccessibleChild(j
)->getAccessibleContext()->getAccessibleRole() == RADIO_BUTTON
)
2014 if (pRParentContext
->getAccessibleChild(j
).get() == m_xAccessible
.get())
2020 *similarItemsInGroup
= number
;
2021 *positionInGroup
= index
;
2025 else if ( COMBO_BOX
== Role
)
2028 *similarItemsInGroup
= 0;
2029 *positionInGroup
= -1;
2031 long nCount
= pRContext
->getAccessibleChildCount();
2036 Reference
<XAccessible
> xList
=pRContext
->getAccessibleChild(1);
2041 Reference
<XAccessibleContext
> xListContext(xList
,UNO_QUERY
);
2042 if (!xListContext
.is())
2046 Reference
<XAccessibleSelection
> xListSel(xList
,UNO_QUERY
);
2051 *similarItemsInGroup
= xListContext
->getAccessibleChildCount();
2052 if (*similarItemsInGroup
> 0 )
2056 Reference
<XAccessible
> xChild
= xListSel
->getSelectedAccessibleChild(0);
2059 Reference
<XAccessibleContext
> xChildContext(xChild
,UNO_QUERY
);
2060 if (xChildContext
.is())
2062 *positionInGroup
=xChildContext
->getAccessibleIndexInParent() + 1 ;
2072 else if ( PAGE_TAB
== Role
)
2075 *similarItemsInGroup
= pRParentContext
->getAccessibleChildCount();
2077 if (*similarItemsInGroup
> 0 )
2079 *positionInGroup
=pRContext
->getAccessibleIndexInParent() + 1 ;
2083 *positionInGroup
= -1;
2089 BOOL isFound
= FALSE
;
2090 while( pParentAcc
.is() && !isFound
)
2093 pRParentContext
= pParentAcc
->getAccessibleContext();
2094 Role
= pRParentContext
->getAccessibleRole();
2095 if( (Role
== TREE
) || (Role
== LIST
) )
2097 pParentAcc
= pRParentContext
->getAccessibleParent();
2102 Reference
< XAccessible
> pTempAcc
= pRContext
->getAccessibleParent();
2103 pRParentContext
= pTempAcc
->getAccessibleContext();
2104 *groupLevel
= level
;
2105 *similarItemsInGroup
= pRParentContext
->getAccessibleChildCount();
2106 *positionInGroup
= pRContext
->getAccessibleIndexInParent() + 1;
2111 *similarItemsInGroup
= 0;
2112 *positionInGroup
= 0;
2116 LEAVE_PROTECTED_BLOCK
2119 STDMETHODIMP
CMAccessible:: get_extendedStates( long, BSTR __RPC_FAR
*__RPC_FAR
*, long __RPC_FAR
*)
2125 STDMETHODIMP
CMAccessible:: get_uniqueID(long __RPC_FAR
*uniqueID
)
2129 ENTER_PROTECTED_BLOCK
2132 if(uniqueID
== NULL
)
2134 return E_INVALIDARG
;
2136 *uniqueID
= m_dChildID
;
2139 LEAVE_PROTECTED_BLOCK
2142 STDMETHODIMP
CMAccessible:: get_windowHandle(HWND __RPC_FAR
*windowHandle
)
2146 ENTER_PROTECTED_BLOCK
2149 if(windowHandle
== NULL
)
2151 return E_INVALIDARG
;
2154 HWND nHwnd
= m_hwnd
;
2155 IAccessible
* pParent
= m_pIParent
;
2156 CMAccessible
* pChild
= this;
2157 while((nHwnd
==0) && pParent
)
2159 pChild
= (CMAccessible
*)pParent
;
2162 pParent
= (IAccessible
*)pChild
->m_pIParent
;
2163 nHwnd
= (HWND
)pChild
->m_hwnd
;
2169 *windowHandle
= nHwnd
;
2172 LEAVE_PROTECTED_BLOCK
2176 * Get XAccessibleContext directly from UNO by the stored XAccessible pointer
2177 * @param pXAcc, UNO XAccessible object point.
2178 * @return XAccessibleContext*, the context of the pXAcc.
2180 XAccessibleContext
* CMAccessible::GetContextByXAcc( XAccessible
* pXAcc
)
2182 Reference
< XAccessibleContext
> pRContext
;
2186 pRContext
= pXAcc
->getAccessibleContext();
2187 if( !pRContext
.is() )
2189 return pRContext
.get();
2193 * Return the member variable m_pXAccessibleSelection, instead of
2194 * get XAccessibleSelection according to XAccessibleContext because if so,it will
2195 * depend on the UNO implementation code,so when COM is created, put XAccessibleSelection
2196 * by bridge management system
2197 * @return XAccessibleSelection*, the selection of the current object.
2199 Reference
< XAccessibleSelection
> CMAccessible::GetSelection()
2201 if (!m_xAccessible
.is())
2203 Reference
<XAccessibleContext
> const pRContext
=
2204 m_xAccessible
->getAccessibleContext();
2207 Reference
< XAccessibleSelection
> pRSelection(pRContext
,UNO_QUERY
);
2214 * Select one XAccessible item, for accSelect implementation
2215 * @param pItem, the item should be selected.
2216 * @return S_OK if successful.
2218 HRESULT
CMAccessible::SelectChild(XAccessible
* pItem
)
2221 ENTER_PROTECTED_BLOCK
2223 XAccessibleContext
* pParentContext
= GetContextByXAcc(m_xAccessible
.get());
2224 XAccessibleContext
* pContext
= GetContextByXAcc( pItem
);
2225 if( pParentContext
== NULL
|| pContext
== NULL
)
2228 Reference
< XAccessibleSelection
> pRSelection
= GetSelection();
2229 if( !pRSelection
.is() )
2231 long Index
= pContext
->getAccessibleIndexInParent();
2232 pRSelection
->selectAccessibleChild( Index
);
2235 LEAVE_PROTECTED_BLOCK
2239 * Deselect one XAccessible item, for accSelect implimentation
2240 * @param pItem, the item should be deselected.
2241 * @return S_OK if successful.
2243 HRESULT
CMAccessible::DeSelectChild(XAccessible
* pItem
)
2246 ENTER_PROTECTED_BLOCK
2248 XAccessibleContext
* pParentContext
= GetContextByXAcc(m_xAccessible
.get());
2250 XAccessibleContext
* pContext
= GetContextByXAcc( pItem
);
2251 if( pParentContext
== NULL
|| pContext
== NULL
)
2252 return E_INVALIDARG
;
2254 Reference
< XAccessibleSelection
> pRSelection
= GetSelection();
2255 if( !pRSelection
.is() )
2257 long Index
= pContext
->getAccessibleIndexInParent();
2258 pRSelection
->deselectAccessibleChild( Index
);
2262 LEAVE_PROTECTED_BLOCK
2266 * Select multiple XAccessible items,for implementation of accSelect
2267 * @param pItem, the items should be selected.
2268 * @param size, the size of the items.
2269 * @return S_OK if successful.
2271 HRESULT
CMAccessible::SelectMutipleChidren( XAccessible
** pItem
,int size
)
2274 ENTER_PROTECTED_BLOCK
2279 return E_INVALIDARG
;
2281 for(int index
= 0;index
< size
;index
++)
2283 SelectChild( pItem
[index
] );
2287 LEAVE_PROTECTED_BLOCK
2291 * Deselect multiple XAccessible items,for implementation of accSelect
2292 * @param pItem, the items should be selected.
2293 * @param size, the size of the items.
2294 * @return S_OK if successful.
2296 HRESULT
CMAccessible::DeSelectMutipleChildren( XAccessible
** pItem
,int size
)
2299 ENTER_PROTECTED_BLOCK
2304 return E_INVALIDARG
;
2306 for(int index
= 0;index
< size
;index
++)
2308 DeSelectChild( pItem
[index
] );
2312 LEAVE_PROTECTED_BLOCK
2316 * When COM is created, UNO set XAccessible pointer to it
2317 * in order to COM can operate UNO information
2318 * @param pXAcc, the XAccessible object of current object.
2319 * @return S_OK if successful.
2321 STDMETHODIMP
CMAccessible::SetXAccessible(hyper pXAcc
)
2323 // internal IMAccessible - no mutex meeded
2325 m_xAccessible
= reinterpret_cast<XAccessible
*>(pXAcc
);
2326 m_pEnumVar
->PutSelection(/*XAccessibleSelection*/
2327 reinterpret_cast<hyper
>(m_xAccessible
.get()));
2329 m_xContext
= m_xAccessible
->getAccessibleContext();
2335 * accSelect method has many optional flags, needs to process comprehensively
2336 * Mozilla and Microsoft do not implement SELFLAG_EXTENDSELECTION flag.
2337 * The implementation of this flag is a little trouble-shooting,so we also
2338 * do not implement it now
2339 * @param flagsSelect, the selection flag of the select action.
2340 * @param varChild, the child object pointer of current action.
2341 * @return S_OK if successful.
2343 STDMETHODIMP
CMAccessible::accSelect(long flagsSelect
, VARIANT varChild
)
2347 ENTER_PROTECTED_BLOCK
2349 if( (flagsSelect
&SELFLAG_ADDSELECTION
) &&
2350 (SELFLAG_REMOVESELECTION
&flagsSelect
) )
2351 return E_INVALIDARG
;
2353 if ( (flagsSelect
&SELFLAG_TAKESELECTION
) &&
2355 (flagsSelect
&SELFLAG_ADDSELECTION
) ||
2356 (flagsSelect
&SELFLAG_REMOVESELECTION
) ||
2357 (flagsSelect
&SELFLAG_EXTENDSELECTION
)
2360 return E_INVALIDARG
;
2362 if ( varChild
.vt
!= VT_I4
)
2363 return E_INVALIDARG
;
2365 IMAccessible
* pSelectAcc
;
2366 if( varChild
.lVal
== CHILDID_SELF
)
2369 pSelectAcc
->AddRef();
2373 pSelectAcc
= GetChildInterface(varChild
.lVal
);
2376 if( pSelectAcc
== NULL
)
2377 return E_INVALIDARG
;
2379 if( flagsSelect
&SELFLAG_TAKEFOCUS
)
2381 XAccessible
* pTempUNO
= 0;
2382 pSelectAcc
->GetUNOInterface(reinterpret_cast<hyper
*>(&pTempUNO
));
2384 if( pTempUNO
== NULL
)
2387 Reference
<XAccessibleContext
> pRContext
= pTempUNO
->getAccessibleContext();
2388 Reference
< XAccessibleComponent
> pRComponent(pRContext
,UNO_QUERY
);
2389 Reference
< XAccessible
> pRParentXAcc
= pRContext
->getAccessibleParent();
2390 Reference
< XAccessibleContext
> pRParentContext
= pRParentXAcc
->getAccessibleContext();
2391 Reference
< XAccessibleComponent
> pRParentComponent(pRParentContext
,UNO_QUERY
);
2392 Reference
< XAccessibleSelection
> pRParentSelection(pRParentContext
,UNO_QUERY
);
2395 pRComponent
->grabFocus();
2397 if( flagsSelect
& SELFLAG_TAKESELECTION
)
2399 pRParentSelection
->clearAccessibleSelection();
2400 pRParentSelection
->selectAccessibleChild( pRContext
->getAccessibleIndexInParent() );
2403 if( flagsSelect
& SELFLAG_ADDSELECTION
)
2405 pRParentSelection
->selectAccessibleChild( pRContext
->getAccessibleIndexInParent() );
2408 if( flagsSelect
& SELFLAG_REMOVESELECTION
)
2410 pRParentSelection
->deselectAccessibleChild( pRContext
->getAccessibleIndexInParent() );
2413 if( flagsSelect
& SELFLAG_EXTENDSELECTION
)
2415 long indexInParrent
= pRContext
->getAccessibleIndexInParent();
2417 if( pRParentSelection
->isAccessibleChildSelected( indexInParrent
+ 1 ) ||
2418 pRParentSelection
->isAccessibleChildSelected( indexInParrent
- 1 ) )
2420 pRParentSelection
->selectAccessibleChild( indexInParrent
);
2426 pSelectAcc
->Release();
2429 LEAVE_PROTECTED_BLOCK
2433 * Return XAccessible interface pointer when needed
2434 * @param pXAcc, [in, out] the Uno interface of the current object.
2435 * @return S_OK if successful.
2437 STDMETHODIMP
CMAccessible::GetUNOInterface(hyper
* pXAcc
)
2439 // internal IMAccessible - no mutex meeded
2442 return E_INVALIDARG
;
2444 *pXAcc
= reinterpret_cast<hyper
>(m_xAccessible
.get());
2449 * Helper method for Implementation of get_accDefaultAction
2450 * @param pAction, the default action point of the current object.
2451 * @return S_OK if successful.
2453 STDMETHODIMP
CMAccessible::SetDefaultAction(hyper pAction
)
2455 // internal IMAccessible - no mutex meeded
2457 m_xAction
= reinterpret_cast<XAccessibleAction
*>(pAction
);
2462 * This method is called when AT open some UI elements initially
2463 * the UI element takes the default action defined here
2464 * @param varChild, the child id of the defaultaction.
2465 * @param pszDefaultAction,[in/out] the description of the current action.
2466 * @return S_OK if successful.
2468 HRESULT STDMETHODCALLTYPE
CMAccessible::get_accDefaultAction(VARIANT varChild
, BSTR
*pszDefaultAction
)
2472 ENTER_PROTECTED_BLOCK
2475 if(pszDefaultAction
== NULL
)
2477 return E_INVALIDARG
;
2479 if(varChild
.vt
==VT_I4
)
2481 if(varChild
.lVal
==CHILDID_SELF
)
2483 if (!m_xAction
.is())
2484 return DISP_E_MEMBERNOTFOUND
;
2485 SAFE_SYSFREESTRING(*pszDefaultAction
);
2486 *pszDefaultAction
= SysAllocString(m_pszActionDescription
);
2490 long lVal
= varChild
.lVal
;
2491 varChild
.lVal
= CHILDID_SELF
;
2492 IMAccessible
*pChild
= this->GetChildInterface(lVal
);
2495 return pChild
->get_accDefaultAction(varChild
,pszDefaultAction
);
2499 LEAVE_PROTECTED_BLOCK
2503 * AT call this method to operate application
2504 * @param varChild, the child id of the action object.
2505 * @return S_OK if successful.
2507 HRESULT STDMETHODCALLTYPE
CMAccessible::accDoDefaultAction(VARIANT varChild
)
2511 ENTER_PROTECTED_BLOCK
2513 if( varChild
.vt
!= VT_I4
)
2514 return E_INVALIDARG
;
2515 if (!m_xAction
.is())
2517 if (m_xAction
->getAccessibleActionCount() == 0)
2520 if(varChild
.lVal
==CHILDID_SELF
)
2522 if (m_xAction
->getAccessibleActionCount() > 0)
2523 m_xAction
->doAccessibleAction(0);
2527 long lVal
= varChild
.lVal
;
2528 varChild
.lVal
= CHILDID_SELF
;
2529 IMAccessible
*pChild
= this->GetChildInterface(lVal
);
2532 return pChild
->accDoDefaultAction( varChild
);
2534 LEAVE_PROTECTED_BLOCK
2538 * UNO set description information for action to COM.
2539 * @param szAction, the action description of the current object.
2540 * @return S_OK if successful.
2542 STDMETHODIMP
CMAccessible::Put_ActionDescription( const OLECHAR
* szAction
)
2544 // internal IMAccessible - no mutex meeded
2546 ENTER_PROTECTED_BLOCK
2549 if(szAction
== NULL
)
2551 return E_INVALIDARG
;
2553 SAFE_SYSFREESTRING(m_pszActionDescription
);
2554 m_pszActionDescription
= SysAllocString( szAction
);
2557 LEAVE_PROTECTED_BLOCK
2560 BOOL
CMAccessible::GetXInterfaceFromXAccessible(XAccessible
* pXAcc
, XInterface
** ppXI
, int index
)
2562 Reference
< XAccessibleContext
> pRContext
;
2567 QUERYXINTERFACE(AccessibleComponent
)
2570 QUERYXINTERFACE(AccessibleText
)
2572 case XI_EDITABLETEXT
:
2573 QUERYXINTERFACE(AccessibleEditableText
)
2576 QUERYXINTERFACE(AccessibleTable
)
2579 QUERYXINTERFACE(AccessibleSelection
)
2581 case XI_EXTENDEDCOMP
:
2582 QUERYXINTERFACE(AccessibleExtendedComponent
)
2585 QUERYXINTERFACE(AccessibleKeyBinding
)
2588 QUERYXINTERFACE(AccessibleAction
)
2591 QUERYXINTERFACE(AccessibleValue
)
2594 QUERYXINTERFACE(AccessibleHypertext
)
2597 QUERYXINTERFACE(AccessibleHyperlink
)
2600 QUERYXINTERFACE(AccessibleImage
)
2609 template<typename T
> HRESULT
2610 createAggInstance(CMAccessible
&rOuter
, void ** ppvObject
)
2612 // Note: CComAggObject has special handling for IUnknown - must
2613 // query for that when creating it! Otherwise we get a T member of it
2614 // which will redirect QueryInterface back to CMAccessible infinitely.
2615 // (CComAggObject has its own ref-count too which is not a problem
2616 // since it is inserted in m_containedObjects.)
2617 return CComCreator
< CComAggObject
<T
> >::CreateInstance(
2618 rOuter
.GetControllingUnknown(), IID_IUnknown
, ppvObject
);
2621 typedef HRESULT (AggCreatorFunc
)(CMAccessible
&, void **);
2626 AggCreatorFunc
* pfnCreateInstance
;
2630 static AggMapEntry g_CMAccessible_AggMap
[] = {
2631 { &IID_IAccessibleComponent
, &createAggInstance
<CAccComponent
>, XI_COMPONENT
},
2632 { &IID_IAccessibleText
, &createAggInstance
<CAccText
>, XI_TEXT
},
2633 { &IID_IAccessibleEditableText
, &createAggInstance
<CAccEditableText
>, XI_EDITABLETEXT
},
2634 { &IID_IAccessibleImage
, &createAggInstance
<CAccImage
>, XI_IMAGE
},
2635 { &IID_IAccessibleTable
, &createAggInstance
<CAccTable
>, XI_TABLE
},
2636 { &IID_IAccessibleAction
, &createAggInstance
<CAccAction
>, XI_ACTION
},
2637 { &IID_IAccessibleValue
, &createAggInstance
<CAccValue
>, XI_VALUE
},
2638 { &IID_IAccessibleHypertext
, &createAggInstance
<CAccHypertext
>, XI_HYPERTEXT
},
2639 { &IID_IAccessibleHyperlink
, &createAggInstance
<CAccHyperLink
>, XI_HYPERLINK
},
2644 HRESULT WINAPI
CMAccessible::SmartQI(void* /*pv*/, REFIID iid
, void** ppvObject
)
2646 ENTER_PROTECTED_BLOCK
2649 if (InlineIsEqualGUID(iid
,IID_IAccIdentity
) ||
2650 InlineIsEqualGUID(iid
,IID_IStdMarshalInfo
) ||
2651 InlineIsEqualGUID(iid
,IID_IMarshal
) ||
2652 InlineIsEqualGUID(iid
,IID_IExternalConnection
)||
2653 InlineIsEqualGUID(iid
,IID_IOleWindow
))
2658 AggMapEntry
* pMap
= &g_CMAccessible_AggMap
[0];
2659 while(pMap
&& pMap
->piid
)
2661 if (InlineIsEqualGUID(iid
, *pMap
->piid
))
2665 XInterface
* pXI
= NULL
;
2666 BOOL bFound
= GetXInterfaceFromXAccessible(m_xAccessible
.get(),
2667 &pXI
, pMap
->XIFIndex
);
2673 XGUIDToComObjHash::iterator pIndTemp
= m_containedObjects
.find( iid
);
2674 if ( pIndTemp
!= m_containedObjects
.end() )
2676 return pIndTemp
->second
.p
->QueryInterface( iid
, ppvObject
);
2680 HRESULT hr
= pMap
->pfnCreateInstance(*this, ppvObject
);
2684 m_containedObjects
.insert(XGUIDToComObjHash::value_type(*pMap
->piid
,(IUnknown
*)*ppvObject
));
2685 IUNOXWrapper
* wrapper
= NULL
;
2686 ((IUnknown
*)*ppvObject
)->QueryInterface(IID_IUNOXWrapper
, (void**)&wrapper
);
2689 wrapper
->put_XInterface(
2690 reinterpret_cast<hyper
>(m_xAccessible
.get()));
2702 LEAVE_PROTECTED_BLOCK
2706 CMAccessible::get_IAccessibleFromXAccessible(XAccessible
* pXAcc
, IAccessible
**ppIA
)
2709 ENTER_PROTECTED_BLOCK
2714 return E_INVALIDARG
;
2718 isGet
= g_pAgent
->GetIAccessibleFromXAccessible(pXAcc
, ppIA
);
2725 LEAVE_PROTECTED_BLOCK
2728 void CMAccessible::get_OLECHARFromAny(Any
& pAny
, OLECHAR
* pChar
)
2734 switch(pAny
.getValueTypeClass())
2736 case TypeClass_CHAR
:
2740 swprintf( pChar
, L
"%d", val
);
2743 case TypeClass_BOOLEAN
:
2747 swprintf( pChar
, L
"%d", val
);
2750 case TypeClass_BYTE
:
2754 swprintf( pChar
, L
"%d", val
);
2757 case TypeClass_SHORT
:
2761 swprintf( pChar
, L
"%d", val
);
2764 case TypeClass_UNSIGNED_SHORT
:
2768 swprintf( pChar
, L
"%d", val
);
2771 case TypeClass_LONG
:
2775 swprintf( pChar
, L
"%ld", val
);
2778 case TypeClass_UNSIGNED_LONG
:
2782 swprintf( pChar
, L
"%ld", val
);
2785 case TypeClass_FLOAT
:
2789 swprintf( pChar
, L
"%.3f", val
);
2792 case TypeClass_DOUBLE
:
2796 swprintf( pChar
, L
"%.6lf", val
);
2799 case TypeClass_STRING
:
2801 ::rtl::OUString val
;
2803 wcscpy(pChar
, val
.getStr());
2806 case TypeClass_SEQUENCE
:
2808 if(pAny
.getValueType() == cppu::UnoType
<Sequence
< ::rtl::OUString
>>::get())
2810 Sequence
< ::rtl::OUString
> val
;
2813 ::rtl::OUString pString
;
2815 int count
= val
.getLength();
2817 for( int iIndex
= 0;iIndex
< count
;iIndex
++ )
2819 pString
+= val
[iIndex
];
2821 wcscpy(pChar
, pString
.getStr());
2823 else if (pAny
.getValueType() == cppu::UnoType
<Sequence
< ::com::sun::star::style::TabStop
>>::get())
2825 Sequence
< ::com::sun::star::style::TabStop
> val
;
2827 int count
= val
.getLength();
2829 for( int iIndex
= 0;iIndex
< count
;iIndex
++ )
2831 OLECHAR pAttrs
[512] = {NULL
};
2833 OLECHAR pAttrsPosition
[512] = {NULL
};
2834 OLECHAR pAttrsDescimalChar
[512] = {NULL
};
2835 OLECHAR pAttrsFillChar
[512] = {NULL
};
2837 ::com::sun::star::style::TabStop sigleVal
= val
[iIndex
];
2839 swprintf( pAttrsPosition
, L
"Position=%ld,TabAlign=%ld",
2840 sigleVal
.Position
, sigleVal
.Alignment
);
2842 if(sigleVal
.DecimalChar
==';' || sigleVal
.DecimalChar
== ':' || sigleVal
.DecimalChar
== ',' ||
2843 sigleVal
.DecimalChar
== '=' || sigleVal
.DecimalChar
== '\\')
2844 swprintf( pAttrsDescimalChar
, L
"DecimalChar=\\%c",sigleVal
.DecimalChar
);
2846 swprintf( pAttrsDescimalChar
, L
"DecimalChar=%c",sigleVal
.DecimalChar
);
2848 if(sigleVal
.FillChar
==';' || sigleVal
.FillChar
== ':' || sigleVal
.FillChar
== ',' ||
2849 sigleVal
.FillChar
== '=' || sigleVal
.FillChar
== '\\')
2850 swprintf( pAttrsFillChar
, L
"FillChar=\\%c",sigleVal
.FillChar
);
2852 swprintf( pAttrsFillChar
, L
"FillChar=%c",sigleVal
.FillChar
);
2854 swprintf( pAttrs
, L
"%s,%s,%s,",pAttrsPosition
,pAttrsDescimalChar
,pAttrsFillChar
);
2856 wcscat(pChar
,pAttrs
);
2861 case TypeClass_ENUM
:
2863 if (pAny
.getValueType() == cppu::UnoType
<com::sun::star::awt::FontSlant
>::get())
2865 com::sun::star::awt::FontSlant val
;
2867 swprintf( pChar
, L
"%d", val
);
2870 case TypeClass_STRUCT
:
2872 if (pAny
.getValueType() == cppu::UnoType
<com::sun::star::style::LineSpacing
>::get())
2874 com::sun::star::style::LineSpacing val
;
2876 swprintf( pChar
, L
"Mode=%ld,Height=%ld,", val
.Mode
, val
.Height
);
2878 else if (pAny
.getValueType() == cppu::UnoType
<com::sun::star::accessibility::TextSegment
>::get())
2880 com::sun::star::accessibility::TextSegment val
;
2882 ::rtl::OUString
realVal(val
.SegmentText
);
2883 wcscpy(pChar
, realVal
.getStr());
2887 case TypeClass_VOID
:
2888 case TypeClass_HYPER
:
2889 case TypeClass_UNSIGNED_HYPER
:
2890 case TypeClass_TYPE
:
2892 case TypeClass_TYPEDEF
:
2893 case TypeClass_EXCEPTION
:
2894 case TypeClass_INTERFACE
:
2895 case TypeClass_SERVICE
:
2896 case TypeClass_MODULE
:
2897 case TypeClass_INTERFACE_METHOD
:
2898 case TypeClass_INTERFACE_ATTRIBUTE
:
2899 case TypeClass_UNKNOWN
:
2900 case TypeClass_PROPERTY
:
2901 case TypeClass_CONSTANT
:
2902 case TypeClass_CONSTANTS
:
2903 case TypeClass_SINGLETON
:
2904 case TypeClass_MAKE_FIXED_SIZE
:
2911 void CMAccessible::get_OLECHAR4Numbering(const Any
& pAny
, short numberingLevel
,const OUString
& numberingPrefix
,OLECHAR
* pChar
)
2915 Reference
< ::com::sun::star::container::XIndexReplace
> pXIndex
;
2916 if((pAny
>>=pXIndex
) && (numberingLevel
!=-1))//numbering level is -1,means invalid value
2918 Any aAny
= pXIndex
->getByIndex(numberingLevel
);
2919 Sequence
< ::com::sun::star::beans::PropertyValue
> aProps
;
2921 const ::com::sun::star::beans::PropertyValue
* pPropArray
= aProps
.getConstArray();
2922 sal_Int32 nCount
= aProps
.getLength();
2923 swprintf(pChar
,L
"Numbering:NumberingLevel=%d,",numberingLevel
);
2924 for( sal_Int32 i
=0; i
<nCount
; i
++ )
2926 ::com::sun::star::beans::PropertyValue rProp
= pPropArray
[i
];
2927 if( (rProp
.Name
== "BulletChar" ) ||
2928 (rProp
.Name
== "GraphicURL" ) ||
2929 (rProp
.Name
== "NumberingType" ))
2931 OLECHAR propStr
[512] = {NULL
};
2932 swprintf(propStr
,L
"%s=",rProp
.Name
.getStr());
2933 OLECHAR pTemp
[256] = {NULL
};
2934 CMAccessible::get_OLECHARFromAny(rProp
.Value
,pTemp
);
2935 if(rProp
.Name
== "GraphicURL")
2937 OLECHAR
* pOccur
= wcschr(pTemp
,':');
2941 wcscat(propStr
,pTemp
);
2942 wcscat(pChar
,propStr
);
2945 if(rProp
.Name
== "NumberingType")
2947 if(numberingPrefix
.getLength()!=0)
2949 swprintf(pTemp
,L
"NumberingPrefix=%s,",numberingPrefix
.getStr());
2950 wcscat(pChar
,pTemp
);
2957 //Because now have three types numbering level:
2958 //1.real numbering list,numbering level>=0 and numbering Rule !=NULL;
2959 //2.common paragraph, numbering level >=0, and numbering Rule == NULL;
2960 //3.TOC paragraph, numbering level >0, and numbering Rule ==NULL;
2961 // IAText:numberinglevel base on 0, but TOC's level base on 1,
2962 // so NumberingLevel value will be decreased 1 in bridge code.
2963 else if(numberingLevel
>0)
2965 swprintf(pChar
,L
"Numbering:NumberingLevel=%d,NumberingType=4,NumberingPrefix=,",numberingLevel
-1);
2969 swprintf(pChar
,L
"Numbering:");
2973 void CMAccessible::ConvertAnyToVariant(const ::com::sun::star::uno::Any
&rAnyVal
, VARIANT
*pvData
)
2975 if(rAnyVal
.hasValue())
2977 // Clear VARIANT variable.
2978 VariantClear(pvData
);
2980 // Set value according to value type.
2981 switch(rAnyVal
.getValueTypeClass())
2983 case TypeClass_CHAR
:
2984 pvData
->vt
= VT_UI1
;
2985 memcpy(&pvData
->bVal
, rAnyVal
.getValue(), sizeof(sal_Char
));
2988 case TypeClass_BOOLEAN
:
2989 pvData
->vt
= VT_BOOL
;
2990 memcpy(&pvData
->boolVal
, rAnyVal
.getValue(), sizeof(sal_Bool
));
2993 case TypeClass_BYTE
:
2994 pvData
->vt
= VT_UI1
;
2995 memcpy(&pvData
->bVal
, rAnyVal
.getValue(), sizeof(sal_Int8
));
2998 case TypeClass_SHORT
:
3000 memcpy(&pvData
->iVal
, rAnyVal
.getValue(), sizeof(sal_Int16
));
3003 case TypeClass_UNSIGNED_SHORT
:
3005 memcpy(&pvData
->iVal
, rAnyVal
.getValue(), sizeof(sal_uInt16
));
3008 case TypeClass_LONG
:
3010 memcpy(&pvData
->lVal
, rAnyVal
.getValue(), sizeof(sal_Int32
));
3013 case TypeClass_UNSIGNED_LONG
:
3015 memcpy(&pvData
->lVal
, rAnyVal
.getValue(), sizeof(sal_uInt32
));
3018 case TypeClass_FLOAT
:
3020 memcpy(&pvData
->fltVal
, rAnyVal
.getValue(), sizeof(float));
3023 case TypeClass_DOUBLE
:
3025 memcpy(&pvData
->dblVal
, rAnyVal
.getValue(), sizeof(double));
3028 case TypeClass_STRING
:
3030 pvData
->vt
= VT_BSTR
;
3031 ::rtl::OUString val
;
3033 pvData
->bstrVal
= SysAllocString((OLECHAR
*)val
.getStr());
3037 case TypeClass_VOID
:
3038 case TypeClass_HYPER
:
3039 case TypeClass_UNSIGNED_HYPER
:
3040 case TypeClass_TYPE
:
3042 case TypeClass_ENUM
:
3043 case TypeClass_TYPEDEF
:
3044 case TypeClass_STRUCT
:
3045 case TypeClass_EXCEPTION
:
3046 case TypeClass_SEQUENCE
:
3047 case TypeClass_INTERFACE
:
3049 Reference
< XAccessible
> pXAcc
;
3050 if(rAnyVal
>>= pXAcc
)
3054 IAccessible
* pIAcc
= NULL
;
3055 get_IAccessibleFromXAccessible(pXAcc
.get(), &pIAcc
);
3058 Reference
< XAccessibleContext
> pXAccContext
= pXAcc
->getAccessibleContext();
3059 g_pAgent
->InsertAccObj(pXAcc
.get(),pXAccContext
->getAccessibleParent().get());
3060 get_IAccessibleFromXAccessible(pXAcc
.get(), &pIAcc
);
3066 pvData
->vt
= VT_UNKNOWN
;
3067 pvData
->pdispVal
= (IAccessible2
*)pIAcc
;
3073 case TypeClass_SERVICE
:
3074 case TypeClass_MODULE
:
3075 case TypeClass_INTERFACE_METHOD
:
3076 case TypeClass_INTERFACE_ATTRIBUTE
:
3077 case TypeClass_UNKNOWN
:
3078 case TypeClass_PROPERTY
:
3079 case TypeClass_CONSTANT
:
3080 case TypeClass_CONSTANTS
:
3081 case TypeClass_SINGLETON
:
3082 case TypeClass_MAKE_FIXED_SIZE
:
3083 // Output the type string, if there is other uno value type.
3084 pvData
->vt
= VT_BSTR
;
3085 pvData
->bstrVal
= SysAllocString(rAnyVal
.getValueTypeName().getStr());
3094 VariantClear(pvData
);
3098 STDMETHODIMP
CMAccessible::Get_XAccChildID(long* childID
)
3100 // internal IMAccessible - no mutex meeded
3106 *childID
= m_dChildID
;
3110 STDMETHODIMP
CMAccessible:: get_states(AccessibleStates __RPC_FAR
*states
)
3114 ENTER_PROTECTED_BLOCK
3117 if (!m_xContext
.is())
3120 Reference
<XAccessibleStateSet
> const pRStateSet
=
3121 m_xContext
.get()->getAccessibleStateSet();
3122 if(!pRStateSet
.is())
3126 Sequence
<short> pStates
= pRStateSet
->getStates();
3129 long count
= pStates
.getLength() ;
3131 for( int i
= 0; i
< count
; i
++ )
3133 for( int j
= 0; j
< SAL_N_ELEMENTS(UNO_STATES
); j
++ )
3135 if( pStates
[i
] == UNO_STATES
[j
] )
3137 *states
|= IA2_STATES
[j
];
3145 LEAVE_PROTECTED_BLOCK
3148 // return the UNO roles
3149 STDMETHODIMP
CMAccessible:: get_extendedRole( BSTR __RPC_FAR
* )
3154 STDMETHODIMP
CMAccessible:: get_localizedExtendedRole( BSTR __RPC_FAR
* )
3159 STDMETHODIMP
CMAccessible:: get_nExtendedStates( long __RPC_FAR
* )
3165 STDMETHODIMP
CMAccessible:: get_localizedExtendedStates( long, BSTR __RPC_FAR
*__RPC_FAR
*, long __RPC_FAR
*)
3171 STDMETHODIMP
CMAccessible:: get_indexInParent( long __RPC_FAR
*accParentIndex
)
3173 ENTER_PROTECTED_BLOCK
3176 if(accParentIndex
== NULL
)
3177 return E_INVALIDARG
;
3179 if (!m_xContext
.is())
3182 *accParentIndex
= m_xContext
.get()->getAccessibleIndexInParent();
3186 LEAVE_PROTECTED_BLOCK
3188 STDMETHODIMP
CMAccessible:: get_locale( IA2Locale __RPC_FAR
*locale
)
3190 ENTER_PROTECTED_BLOCK
3193 return E_INVALIDARG
;
3195 if (!m_xContext
.is())
3198 ::com::sun::star::lang::Locale unoLoc
= m_xContext
.get()->getLocale();
3199 locale
->language
= SysAllocString((OLECHAR
*)unoLoc
.Language
.getStr());
3200 locale
->country
= SysAllocString((OLECHAR
*)unoLoc
.Country
.getStr());
3201 locale
->variant
= SysAllocString((OLECHAR
*)unoLoc
.Variant
.getStr());
3205 LEAVE_PROTECTED_BLOCK
3208 DWORD
GetMSAAStateFromUNO(short xState
)
3210 DWORD IState
= STATE_SYSTEM_UNAVAILABLE
;
3213 case /*AccessibleStateType::*/AccessibleStateType::BUSY
:
3214 IState
= STATE_SYSTEM_BUSY
;
3216 case /*AccessibleStateType::*/AccessibleStateType::CHECKED
:
3217 IState
= STATE_SYSTEM_CHECKED
;
3219 case /*AccessibleStateType::*/AccessibleStateType::DEFUNC
:
3220 IState
= STATE_SYSTEM_UNAVAILABLE
;
3222 case /*AccessibleStateType::*/AccessibleStateType::EXPANDED
:
3223 IState
= STATE_SYSTEM_EXPANDED
;
3225 case /*AccessibleStateType::*/AccessibleStateType::FOCUSABLE
:
3226 IState
= STATE_SYSTEM_FOCUSABLE
;
3228 case /*AccessibleStateType::*/AccessibleStateType::FOCUSED
:
3229 IState
= STATE_SYSTEM_FOCUSED
;
3231 case /*AccessibleStateType::*/AccessibleStateType::INDETERMINATE
:
3232 IState
= STATE_SYSTEM_MIXED
;
3234 case /*AccessibleStateType::*/AccessibleStateType::MULTI_SELECTABLE
:
3235 IState
= STATE_SYSTEM_MULTISELECTABLE
;
3237 case /*AccessibleStateType::*/AccessibleStateType::PRESSED
:
3238 IState
= STATE_SYSTEM_PRESSED
;
3240 case /*AccessibleStateType::*/AccessibleStateType::RESIZABLE
:
3241 IState
= STATE_SYSTEM_SIZEABLE
;
3243 case /*AccessibleStateType::*/AccessibleStateType::SELECTABLE
:
3244 IState
= STATE_SYSTEM_SELECTABLE
;
3246 case /*AccessibleStateType::*/AccessibleStateType::SELECTED
:
3247 IState
= STATE_SYSTEM_SELECTED
;
3249 case /*AccessibleStateType::*/AccessibleStateType::ARMED
:
3250 IState
= STATE_SYSTEM_FOCUSED
;
3252 case /*AccessibleStateType::*/AccessibleStateType::EXPANDABLE
:
3253 IState
= STATE_SYSTEM_COLLAPSED
;
3261 STDMETHODIMP
CMAccessible:: get_appName( BSTR __RPC_FAR
*name
)
3265 ENTER_PROTECTED_BLOCK
3268 return E_INVALIDARG
;
3270 *name
= SysAllocString(OLESTR("Hannover"));
3272 LEAVE_PROTECTED_BLOCK
3274 STDMETHODIMP
CMAccessible:: get_appVersion(BSTR __RPC_FAR
*version
)
3278 ENTER_PROTECTED_BLOCK
3281 return E_INVALIDARG
;
3282 *version
=SysAllocString(OLESTR("3.0"));
3284 LEAVE_PROTECTED_BLOCK
3286 STDMETHODIMP
CMAccessible:: get_toolkitName(BSTR __RPC_FAR
*name
)
3290 ENTER_PROTECTED_BLOCK
3293 return E_INVALIDARG
;
3294 *name
= SysAllocString(OLESTR(" "));
3296 LEAVE_PROTECTED_BLOCK
3298 STDMETHODIMP
CMAccessible:: get_toolkitVersion(BSTR __RPC_FAR
*version
)
3302 ENTER_PROTECTED_BLOCK
3305 return E_INVALIDARG
;
3306 *version
= SysAllocString(OLESTR(" "));
3308 LEAVE_PROTECTED_BLOCK
3312 STDMETHODIMP
CMAccessible::get_attributes(/*[out]*/ BSTR
*pAttr
)
3316 ENTER_PROTECTED_BLOCK
3319 if (!m_xAccessible
.is())
3322 Reference
<XAccessibleContext
> pRContext
= m_xAccessible
->getAccessibleContext();
3323 if( !pRContext
.is() )
3327 Reference
<XAccessibleExtendedAttributes
> pRXI(pRContext
,UNO_QUERY
);
3332 com::sun::star::uno::Reference
<com::sun::star::accessibility::XAccessibleExtendedAttributes
> pRXAttr
;
3333 pRXAttr
= pRXI
.get();
3334 ::com::sun::star::uno::Any anyVal
= pRXAttr
->getExtendedAttributes();
3336 ::rtl::OUString val
;
3340 SAFE_SYSFREESTRING(*pAttr
);
3341 *pAttr
= SysAllocString((OLECHAR
*)val
.getStr());
3345 LEAVE_PROTECTED_BLOCK
3348 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */