fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / winaccessibility / source / UAccCOM / MAccessible.cxx
bloba6bdc9095f4c308642d2aa20b1cf643e3c289448
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 .
20 #include "stdafx.h"
21 #include "UAccCOM.h"
22 #include "MAccessible.h"
24 #include <algorithm>
25 #include "AccAction.h"
26 #include "AccRelation.h"
27 #include "AccComponent.h"
28 #include "AccText.h"
29 #include "AccEditableText.h"
30 #include "AccImage.h"
31 #include "AccTable.h"
32 #include "AccValue.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 {
63 XI_COMPONENT = 0x01,
64 XI_TEXT = 0x02,
65 XI_TABLE = 0x03,
66 XI_EDITABLETEXT = 0x04,
67 XI_IMAGE = 0x05,
68 XI_SELECTION = 0x06,
69 XI_EXTENDEDCOMP = 0x07,
70 XI_VALUE = 0x08,
71 XI_KEYBINDING = 0x09,
72 XI_ACTION = 0x0A,
73 XI_HYPERTEXT = 0x0B,
74 XI_HYPERLINK = 0x0C,
75 XI_ATTRIBUTE = 0x0D,
76 XI_NULL = -1
79 // IA2 states mapping, and name
80 // maintenance the consistency, change one array, change the three all
81 long IA2_STATES[] =
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;
104 <=== map ===>
107 short UNO_STATES[] =
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;
129 // <=== map ===>
131 BSTR IA2_STATES_NAME[] =
133 _T("Active"),
134 _T("Armed"),
135 _T("Defunct"),
136 _T("Editable"),
137 _T("Horizontal"),
138 _T("Iconified"),
139 _T("Invalid Entry"),
140 _T("Manages Descendants"),
141 _T("Modal"),
142 _T("Multi Line"),
143 _T("Opaque"),
144 _T("Required"),
145 _T("Selectable Text"),
146 _T("Single Line"),
147 _T("Stale"),
148 _T("Supports Autocompletion"),
149 _T("Transient"),
150 _T("Vertical")
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) \
202 if(pXAcc == NULL) \
203 return FALSE; \
204 pRContext = pXAcc->getAccessibleContext(); \
205 if( !pRContext.is() ) \
207 return FALSE; \
209 Reference<X##ainterface> pRXI(pRContext,UNO_QUERY);\
210 if( !pRXI.is() ) \
212 return FALSE; \
214 *ppXI = (XInterface*)pRXI.get(); \
215 return TRUE; \
218 #define ISDESTROY() \
219 if(m_isDestroy) \
220 return S_FALSE;
223 AccObjectManagerAgent* CMAccessible::g_pAgent = NULL;
225 CMAccessible::CMAccessible():
226 m_iRole(0x00),
227 m_dState(0x00),
228 m_dChildID(0x00),
229 m_dFocusChildID(UACC_NO_FOCUS),
230 m_hwnd(NULL),
231 m_pIParent(NULL),
232 m_pszName(NULL),
233 m_pszValue(NULL),
234 m_pszDescription(NULL),
235 m_isDestroy(FALSE),
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()
249 SolarMutexGuard g;
251 if(m_pszName!=NULL)
253 SAFE_SYSFREESTRING(m_pszName);
254 m_pszName=NULL;
256 if(m_pszValue!=NULL)
258 SAFE_SYSFREESTRING(m_pszValue);
259 m_pszValue=NULL;
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;
273 if(m_pIParent)
275 m_pIParent->Release();
276 m_pIParent=NULL;
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)
292 SolarMutexGuard g;
294 ENTER_PROTECTED_BLOCK
295 ISDESTROY()
296 // #CHECK#
297 if(ppdispParent == NULL)
299 return E_INVALIDARG;
302 if(m_pIParent)
304 *ppdispParent = m_pIParent;
305 (*ppdispParent)->AddRef();
306 return S_OK;
308 else if(m_hwnd)
310 HRESULT hr = AccessibleObjectFromWindow(m_hwnd, OBJID_WINDOW, IID_IAccessible, (void**)ppdispParent);
311 if( ! SUCCEEDED( hr ) || ! ppdispParent )
313 return S_FALSE;
315 return S_OK;
317 return S_FALSE;
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)
329 SolarMutexGuard g;
331 ENTER_PROTECTED_BLOCK
332 ISDESTROY()
333 // #CHECK#
334 if(pcountChildren == NULL)
336 return E_INVALIDARG;
339 if (!m_xAccessible.is())
340 return S_FALSE;
342 Reference<XAccessibleContext> const pRContext =
343 m_xAccessible->getAccessibleContext();
344 if( pRContext.is() )
346 *pcountChildren = pRContext->getAccessibleChildCount();
349 return S_OK;
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)
363 SolarMutexGuard g;
365 ENTER_PROTECTED_BLOCK
366 ISDESTROY()
367 // #CHECK#
368 if(ppdispChild == NULL)
370 return E_INVALIDARG;
372 if(varChild.vt==VT_I4)
374 //get child interface pointer due to child ID
375 if(varChild.lVal==CHILDID_SELF)
377 AddRef();
378 *ppdispChild = this;
379 return S_OK;
381 *ppdispChild = GetChildInterface(varChild.lVal);
382 if((*ppdispChild) == NULL)
383 return E_FAIL;
384 (*ppdispChild)->AddRef();
385 return S_OK;
387 return S_FALSE;
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)
401 SolarMutexGuard g;
403 ENTER_PROTECTED_BLOCK
404 ISDESTROY()
405 // #CHECK#
406 if(pszName == NULL)
408 return E_INVALIDARG;
410 if(varChild.vt==VT_I4)
412 if(varChild.lVal==CHILDID_SELF)
414 SAFE_SYSFREESTRING(*pszName);
415 *pszName = SysAllocString(m_pszName);
416 return S_OK;
419 long lVal = varChild.lVal;
420 varChild.lVal = CHILDID_SELF;
421 IMAccessible *pChild = this->GetChildInterface(lVal);
422 if(!pChild)
423 return E_FAIL;
424 return pChild->get_accName(varChild,pszName);
426 return S_FALSE;
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)
440 SolarMutexGuard g;
442 ENTER_PROTECTED_BLOCK
443 ISDESTROY()
444 // #CHECK#
445 if( pszValue == NULL )
447 return E_INVALIDARG;
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 )
457 return S_OK;
459 SAFE_SYSFREESTRING(*pszValue);
460 *pszValue = SysAllocString(m_pszValue);
461 return S_OK;
464 long lVal = varChild.lVal;
465 varChild.lVal = CHILDID_SELF;
466 IMAccessible *pChild = this->GetChildInterface(lVal);
467 if(!pChild)
468 return E_FAIL;
469 return pChild->get_accValue(varChild,pszValue);
471 return S_FALSE;
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)
485 SolarMutexGuard g;
487 ENTER_PROTECTED_BLOCK
488 ISDESTROY()
489 // #CHECK#
490 if(pszDescription == NULL)
492 return E_INVALIDARG;
494 if(varChild.vt==VT_I4)
496 if(varChild.lVal==CHILDID_SELF)
498 SAFE_SYSFREESTRING(*pszDescription);
499 *pszDescription = SysAllocString(m_pszDescription);
500 return S_OK;
503 long lVal = varChild.lVal;
504 varChild.lVal = CHILDID_SELF;
505 IMAccessible *pChild = this->GetChildInterface(lVal);
506 if(!pChild)
507 return E_FAIL;
508 return pChild->get_accDescription(varChild,pszDescription);
510 return S_FALSE;
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)
524 SolarMutexGuard g;
526 ENTER_PROTECTED_BLOCK
527 ISDESTROY()
528 // #CHECK#
529 if(pvarRole == NULL)
531 return E_INVALIDARG;
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;
544 else
546 VariantInit(pvarRole);
547 pvarRole->vt = VT_I4;
548 pvarRole->lVal = ROLE_SYSTEM_CLIENT;
550 return S_OK;
554 long lVal = varChild.lVal;
555 varChild.lVal = CHILDID_SELF;
556 IMAccessible *pChild = this->GetChildInterface(lVal);
557 if(!pChild)
558 return E_FAIL;
559 return pChild->get_accRole(varChild,pvarRole);
561 return S_FALSE;
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)
575 SolarMutexGuard g;
577 ENTER_PROTECTED_BLOCK
578 ISDESTROY()
579 // #CHECK#
580 if(pvarState == NULL)
582 return E_INVALIDARG;
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();
592 if(pContext.is())
594 // add the STATE_SYSTEM_LINKED state
595 Reference< XAccessibleHypertext > pRHypertext(pContext,UNO_QUERY);
596 if(pRHypertext.is())
598 if( pRHypertext->getHyperLinkCount() > 0 )
599 m_dState |= STATE_SYSTEM_LINKED;
600 else
601 m_dState &= ~STATE_SYSTEM_LINKED;
603 else
604 m_dState &= ~STATE_SYSTEM_LINKED;
608 VariantInit(pvarState);
609 pvarState->vt = VT_I4;
610 pvarState->lVal = m_dState;
611 return S_OK;
614 long lVal = varChild.lVal;
615 varChild.lVal = CHILDID_SELF;
616 IMAccessible *pChild = this->GetChildInterface(lVal);
617 if(!pChild)
618 return E_FAIL;
619 return pChild->get_accState(varChild,pvarState);
621 return S_FALSE;
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 *)
635 return E_NOTIMPL;
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 *)
649 return E_NOTIMPL;
652 static void GetMnemonicChar( const ::rtl::OUString& aStr, WCHAR* wStr)
654 int nLen = aStr.pData->length;
655 int i = 0;
656 WCHAR* text = aStr.pData->buffer;
658 while ( i < nLen )
660 if ( text[i] == L'~' )
661 if ( text[i+1] != L'~' )
663 wStr[0] = text[i+1];
664 break;
666 i++;
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)
679 SolarMutexGuard g;
681 ENTER_PROTECTED_BLOCK
683 ISDESTROY()
684 // #CHECK#
685 if(pszKeyboardShortcut == NULL)
687 return E_INVALIDARG;
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() )
699 return S_FALSE;
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);
708 if( binding.is() )
710 long nCount = binding->getAccessibleKeyBindingCount();
711 if(nCount >= 1)
713 CAccAction::GetkeyBindingStrByXkeyBinding( binding->getAccessibleKeyBinding(0),wString );
717 if(wString[0] == 0)
719 Reference<XAccessibleRelationSet> pRrelationSet = pRContext->getAccessibleRelationSet();
720 if(!pRrelationSet.is())
722 return S_FALSE;
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);
738 return S_OK;
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)
754 return S_FALSE;
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())
763 return S_FALSE;
765 pRrelationSet = pRLebelContext->getAccessibleRelationSet();
766 nRelCount = pRrelationSet->getRelationCount();
768 paccRelation = NULL;
769 for(int j=0; j<nRelCount ; j++)
771 if( pRrelationSet->getRelation(j).RelationType == 5 )
773 accRelation = pRrelationSet->getRelation(j);
774 paccRelation = &accRelation;
778 if(paccRelation)
780 xTargets = paccRelation->TargetSet;
781 pRAcc = xTargets[0];
782 if (m_xAccessible.get() != (XAccessible*)pRAcc.get())
783 return S_FALSE;
786 Reference<XAccessibleExtendedComponent> pRXIE(pRLebelContext,UNO_QUERY);
787 if(!pRXIE.is())
788 return S_FALSE;
790 ::rtl::OUString ouStr = pRXIE->getTitledBorderText();
791 WCHAR key[2] = {NULL};
792 GetMnemonicChar(ouStr, key);
793 if(key[0] != 0)
795 wcscat(wString, L"Alt+");
796 wcscat(wString, key);
798 else
799 return S_FALSE;
802 SAFE_SYSFREESTRING(*pszKeyboardShortcut);
803 *pszKeyboardShortcut = SysAllocString(wString);
805 return S_OK;
807 else
809 return S_FALSE;
813 long lVal = varChild.lVal;
814 varChild.lVal = CHILDID_SELF;
815 IMAccessible *pChild = this->GetChildInterface(lVal);
816 if(!pChild)
817 return E_FAIL;
819 return pChild->get_accKeyboardShortcut(varChild,pszKeyboardShortcut);
821 return S_FALSE;
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)
834 SolarMutexGuard g;
836 ENTER_PROTECTED_BLOCK
837 ISDESTROY()
838 // #CHECK#
839 if(pvarChild == NULL)
841 return E_INVALIDARG;
843 if( m_dFocusChildID==UACC_NO_FOCUS )
845 pvarChild->vt = VT_EMPTY;//no focus on the object and its children
846 return S_OK;
848 //if the descendant of current object has focus indicated by m_dFocusChildID, return the IDispatch of this focused object
849 else
851 IMAccessible* pIMAcc = NULL;
852 g_pAgent->GetIAccessibleFromResID(m_dFocusChildID,&pIMAcc);
853 pIMAcc->AddRef();
854 pvarChild->vt = VT_DISPATCH;
855 pvarChild->pdispVal = pIMAcc;
858 return S_OK;
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)
873 SolarMutexGuard g;
875 ENTER_PROTECTED_BLOCK
876 ISDESTROY()
877 // #CHECK#
878 if(pvarChildren == NULL)
880 return E_INVALIDARG;
882 switch(m_pEnumVar->GetCountOfElements())
884 case 0:
885 pvarChildren->vt = VT_EMPTY;
886 break;
887 case 1:
888 VARIANT varTmp[1];
889 ULONG count;
890 VariantInit(&varTmp[0]);
891 m_pEnumVar->Next(1,varTmp,&count);
892 if(count!=1)
893 return S_FALSE;
894 pvarChildren->vt = VT_I4;
895 pvarChildren->lVal = varTmp[0].lVal;
896 VariantClear(&varTmp[0]);
897 m_pEnumVar->Reset();
898 break;
899 default:
900 pvarChildren->vt = VT_UNKNOWN;
901 m_pEnumVar->AddRef();
902 pvarChildren->punkVal = m_pEnumVar;
903 break;
905 return S_OK;
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)
922 SolarMutexGuard g;
924 ENTER_PROTECTED_BLOCK
925 ISDESTROY()
926 // #CHECK#
927 if(pxLeft == NULL || pyTop == NULL || pcxWidth == NULL || pcyHeight == NULL)
929 return E_INVALIDARG;
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() )
942 return S_FALSE;
943 Reference< XAccessibleComponent > pRComponent(pRContext,UNO_QUERY);
944 if( !pRComponent.is() )
945 return S_FALSE;
947 ::com::sun::star::awt::Point pCPoint = pRComponent->getLocationOnScreen();
948 ::com::sun::star::awt::Size pCSize = pRComponent->getSize();
949 *pxLeft = pCPoint.X;
950 *pyTop = pCPoint.Y;
951 *pcxWidth = pCSize.Width;
952 *pcyHeight = pCSize.Height;
953 return S_OK;
955 else
957 *pxLeft = m_sLocation.m_dLeft;
958 *pyTop = m_sLocation.m_dTop;
959 *pcxWidth = m_sLocation.m_dWidth;
960 *pcyHeight = m_sLocation.m_dHeight;
961 return S_OK;
966 return S_FALSE;
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)
980 SolarMutexGuard g;
982 ENTER_PROTECTED_BLOCK
983 ISDESTROY()
984 // #CHECK#
985 if(pvarEndUpAt == NULL)
987 return E_INVALIDARG;
989 HRESULT ret = E_FAIL;
990 switch (navDir)
992 case NAVDIR_FIRSTCHILD:
993 ret = GetFirstChild(varStart,pvarEndUpAt);
994 break;
995 case NAVDIR_LASTCHILD:
996 ret = GetLastChild(varStart,pvarEndUpAt);
997 break;
998 case NAVDIR_NEXT:
999 ret = GetNextSibling(varStart,pvarEndUpAt);
1000 break;
1001 case NAVDIR_PREVIOUS:
1002 ret = GetPreSibling(varStart,pvarEndUpAt);
1003 break;
1004 case NAVDIR_DOWN://do not implement temporarily
1005 break;
1006 case NAVDIR_UP://do not implement temporarily
1007 break;
1008 case NAVDIR_LEFT://do not implement temporarily
1009 break;
1010 case NAVDIR_RIGHT://do not implement temporarily
1011 break;
1012 default:
1013 break;
1015 return ret;
1017 LEAVE_PROTECTED_BLOCK
1020 STDMETHODIMP CMAccessible::accHitTest(long xLeft, long yTop, VARIANT *pvarChild)
1022 SolarMutexGuard g;
1024 ENTER_PROTECTED_BLOCK
1025 ISDESTROY()
1026 // #CHECK#
1027 if(pvarChild == NULL)
1029 return E_INVALIDARG;
1031 long x, y, w, h;
1032 VARIANT varSelf;
1033 VariantInit(&varSelf);
1034 varSelf.vt = VT_I4;
1035 varSelf.lVal = CHILDID_SELF;
1036 accLocation(&x,&y,&w,&h,varSelf);
1037 if( (x < xLeft && (x + w) >xLeft) && (y < yTop && (y + h) >yTop) )
1039 int i, nCount;
1040 pvarChild->vt = VT_EMPTY;
1041 Reference< XAccessibleContext > pRContext = GetContextByXAcc(m_xAccessible.get());
1042 nCount = pRContext->getAccessibleChildCount();
1043 if(nCount > 256)
1044 return E_FAIL;
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)
1051 break;
1054 if(pvarChild->vt == VT_DISPATCH)
1055 return S_OK;
1057 if( i < nCount)
1059 pvarChild->vt = VT_DISPATCH;
1060 pvarChild->pdispVal = child;
1061 child->AddRef();
1063 else
1065 pvarChild->vt = VT_I4;
1066 pvarChild->lVal = CHILDID_SELF;
1068 return S_OK;
1070 return S_FALSE;
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);
1085 return S_FALSE;
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)
1097 SolarMutexGuard g;
1099 ENTER_PROTECTED_BLOCK
1100 ISDESTROY()
1101 if(varChild.vt==VT_I4)
1103 if(varChild.lVal==CHILDID_SELF)
1105 SAFE_SYSFREESTRING(m_pszName);
1106 m_pszName=SysAllocString(szName);
1107 return S_OK;
1110 long lVal = varChild.lVal;
1111 varChild.lVal = CHILDID_SELF;
1112 IMAccessible *pChild = this->GetChildInterface(lVal);
1113 if(!pChild)
1114 return E_FAIL;
1115 return pChild->put_accName(varChild,szName);
1117 return E_FAIL;
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)
1131 SolarMutexGuard g;
1133 ENTER_PROTECTED_BLOCK
1134 ISDESTROY()
1135 if(varChild.vt==VT_I4)
1137 if(varChild.lVal==CHILDID_SELF)
1139 SysAllocString(m_pszValue);
1140 m_pszValue=SysAllocString(szValue);
1141 return S_OK;
1144 long lVal = varChild.lVal;
1145 varChild.lVal = CHILDID_SELF;
1146 IMAccessible *pChild = this->GetChildInterface(lVal);
1147 if(!pChild)
1148 return E_FAIL;
1149 return pChild->put_accValue(varChild,szValue);
1151 return E_FAIL;
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
1166 ISDESTROY()
1167 // #CHECK#
1168 if(pszName == NULL)
1170 return E_INVALIDARG;
1173 SAFE_SYSFREESTRING(m_pszName);//??
1174 m_pszName = SysAllocString(pszName);
1175 if(m_pszName==NULL)
1176 return E_FAIL;
1177 return S_OK;
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
1191 m_iRole = pRole;
1192 return S_OK;
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);
1205 return S_OK;
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
1217 m_dState |= pXSate;
1218 return S_OK;
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
1230 m_dState = pXSate;
1231 return S_OK;
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
1246 ISDESTROY()
1247 // #CHECK#
1248 if(pszDescription == NULL)
1250 return E_INVALIDARG;
1253 SAFE_SYSFREESTRING(m_pszDescription);
1254 m_pszDescription = SysAllocString(pszDescription);
1256 if(m_pszDescription==NULL)
1257 return E_FAIL;
1258 return S_OK;
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
1273 ISDESTROY()
1274 // #CHECK#
1275 if(pszAccValue == NULL)
1277 return E_INVALIDARG;
1279 SAFE_SYSFREESTRING(m_pszValue);
1280 m_pszValue = SysAllocString(pszAccValue);
1281 if(m_pszValue==NULL)
1282 return E_FAIL;
1283 return S_OK;
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
1299 ISDESTROY()
1300 m_hwnd = hwnd;
1301 return S_OK;
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
1316 ISDESTROY()
1318 if(dChildID==CHILDID_SELF)
1320 if(m_pIParent)
1322 m_pIParent->Put_XAccFocus(m_dChildID);
1325 else
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.
1330 if(m_pIParent)
1332 m_pIParent->Put_XAccFocus(dChildID);
1335 return S_OK;
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;
1350 return S_OK;
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;
1365 if(pIParent)
1366 m_pIParent->AddRef();
1368 return S_OK;
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;
1381 return S_OK;
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);
1394 return S_OK;
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();
1410 return S_OK;
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
1424 if(dChildID<0)
1426 if(g_pAgent)
1428 IMAccessible* pIMAcc = NULL;
1429 g_pAgent->GetIAccessibleFromResID(dChildID,&pIMAcc);
1430 return pIMAcc;
1432 return NULL;
1434 else
1436 if (!m_xAccessible.is())
1437 return NULL;
1439 Reference<XAccessibleContext> const pRContext =
1440 m_xAccessible->getAccessibleContext();
1441 if( !pRContext.is() )
1442 return NULL;
1444 if(dChildID<1 || dChildID>pRContext->getAccessibleChildCount())
1445 return NULL;
1447 IAccessible* pChild = NULL;
1448 Reference< XAccessible > pXChild = pRContext->getAccessibleChild(dChildID-1);
1449 BOOL isGet = get_IAccessibleFromXAccessible(pXChild.get(), &pChild);
1451 if(!isGet)
1453 g_pAgent->InsertAccObj(pXChild.get(), m_xAccessible.get(),
1454 reinterpret_cast<sal_Int64>(m_hwnd));
1455 isGet = get_IAccessibleFromXAccessible(pXChild.get(), &pChild);
1458 if(isGet)
1460 IMAccessible* pIMAcc = (IMAccessible*)pChild;
1461 return pIMAcc;
1465 return NULL;
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());
1489 if(pXContext==NULL)
1491 return NULL;
1494 int count = pXContext->getAccessibleChildCount();
1495 if(count<1)
1497 return NULL;
1500 IMAccessible* pCurChild = NULL;
1501 XAccessible* pChildXAcc = NULL;
1502 Reference<XAccessible> pRChildXAcc;
1503 XAccessibleContext* pChildContext = NULL;
1504 int index = 0,delta=0;
1505 switch(flags)
1507 case DM_FIRSTCHILD:
1508 pRChildXAcc = pXContext->getAccessibleChild(0);
1509 break;
1510 case DM_LASTCHILD:
1511 pRChildXAcc = pXContext->getAccessibleChild(count-1);
1512 break;
1513 case DM_NEXTCHILD:
1514 case DM_PREVCHILD:
1515 pCurChild = GetChildInterface(varCur.lVal);
1516 if(pCurChild==NULL)
1518 return NULL;
1520 pCurChild->GetUNOInterface(reinterpret_cast<hyper*>(&pChildXAcc));
1521 if(pChildXAcc==NULL)
1523 return NULL;
1525 pChildContext = GetContextByXAcc(pChildXAcc);
1526 if(pChildContext == NULL)
1528 return 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);
1539 break;
1540 default:
1541 break;
1544 if(!pRChildXAcc.is())
1546 return NULL;
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
1568 ISDESTROY()
1569 // #CHECK#
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;
1585 return S_OK;
1588 pvarEndUpAt->vt = VT_EMPTY;
1589 return E_FAIL;
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
1605 ISDESTROY()
1606 // #CHECK#
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;
1622 return S_OK;
1624 pvarEndUpAt->vt = VT_EMPTY;
1625 return E_FAIL;
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
1641 ISDESTROY()
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());
1650 if(pRContext.is())
1652 varStart.iVal = sal_Int16(pRContext->getAccessibleIndexInParent() + 2);
1653 if(m_pIParent)
1654 if( m_pIParent->get_accChild(varStart,&pvarEndUpAt->pdispVal) == S_OK)
1656 pvarEndUpAt->vt = VT_DISPATCH;
1657 return S_OK;
1660 pvarEndUpAt->vt = VT_EMPTY;
1661 return E_FAIL;
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
1676 ISDESTROY()
1677 // #CHECK#
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());
1690 if(pRContext.is())
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;
1697 return S_OK;
1700 pvarEndUpAt->vt = VT_EMPTY;
1701 return E_FAIL;
1703 LEAVE_PROTECTED_BLOCK
1707 * For IAccessible2 implementation methods
1709 STDMETHODIMP CMAccessible::get_nRelations( long __RPC_FAR *nRelations)
1711 SolarMutexGuard g;
1713 ENTER_PROTECTED_BLOCK
1714 ISDESTROY()
1716 // #CHECK#
1717 if(nRelations == NULL)
1719 return E_INVALIDARG;
1722 *nRelations = 0;
1724 if (!m_xContext.is())
1725 return E_FAIL;
1726 Reference<XAccessibleRelationSet> pRrelationSet =
1727 m_xContext.get()->getAccessibleRelationSet();
1728 if(!pRrelationSet.is())
1730 *nRelations = 0;
1731 return S_OK;
1734 *nRelations = pRrelationSet->getRelationCount();
1735 return S_OK;
1737 LEAVE_PROTECTED_BLOCK
1740 STDMETHODIMP CMAccessible::get_relation( long relationIndex, IAccessibleRelation __RPC_FAR *__RPC_FAR *relation)
1742 SolarMutexGuard g;
1744 ENTER_PROTECTED_BLOCK
1745 ISDESTROY()
1746 // #CHECK#
1747 if(relation == NULL)
1749 return E_INVALIDARG;
1752 if (!m_xContext.is())
1753 return E_FAIL;
1756 long nMax = 0;
1757 get_nRelations(&nMax);
1759 *relation = (IAccessibleRelation*)::CoTaskMemAlloc(sizeof(IAccessibleRelation));
1761 // #CHECK Memory Allocation#
1762 if(*relation == NULL)
1764 return E_FAIL;
1767 if( relationIndex < nMax )
1769 Reference<XAccessibleRelationSet> const pRrelationSet =
1770 m_xContext.get()->getAccessibleRelationSet();
1771 if(!pRrelationSet.is())
1774 return E_FAIL;
1777 IAccessibleRelation* pRelation = NULL;
1778 HRESULT hr = createInstance<CAccRelation>(IID_IAccessibleRelation,
1779 &pRelation);
1780 if(SUCCEEDED(hr))
1782 IUNOXWrapper* wrapper = NULL;
1783 hr = pRelation->QueryInterface(IID_IUNOXWrapper, (void**)&wrapper);
1784 if(SUCCEEDED(hr))
1786 AccessibleRelation accRelation = pRrelationSet->getRelation(relationIndex);
1787 wrapper->put_XSubInterface(
1788 reinterpret_cast<hyper>(&accRelation));
1789 wrapper->Release();
1790 *relation = pRelation;
1791 return S_OK;
1797 return E_FAIL;
1799 LEAVE_PROTECTED_BLOCK
1802 STDMETHODIMP CMAccessible::get_relations( long, IAccessibleRelation __RPC_FAR *__RPC_FAR *relation, long __RPC_FAR *nRelations)
1804 SolarMutexGuard g;
1806 ENTER_PROTECTED_BLOCK
1807 ISDESTROY()
1809 // #CHECK#
1810 if(relation == NULL || nRelations == NULL)
1812 return E_INVALIDARG;
1814 // #CHECK XInterface#
1816 if (!m_xContext.is())
1817 return E_FAIL;
1819 Reference<XAccessibleRelationSet> const pRrelationSet =
1820 m_xContext.get()->getAccessibleRelationSet();
1821 if(!pRrelationSet.is())
1823 *nRelations = 0;
1824 return S_OK;
1827 long nCount = pRrelationSet->getRelationCount();
1829 *relation = (IAccessibleRelation*)::CoTaskMemAlloc(nCount*sizeof(IAccessibleRelation));
1831 // #CHECK Memory Allocation#
1832 if(*relation == NULL)
1834 return E_FAIL;
1837 for(int i=0; i<nCount ; i++)
1839 IAccessibleRelation* pRelation = NULL;
1840 HRESULT hr = createInstance<CAccRelation>(IID_IAccessibleRelation,
1841 &pRelation);
1842 if(SUCCEEDED(hr))
1844 IUNOXWrapper* wrapper = NULL;
1845 hr = pRelation->QueryInterface(IID_IUNOXWrapper, (void**)&wrapper);
1846 if(SUCCEEDED(hr))
1848 AccessibleRelation accRelation = pRrelationSet->getRelation(i);
1849 wrapper->put_XSubInterface(
1850 reinterpret_cast<hyper>(&accRelation));
1851 wrapper->Release();
1853 (relation)[i] = pRelation;
1857 *nRelations = nCount;
1858 return S_OK;
1860 LEAVE_PROTECTED_BLOCK
1863 STDMETHODIMP CMAccessible::role(long __RPC_FAR *role)
1865 SolarMutexGuard g;
1867 ENTER_PROTECTED_BLOCK
1869 (*role) = m_iRole;
1871 return S_OK;
1873 LEAVE_PROTECTED_BLOCK
1877 STDMETHODIMP CMAccessible:: get_nActions(long __RPC_FAR *nActions)
1879 SolarMutexGuard g;
1883 ISDESTROY()
1884 // #CHECK#
1885 if(nActions == NULL)
1887 return E_INVALIDARG;
1889 *nActions = 0L;
1890 IAccessibleAction* pAcc = NULL;
1891 HRESULT hr = QueryInterface(IID_IAccessibleAction, (void**)&pAcc);
1892 if( hr == S_OK )
1894 pAcc->nActions(nActions);
1895 pAcc->Release();
1898 return S_OK;
1900 catch(...)
1902 *nActions = 0L;
1903 return S_OK;
1908 STDMETHODIMP CMAccessible:: scrollToPoint(enum IA2CoordinateType, long, long)
1910 return E_NOTIMPL;
1913 STDMETHODIMP CMAccessible:: scrollTo(enum IA2ScrollType)
1915 return E_NOTIMPL;
1918 static XAccessible* getTheParentOfMember(XAccessible* pXAcc)
1920 // #CHECK#
1921 if(pXAcc == NULL)
1923 return NULL;
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();
1937 return NULL;
1940 STDMETHODIMP CMAccessible:: get_groupPosition(long __RPC_FAR *groupLevel,long __RPC_FAR *similarItemsInGroup,long __RPC_FAR *positionInGroup)
1942 SolarMutexGuard g;
1944 ENTER_PROTECTED_BLOCK
1945 ISDESTROY()
1946 // #CHECK#
1947 if(groupLevel == NULL || similarItemsInGroup == NULL || positionInGroup == NULL)
1949 return E_INVALIDARG;
1952 if (!m_xAccessible.is())
1953 return E_FAIL;
1955 Reference<XAccessibleContext> const pRContext =
1956 m_xAccessible->getAccessibleContext();
1957 if(!pRContext.is())
1958 return E_FAIL;
1959 long Role = pRContext->getAccessibleRole();
1961 *groupLevel = 0;
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();
1973 if ( pSeq )
1975 *groupLevel = pSeq[0];
1976 *similarItemsInGroup = pSeq[1];
1977 *positionInGroup = pSeq[2];
1978 return S_OK;
1980 return S_OK;
1984 Reference< XAccessible> pParentAcc = pRContext->getAccessibleParent();
1985 if( !pParentAcc.is() )
1987 return S_OK;
1990 Reference<XAccessibleContext> pRParentContext = pParentAcc->getAccessibleContext();
1992 int level = 0;
1993 int index = 0;
1994 int number = 0;
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)
2013 number++;
2014 if (pRParentContext->getAccessibleChild(j).get() == m_xAccessible.get())
2015 index = number;
2019 *groupLevel = 1;
2020 *similarItemsInGroup = number;
2021 *positionInGroup = index;
2022 return S_OK;
2025 else if ( COMBO_BOX == Role )
2027 *groupLevel = 1;
2028 *similarItemsInGroup = 0;
2029 *positionInGroup = -1;
2031 long nCount = pRContext->getAccessibleChildCount();
2032 if( 2 != nCount)
2034 return S_OK;
2036 Reference<XAccessible> xList=pRContext->getAccessibleChild(1);
2037 if (!xList.is())
2039 return S_OK;
2041 Reference<XAccessibleContext> xListContext(xList,UNO_QUERY);
2042 if (!xListContext.is())
2044 return S_OK;
2046 Reference<XAccessibleSelection> xListSel(xList,UNO_QUERY);
2047 if (!xListSel.is())
2049 return S_OK;
2051 *similarItemsInGroup = xListContext->getAccessibleChildCount();
2052 if (*similarItemsInGroup > 0 )
2056 Reference<XAccessible> xChild = xListSel->getSelectedAccessibleChild(0);
2057 if (xChild.is())
2059 Reference<XAccessibleContext> xChildContext(xChild,UNO_QUERY);
2060 if (xChildContext.is())
2062 *positionInGroup=xChildContext->getAccessibleIndexInParent() + 1 ;
2063 return S_OK;
2067 catch(...)
2070 return S_OK;
2072 else if ( PAGE_TAB == Role )
2074 *groupLevel = 1;
2075 *similarItemsInGroup = pRParentContext->getAccessibleChildCount();
2077 if (*similarItemsInGroup > 0 )
2079 *positionInGroup=pRContext->getAccessibleIndexInParent() + 1 ;
2081 else
2083 *positionInGroup = -1;
2085 return S_OK;
2089 BOOL isFound = FALSE;
2090 while( pParentAcc.is() && !isFound)
2092 level++;
2093 pRParentContext = pParentAcc->getAccessibleContext();
2094 Role = pRParentContext->getAccessibleRole();
2095 if( (Role == TREE) || (Role == LIST) )
2096 isFound = TRUE;
2097 pParentAcc = pRParentContext->getAccessibleParent();
2100 if( isFound )
2102 Reference< XAccessible> pTempAcc = pRContext->getAccessibleParent();
2103 pRParentContext = pTempAcc->getAccessibleContext();
2104 *groupLevel = level;
2105 *similarItemsInGroup = pRParentContext->getAccessibleChildCount();
2106 *positionInGroup = pRContext->getAccessibleIndexInParent() + 1;
2108 else
2110 *groupLevel = 0;
2111 *similarItemsInGroup = 0;
2112 *positionInGroup = 0;
2114 return S_OK;
2116 LEAVE_PROTECTED_BLOCK
2119 STDMETHODIMP CMAccessible:: get_extendedStates( long, BSTR __RPC_FAR *__RPC_FAR *, long __RPC_FAR *)
2121 return E_NOTIMPL;
2125 STDMETHODIMP CMAccessible:: get_uniqueID(long __RPC_FAR *uniqueID)
2127 SolarMutexGuard g;
2129 ENTER_PROTECTED_BLOCK
2130 ISDESTROY()
2131 // #CHECK#
2132 if(uniqueID == NULL)
2134 return E_INVALIDARG;
2136 *uniqueID = m_dChildID;
2137 return S_OK;
2139 LEAVE_PROTECTED_BLOCK
2142 STDMETHODIMP CMAccessible:: get_windowHandle(HWND __RPC_FAR *windowHandle)
2144 SolarMutexGuard g;
2146 ENTER_PROTECTED_BLOCK
2147 ISDESTROY()
2148 // #CHECK#
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;
2160 if(pChild)
2162 pParent = (IAccessible*)pChild->m_pIParent;
2163 nHwnd = (HWND)pChild->m_hwnd;
2165 else
2166 pParent = NULL;
2169 *windowHandle = nHwnd;
2170 return S_OK;
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;
2183 if( pXAcc == NULL)
2184 return NULL;
2186 pRContext = pXAcc->getAccessibleContext();
2187 if( !pRContext.is() )
2188 return NULL;
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())
2202 return NULL;
2203 Reference<XAccessibleContext> const pRContext =
2204 m_xAccessible->getAccessibleContext();
2205 if(pRContext.is())
2207 Reference< XAccessibleSelection > pRSelection(pRContext,UNO_QUERY);
2208 return pRSelection;
2210 return NULL;
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
2222 ISDESTROY()
2223 XAccessibleContext* pParentContext = GetContextByXAcc(m_xAccessible.get());
2224 XAccessibleContext* pContext = GetContextByXAcc( pItem );
2225 if( pParentContext == NULL || pContext == NULL )
2226 return E_FAIL;
2228 Reference< XAccessibleSelection > pRSelection = GetSelection();
2229 if( !pRSelection.is() )
2230 return E_FAIL;
2231 long Index = pContext->getAccessibleIndexInParent();
2232 pRSelection->selectAccessibleChild( Index );
2233 return S_OK;
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
2247 ISDESTROY()
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() )
2256 return E_FAIL;
2257 long Index = pContext->getAccessibleIndexInParent();
2258 pRSelection->deselectAccessibleChild( Index );
2260 return S_OK;
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
2275 ISDESTROY()
2276 // #CHECK#
2277 if(pItem == NULL)
2279 return E_INVALIDARG;
2281 for(int index = 0;index < size;index++)
2283 SelectChild( pItem[index] );
2285 return S_OK;
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
2300 ISDESTROY()
2301 // #CHECK#
2302 if(pItem == NULL)
2304 return E_INVALIDARG;
2306 for(int index = 0;index < size;index++)
2308 DeSelectChild( pItem[index] );
2310 return S_OK;
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();
2331 return S_OK;
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)
2345 SolarMutexGuard g;
2347 ENTER_PROTECTED_BLOCK
2348 ISDESTROY()
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 )
2368 pSelectAcc = this;
2369 pSelectAcc->AddRef();
2371 else
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 )
2385 return 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();
2427 return S_OK;
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
2441 if(pXAcc == NULL)
2442 return E_INVALIDARG;
2444 *pXAcc = reinterpret_cast<hyper>(m_xAccessible.get());
2445 return S_OK;
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);
2458 return S_OK;
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)
2470 SolarMutexGuard g;
2472 ENTER_PROTECTED_BLOCK
2473 ISDESTROY()
2474 // #CHECK#
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);
2487 return S_OK;
2490 long lVal = varChild.lVal;
2491 varChild.lVal = CHILDID_SELF;
2492 IMAccessible *pChild = this->GetChildInterface(lVal);
2493 if(!pChild)
2494 return E_FAIL;
2495 return pChild->get_accDefaultAction(varChild,pszDefaultAction);
2497 return S_FALSE;
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)
2509 SolarMutexGuard g;
2511 ENTER_PROTECTED_BLOCK
2512 ISDESTROY()
2513 if( varChild.vt != VT_I4 )
2514 return E_INVALIDARG;
2515 if (!m_xAction.is())
2516 return E_FAIL;
2517 if (m_xAction->getAccessibleActionCount() == 0)
2518 return E_FAIL;
2520 if(varChild.lVal==CHILDID_SELF)
2522 if (m_xAction->getAccessibleActionCount() > 0)
2523 m_xAction->doAccessibleAction(0);
2524 return S_OK;
2527 long lVal = varChild.lVal;
2528 varChild.lVal = CHILDID_SELF;
2529 IMAccessible *pChild = this->GetChildInterface(lVal);
2530 if(!pChild)
2531 return E_FAIL;
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
2547 ISDESTROY()
2548 // #CHECK#
2549 if(szAction == NULL)
2551 return E_INVALIDARG;
2553 SAFE_SYSFREESTRING(m_pszActionDescription );
2554 m_pszActionDescription = SysAllocString( szAction );
2555 return S_OK;
2557 LEAVE_PROTECTED_BLOCK
2560 BOOL CMAccessible::GetXInterfaceFromXAccessible(XAccessible* pXAcc, XInterface** ppXI, int index)
2562 Reference< XAccessibleContext > pRContext;
2564 switch(index)
2566 case XI_COMPONENT:
2567 QUERYXINTERFACE(AccessibleComponent)
2568 break;
2569 case XI_TEXT:
2570 QUERYXINTERFACE(AccessibleText)
2571 break;
2572 case XI_EDITABLETEXT:
2573 QUERYXINTERFACE(AccessibleEditableText)
2574 break;
2575 case XI_TABLE:
2576 QUERYXINTERFACE(AccessibleTable)
2577 break;
2578 case XI_SELECTION:
2579 QUERYXINTERFACE(AccessibleSelection)
2580 break;
2581 case XI_EXTENDEDCOMP:
2582 QUERYXINTERFACE(AccessibleExtendedComponent)
2583 break;
2584 case XI_KEYBINDING:
2585 QUERYXINTERFACE(AccessibleKeyBinding)
2586 break;
2587 case XI_ACTION:
2588 QUERYXINTERFACE(AccessibleAction)
2589 break;
2590 case XI_VALUE:
2591 QUERYXINTERFACE(AccessibleValue)
2592 break;
2593 case XI_HYPERTEXT:
2594 QUERYXINTERFACE(AccessibleHypertext)
2595 break;
2596 case XI_HYPERLINK:
2597 QUERYXINTERFACE(AccessibleHyperlink)
2598 break;
2599 case XI_IMAGE:
2600 QUERYXINTERFACE(AccessibleImage)
2601 break;
2602 default:
2603 break;
2606 return FALSE;
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 **);
2623 struct AggMapEntry
2625 const IID* piid;
2626 AggCreatorFunc* pfnCreateInstance;
2627 int XIFIndex;
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 },
2640 { 0, 0, 0 },
2644 HRESULT WINAPI CMAccessible::SmartQI(void* /*pv*/, REFIID iid, void** ppvObject)
2646 ENTER_PROTECTED_BLOCK
2648 ISDESTROY()
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))
2655 return E_FAIL;
2658 AggMapEntry * pMap = &g_CMAccessible_AggMap[0];
2659 while(pMap && pMap->piid)
2661 if (InlineIsEqualGUID(iid, *pMap->piid))
2663 SolarMutexGuard g;
2665 XInterface* pXI = NULL;
2666 BOOL bFound = GetXInterfaceFromXAccessible(m_xAccessible.get(),
2667 &pXI, pMap->XIFIndex);
2668 if(!bFound)
2670 return E_FAIL;
2673 XGUIDToComObjHash::iterator pIndTemp = m_containedObjects.find( iid );
2674 if ( pIndTemp != m_containedObjects.end() )
2676 return pIndTemp->second.p->QueryInterface( iid, ppvObject );
2678 else
2680 HRESULT hr = pMap->pfnCreateInstance(*this, ppvObject);
2681 assert(hr == S_OK);
2682 if(hr == S_OK)
2684 m_containedObjects.insert(XGUIDToComObjHash::value_type(*pMap->piid,(IUnknown*)*ppvObject));
2685 IUNOXWrapper* wrapper = NULL;
2686 ((IUnknown*)*ppvObject)->QueryInterface(IID_IUNOXWrapper, (void**)&wrapper);
2687 if(wrapper)
2689 wrapper->put_XInterface(
2690 reinterpret_cast<hyper>(m_xAccessible.get()));
2691 wrapper->Release();
2693 return S_OK;
2696 return E_FAIL;
2698 pMap++;
2700 return E_FAIL;
2702 LEAVE_PROTECTED_BLOCK
2705 BOOL
2706 CMAccessible::get_IAccessibleFromXAccessible(XAccessible * pXAcc, IAccessible **ppIA)
2709 ENTER_PROTECTED_BLOCK
2711 // #CHECK#
2712 if(ppIA == NULL)
2714 return E_INVALIDARG;
2716 BOOL isGet = FALSE;
2717 if(g_pAgent)
2718 isGet = g_pAgent->GetIAccessibleFromXAccessible(pXAcc, ppIA);
2720 if(isGet)
2721 return TRUE;
2722 else
2723 return FALSE;
2725 LEAVE_PROTECTED_BLOCK
2728 void CMAccessible::get_OLECHARFromAny(Any& pAny, OLECHAR* pChar)
2730 // #CHECK#
2731 if(pChar == NULL)
2732 return;
2734 switch(pAny.getValueTypeClass())
2736 case TypeClass_CHAR:
2738 sal_Int8 val;
2739 pAny >>= val;
2740 swprintf( pChar, L"%d", val);
2741 break;
2743 case TypeClass_BOOLEAN:
2745 sal_Bool val;
2746 pAny >>= val;
2747 swprintf( pChar, L"%d", val);
2748 break;
2750 case TypeClass_BYTE:
2752 sal_Int8 val;
2753 pAny >>= val;
2754 swprintf( pChar, L"%d", val);
2755 break;
2757 case TypeClass_SHORT:
2759 SHORT val;
2760 pAny >>= val;
2761 swprintf( pChar, L"%d", val);
2762 break;
2764 case TypeClass_UNSIGNED_SHORT:
2766 USHORT val;
2767 pAny >>= val;
2768 swprintf( pChar, L"%d", val);
2769 break;
2771 case TypeClass_LONG:
2773 LONG val;
2774 pAny >>= val;
2775 swprintf( pChar, L"%ld", val);
2776 break;
2778 case TypeClass_UNSIGNED_LONG:
2780 ULONG val;
2781 pAny >>= val;
2782 swprintf( pChar, L"%ld", val);
2783 break;
2785 case TypeClass_FLOAT:
2787 FLOAT val;
2788 pAny >>= val;
2789 swprintf( pChar, L"%.3f", val);
2790 break;
2792 case TypeClass_DOUBLE:
2794 DOUBLE val;
2795 pAny >>= val;
2796 swprintf( pChar, L"%.6lf", val);
2797 break;
2799 case TypeClass_STRING:
2801 ::rtl::OUString val;
2802 pAny >>= val;
2803 wcscpy(pChar, val.getStr());
2804 break;
2806 case TypeClass_SEQUENCE:
2808 if(pAny.getValueType() == cppu::UnoType<Sequence< ::rtl::OUString >>::get())
2810 Sequence < ::rtl::OUString > val;
2811 pAny >>= 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;
2826 pAny >>= 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);
2845 else
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);
2851 else
2852 swprintf( pAttrsFillChar, L"FillChar=%c",sigleVal.FillChar);
2854 swprintf( pAttrs, L"%s,%s,%s,",pAttrsPosition,pAttrsDescimalChar,pAttrsFillChar);
2856 wcscat(pChar,pAttrs);
2859 break;
2861 case TypeClass_ENUM:
2863 if (pAny.getValueType() == cppu::UnoType<com::sun::star::awt::FontSlant>::get())
2865 com::sun::star::awt::FontSlant val;
2866 pAny >>= 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;
2875 pAny >>= 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;
2881 pAny >>= val;
2882 ::rtl::OUString realVal(val.SegmentText);
2883 wcscpy(pChar, realVal.getStr());
2885 break;
2887 case TypeClass_VOID:
2888 case TypeClass_HYPER:
2889 case TypeClass_UNSIGNED_HYPER:
2890 case TypeClass_TYPE:
2891 case TypeClass_ANY:
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:
2905 break;
2906 default:
2907 break;
2911 void CMAccessible::get_OLECHAR4Numbering(const Any& pAny, short numberingLevel,const OUString& numberingPrefix,OLECHAR* pChar)
2913 if(pChar == NULL)
2914 return;
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;
2920 aAny >>= 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,':');
2938 if(pOccur)
2939 *pOccur = '.';
2941 wcscat(propStr,pTemp);
2942 wcscat(pChar,propStr);
2943 wcscat(pChar,L",");
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);
2967 else
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));
2986 break;
2988 case TypeClass_BOOLEAN:
2989 pvData->vt = VT_BOOL;
2990 memcpy(&pvData->boolVal, rAnyVal.getValue(), sizeof(sal_Bool));
2991 break;
2993 case TypeClass_BYTE:
2994 pvData->vt = VT_UI1;
2995 memcpy(&pvData->bVal, rAnyVal.getValue(), sizeof(sal_Int8));
2996 break;
2998 case TypeClass_SHORT:
2999 pvData->vt = VT_I2;
3000 memcpy(&pvData->iVal, rAnyVal.getValue(), sizeof(sal_Int16));
3001 break;
3003 case TypeClass_UNSIGNED_SHORT:
3004 pvData->vt = VT_I2;
3005 memcpy(&pvData->iVal, rAnyVal.getValue(), sizeof(sal_uInt16));
3006 break;
3008 case TypeClass_LONG:
3009 pvData->vt = VT_I4;
3010 memcpy(&pvData->lVal, rAnyVal.getValue(), sizeof(sal_Int32));
3011 break;
3013 case TypeClass_UNSIGNED_LONG:
3014 pvData->vt = VT_I4;
3015 memcpy(&pvData->lVal, rAnyVal.getValue(), sizeof(sal_uInt32));
3016 break;
3018 case TypeClass_FLOAT:
3019 pvData->vt = VT_R4;
3020 memcpy(&pvData->fltVal, rAnyVal.getValue(), sizeof(float));
3021 break;
3023 case TypeClass_DOUBLE:
3024 pvData->vt = VT_R8;
3025 memcpy(&pvData->dblVal, rAnyVal.getValue(), sizeof(double));
3026 break;
3028 case TypeClass_STRING:
3030 pvData->vt = VT_BSTR;
3031 ::rtl::OUString val;
3032 rAnyVal >>= val;
3033 pvData->bstrVal = SysAllocString((OLECHAR *)val.getStr());
3034 break;
3037 case TypeClass_VOID:
3038 case TypeClass_HYPER:
3039 case TypeClass_UNSIGNED_HYPER:
3040 case TypeClass_TYPE:
3041 case TypeClass_ANY:
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)
3052 if(pXAcc.is())
3054 IAccessible* pIAcc = NULL;
3055 get_IAccessibleFromXAccessible(pXAcc.get(), &pIAcc);
3056 if(pIAcc == NULL)
3058 Reference< XAccessibleContext > pXAccContext = pXAcc->getAccessibleContext();
3059 g_pAgent->InsertAccObj(pXAcc.get(),pXAccContext->getAccessibleParent().get());
3060 get_IAccessibleFromXAccessible(pXAcc.get(), &pIAcc);
3062 if(pIAcc)
3064 pIAcc->AddRef();
3066 pvData->vt = VT_UNKNOWN;
3067 pvData->pdispVal = (IAccessible2*)pIAcc;
3068 break;
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());
3086 break;
3088 default:
3089 break;
3092 else
3094 VariantClear(pvData);
3098 STDMETHODIMP CMAccessible::Get_XAccChildID(long* childID)
3100 // internal IMAccessible - no mutex meeded
3102 if(childID == NULL)
3104 return E_FAIL;
3106 *childID = m_dChildID;
3107 return S_OK;
3110 STDMETHODIMP CMAccessible:: get_states(AccessibleStates __RPC_FAR *states )
3112 SolarMutexGuard g;
3114 ENTER_PROTECTED_BLOCK
3115 ISDESTROY()
3117 if (!m_xContext.is())
3118 return E_FAIL;
3120 Reference<XAccessibleStateSet> const pRStateSet =
3121 m_xContext.get()->getAccessibleStateSet();
3122 if(!pRStateSet.is())
3124 return S_OK;
3126 Sequence<short> pStates = pRStateSet->getStates();
3129 long count = pStates.getLength() ;
3130 *states = 0x0;
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];
3138 break;
3142 return S_OK;
3145 LEAVE_PROTECTED_BLOCK
3148 // return the UNO roles
3149 STDMETHODIMP CMAccessible:: get_extendedRole( BSTR __RPC_FAR * )
3151 return E_NOTIMPL;
3154 STDMETHODIMP CMAccessible:: get_localizedExtendedRole( BSTR __RPC_FAR * )
3156 return E_NOTIMPL;
3159 STDMETHODIMP CMAccessible:: get_nExtendedStates( long __RPC_FAR * )
3161 return E_NOTIMPL;
3165 STDMETHODIMP CMAccessible:: get_localizedExtendedStates( long, BSTR __RPC_FAR *__RPC_FAR *, long __RPC_FAR *)
3167 return E_NOTIMPL;
3171 STDMETHODIMP CMAccessible:: get_indexInParent( long __RPC_FAR *accParentIndex)
3173 ENTER_PROTECTED_BLOCK
3174 ISDESTROY()
3175 // #CHECK#
3176 if(accParentIndex == NULL)
3177 return E_INVALIDARG;
3179 if (!m_xContext.is())
3180 return E_FAIL;
3182 *accParentIndex = m_xContext.get()->getAccessibleIndexInParent();
3183 return S_OK;
3186 LEAVE_PROTECTED_BLOCK
3188 STDMETHODIMP CMAccessible:: get_locale( IA2Locale __RPC_FAR *locale )
3190 ENTER_PROTECTED_BLOCK
3191 ISDESTROY()
3192 if(locale == NULL)
3193 return E_INVALIDARG;
3195 if (!m_xContext.is())
3196 return E_FAIL;
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());
3203 return S_OK;
3205 LEAVE_PROTECTED_BLOCK
3208 DWORD GetMSAAStateFromUNO(short xState)
3210 DWORD IState = STATE_SYSTEM_UNAVAILABLE;
3211 switch( xState )
3213 case /*AccessibleStateType::*/AccessibleStateType::BUSY:
3214 IState = STATE_SYSTEM_BUSY;
3215 break;
3216 case /*AccessibleStateType::*/AccessibleStateType::CHECKED:
3217 IState = STATE_SYSTEM_CHECKED;
3218 break;
3219 case /*AccessibleStateType::*/AccessibleStateType::DEFUNC:
3220 IState = STATE_SYSTEM_UNAVAILABLE;
3221 break;
3222 case /*AccessibleStateType::*/AccessibleStateType::EXPANDED:
3223 IState = STATE_SYSTEM_EXPANDED;
3224 break;
3225 case /*AccessibleStateType::*/AccessibleStateType::FOCUSABLE:
3226 IState = STATE_SYSTEM_FOCUSABLE;
3227 break;
3228 case /*AccessibleStateType::*/AccessibleStateType::FOCUSED:
3229 IState = STATE_SYSTEM_FOCUSED;
3230 break;
3231 case /*AccessibleStateType::*/AccessibleStateType::INDETERMINATE:
3232 IState = STATE_SYSTEM_MIXED;
3233 break;
3234 case /*AccessibleStateType::*/AccessibleStateType::MULTI_SELECTABLE:
3235 IState = STATE_SYSTEM_MULTISELECTABLE;
3236 break;
3237 case /*AccessibleStateType::*/AccessibleStateType::PRESSED:
3238 IState = STATE_SYSTEM_PRESSED;
3239 break;
3240 case /*AccessibleStateType::*/AccessibleStateType::RESIZABLE:
3241 IState = STATE_SYSTEM_SIZEABLE;
3242 break;
3243 case /*AccessibleStateType::*/AccessibleStateType::SELECTABLE:
3244 IState = STATE_SYSTEM_SELECTABLE;
3245 break;
3246 case /*AccessibleStateType::*/AccessibleStateType::SELECTED:
3247 IState = STATE_SYSTEM_SELECTED;
3248 break;
3249 case /*AccessibleStateType::*/AccessibleStateType::ARMED:
3250 IState = STATE_SYSTEM_FOCUSED;
3251 break;
3252 case /*AccessibleStateType::*/AccessibleStateType::EXPANDABLE:
3253 IState = STATE_SYSTEM_COLLAPSED;
3254 break;
3255 default:
3256 break;
3258 return IState;
3261 STDMETHODIMP CMAccessible:: get_appName( BSTR __RPC_FAR *name)
3263 SolarMutexGuard g;
3265 ENTER_PROTECTED_BLOCK
3266 ISDESTROY()
3267 if(name == NULL)
3268 return E_INVALIDARG;
3270 *name = SysAllocString(OLESTR("Hannover"));
3271 return S_OK;
3272 LEAVE_PROTECTED_BLOCK
3274 STDMETHODIMP CMAccessible:: get_appVersion(BSTR __RPC_FAR *version)
3276 SolarMutexGuard g;
3278 ENTER_PROTECTED_BLOCK
3279 ISDESTROY()
3280 if(version == NULL)
3281 return E_INVALIDARG;
3282 *version=SysAllocString(OLESTR("3.0"));
3283 return S_OK;
3284 LEAVE_PROTECTED_BLOCK
3286 STDMETHODIMP CMAccessible:: get_toolkitName(BSTR __RPC_FAR *name)
3288 SolarMutexGuard g;
3290 ENTER_PROTECTED_BLOCK
3291 ISDESTROY()
3292 if(name == NULL)
3293 return E_INVALIDARG;
3294 *name = SysAllocString(OLESTR(" "));
3295 return S_OK;
3296 LEAVE_PROTECTED_BLOCK
3298 STDMETHODIMP CMAccessible:: get_toolkitVersion(BSTR __RPC_FAR *version)
3300 SolarMutexGuard g;
3302 ENTER_PROTECTED_BLOCK
3303 ISDESTROY()
3304 if(version == NULL)
3305 return E_INVALIDARG;
3306 *version = SysAllocString(OLESTR(" "));
3307 return S_OK;
3308 LEAVE_PROTECTED_BLOCK
3312 STDMETHODIMP CMAccessible::get_attributes(/*[out]*/ BSTR *pAttr)
3314 SolarMutexGuard g;
3316 ENTER_PROTECTED_BLOCK
3317 ISDESTROY()
3319 if (!m_xAccessible.is())
3320 return E_FAIL;
3322 Reference<XAccessibleContext> pRContext = m_xAccessible->getAccessibleContext();
3323 if( !pRContext.is() )
3325 return E_FAIL;
3327 Reference<XAccessibleExtendedAttributes> pRXI(pRContext,UNO_QUERY);
3328 if( !pRXI.is() )
3329 return E_FAIL;
3330 else
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;
3337 anyVal >>= val;
3339 if(*pAttr)
3340 SAFE_SYSFREESTRING(*pAttr);
3341 *pAttr = SysAllocString((OLECHAR *)val.getStr());
3343 return S_OK;
3345 LEAVE_PROTECTED_BLOCK
3348 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */