summaryrefslogtreecommitdiffstats
path: root/winaccessibility/source/UAccCOM
diff options
context:
space:
mode:
Diffstat (limited to 'winaccessibility/source/UAccCOM')
-rw-r--r--winaccessibility/source/UAccCOM/AccAction.cxx118
-rw-r--r--winaccessibility/source/UAccCOM/AccAction.h102
-rw-r--r--winaccessibility/source/UAccCOM/AccActionBase.cxx221
-rw-r--r--winaccessibility/source/UAccCOM/AccActionBase.h74
-rw-r--r--winaccessibility/source/UAccCOM/AccComponent.cxx66
-rw-r--r--winaccessibility/source/UAccCOM/AccComponent.h87
-rw-r--r--winaccessibility/source/UAccCOM/AccComponentBase.cxx214
-rw-r--r--winaccessibility/source/UAccCOM/AccComponentBase.h63
-rw-r--r--winaccessibility/source/UAccCOM/AccEditableText.cxx505
-rw-r--r--winaccessibility/source/UAccCOM/AccEditableText.h118
-rw-r--r--winaccessibility/source/UAccCOM/AccHyperLink.cxx300
-rw-r--r--winaccessibility/source/UAccCOM/AccHyperLink.h136
-rw-r--r--winaccessibility/source/UAccCOM/AccHypertext.cxx401
-rw-r--r--winaccessibility/source/UAccCOM/AccHypertext.h153
-rw-r--r--winaccessibility/source/UAccCOM/AccImage.cxx119
-rw-r--r--winaccessibility/source/UAccCOM/AccImage.h99
-rw-r--r--winaccessibility/source/UAccCOM/AccRelation.cxx217
-rw-r--r--winaccessibility/source/UAccCOM/AccRelation.h91
-rw-r--r--winaccessibility/source/UAccCOM/AccTable.cxx1095
-rw-r--r--winaccessibility/source/UAccCOM/AccTable.h184
-rw-r--r--winaccessibility/source/UAccCOM/AccTableCell.cxx186
-rw-r--r--winaccessibility/source/UAccCOM/AccTableCell.h87
-rw-r--r--winaccessibility/source/UAccCOM/AccText.cxx267
-rw-r--r--winaccessibility/source/UAccCOM/AccText.h129
-rw-r--r--winaccessibility/source/UAccCOM/AccTextBase.cxx911
-rw-r--r--winaccessibility/source/UAccCOM/AccTextBase.h113
-rw-r--r--winaccessibility/source/UAccCOM/AccValue.cxx245
-rw-r--r--winaccessibility/source/UAccCOM/AccValue.h102
-rw-r--r--winaccessibility/source/UAccCOM/AccessibleKeyStroke.h152
-rw-r--r--winaccessibility/source/UAccCOM/EnumVariant.cxx245
-rw-r--r--winaccessibility/source/UAccCOM/EnumVariant.h109
-rw-r--r--winaccessibility/source/UAccCOM/MAccessible.cxx3162
-rw-r--r--winaccessibility/source/UAccCOM/MAccessible.h242
-rw-r--r--winaccessibility/source/UAccCOM/Resource.h38
-rw-r--r--winaccessibility/source/UAccCOM/StdAfx.cxx26
-rw-r--r--winaccessibility/source/UAccCOM/UAccCOM.cxx117
-rw-r--r--winaccessibility/source/UAccCOM/UAccCOM.def5
-rw-r--r--winaccessibility/source/UAccCOM/UAccCOM.rc90
-rw-r--r--winaccessibility/source/UAccCOM/UNOXWrapper.cxx43
-rw-r--r--winaccessibility/source/UAccCOM/UNOXWrapper.h58
-rw-r--r--winaccessibility/source/UAccCOM/acccommon.h68
-rw-r--r--winaccessibility/source/UAccCOM/stdafx.h65
42 files changed, 10823 insertions, 0 deletions
diff --git a/winaccessibility/source/UAccCOM/AccAction.cxx b/winaccessibility/source/UAccCOM/AccAction.cxx
new file mode 100644
index 000000000..97bfc4f40
--- /dev/null
+++ b/winaccessibility/source/UAccCOM/AccAction.cxx
@@ -0,0 +1,118 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+/**
+ * AccAction.cpp : Implementation of CAccAction
+ */
+#include "stdafx.h"
+#include "AccAction.h"
+
+#if defined __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wnon-virtual-dtor"
+#endif
+#include <UAccCOM.h>
+#if defined __clang__
+#pragma clang diagnostic pop
+#endif
+
+using namespace com::sun::star::accessibility;
+using namespace com::sun::star::uno;
+
+/**
+ * Returns the number of action.
+ *
+ * @param nActions the number of action.
+ */
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccAction::nActions(/*[out,retval]*/long* nActions)
+{
+
+ return CAccActionBase::nActions(nActions);
+}
+
+/**
+ * Performs specified action on the object.
+ *
+ * @param actionIndex the index of action.
+ */
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccAction::doAction(/* [in] */ long actionIndex)
+{
+
+ return CAccActionBase::doAction(actionIndex);
+}
+
+/**
+ * Gets description of specified action.
+ *
+ * @param actionIndex the index of action.
+ * @param description the description string of the specified action.
+ */
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccAction::get_description(long actionIndex,BSTR __RPC_FAR *description)
+{
+
+ return CAccActionBase::get_description(actionIndex, description);
+}
+
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccAction::get_name( long actionIndex, BSTR __RPC_FAR *name)
+{
+
+ return CAccActionBase::get_name(actionIndex, name);
+}
+
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccAction::get_localizedName( long actionIndex, BSTR __RPC_FAR *localizedName)
+{
+
+ return CAccActionBase::get_localizedName(actionIndex, localizedName);
+}
+
+/**
+ * Returns key binding object (if any) associated with specified action
+ * key binding is string.
+ * e.g. "alt+d" (like IAccessible::get_accKeyboardShortcut).
+ *
+ * @param actionIndex the index of action.
+ * @param nMaxBinding the max number of key binding.
+ * @param keyBinding the key binding array.
+ * @param nBinding the actual number of key binding returned.
+ */
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccAction::get_keyBinding(
+ /* [in] */ long actionIndex,
+ /* [in] */ long nMaxBinding,
+ /* [length_is][length_is][size_is][size_is][out] */ BSTR __RPC_FAR *__RPC_FAR *keyBinding,
+ /* [retval][out] */ long __RPC_FAR *nBinding)
+{
+
+ return CAccActionBase::get_keyBinding(actionIndex, nMaxBinding, keyBinding, nBinding);
+}
+
+/**
+ * Put UNO interface.
+ * @param pXSubInterface XAccessibleHyperlink interface.
+ * @return Result.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccAction::put_XSubInterface(hyper pXSubInterface)
+{
+
+
+ pRXAct = reinterpret_cast<XAccessibleAction*>(pXSubInterface);
+
+ return S_OK;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/winaccessibility/source/UAccCOM/AccAction.h b/winaccessibility/source/UAccCOM/AccAction.h
new file mode 100644
index 000000000..7fcff0810
--- /dev/null
+++ b/winaccessibility/source/UAccCOM/AccAction.h
@@ -0,0 +1,102 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include "Resource.h" // main symbols
+#include "AccActionBase.h"
+
+/**
+ * CAccAction implements IAccessibleAction interface.
+ */
+class ATL_NO_VTABLE CAccAction :
+ public CComObjectRoot,
+ public CComCoClass<CAccAction, &CLSID_AccAction>,
+ public IAccessibleAction,
+ public CAccActionBase
+{
+public:
+ CAccAction()
+ {
+
+ }
+
+ DECLARE_NO_REGISTRY()
+
+ BEGIN_COM_MAP(CAccAction)
+ COM_INTERFACE_ENTRY(IAccessibleAction)
+ COM_INTERFACE_ENTRY(IUNOXWrapper)
+ COM_INTERFACE_ENTRY_FUNC_BLIND(0,SmartQI_)
+#if defined __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Winconsistent-missing-override"
+#endif
+ END_COM_MAP()
+#if defined __clang__
+#pragma clang diagnostic pop
+#endif
+
+ static HRESULT WINAPI SmartQI_(void* pv,
+ REFIID iid, void** ppvObject, DWORD_PTR)
+ {
+ return static_cast<CAccAction*>(pv)->SmartQI(iid,ppvObject);
+ }
+
+ HRESULT SmartQI(REFIID iid, void** ppvObject)
+ {
+ if( m_pOuterUnknown )
+ return OuterQueryInterface(iid,ppvObject);
+ return E_FAIL;
+ }
+
+ // IAccessibleAction
+public:
+ // IAccessibleAction
+
+ // Returns the number of action.
+ STDMETHOD(nActions)(/*[out,retval]*/long* nActions) override;
+
+ // Performs specified action on the object.
+ STDMETHOD(doAction)(/* [in] */ long actionIndex) override;
+
+ // Gets description of specified action.
+ STDMETHOD(get_description)(long actionIndex,BSTR __RPC_FAR *description) override;
+
+ // added , 2006/06/28, for driver 07/11
+ // get the action name
+ STDMETHOD(get_name)( long actionIndex, BSTR __RPC_FAR *name) override;
+
+ // get the localized action name
+ STDMETHOD(get_localizedName)( long actionIndex, BSTR __RPC_FAR *localizedName) override;
+
+ // Returns key binding object (if any) associated with specified action
+ // key binding is string.
+ // e.g. "alt+d" (like IAccessible::get_accKeyboardShortcut).
+ STDMETHOD(get_keyBinding)(
+ /* [in] */ long actionIndex,
+ /* [in] */ long nMaxBinding,
+ /* [length_is][length_is][size_is][size_is][out] */ BSTR __RPC_FAR *__RPC_FAR *keyBinding,
+ /* [retval][out] */ long __RPC_FAR *nBinding) override;
+
+ // Override of IUNOXWrapper.
+ STDMETHOD(put_XSubInterface)(hyper pXSubInterface) override;
+
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/winaccessibility/source/UAccCOM/AccActionBase.cxx b/winaccessibility/source/UAccCOM/AccActionBase.cxx
new file mode 100644
index 000000000..cd68f3032
--- /dev/null
+++ b/winaccessibility/source/UAccCOM/AccActionBase.cxx
@@ -0,0 +1,221 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+
+// AccActionBase.cpp: implementation of the CAccActionBase class.
+
+#include "stdafx.h"
+
+#include "AccActionBase.h"
+#include <com/sun/star/accessibility/XAccessible.hpp>
+#include <com/sun/star/accessibility/AccessibleStateType.hpp>
+#include <com/sun/star/accessibility/AccessibleRole.hpp>
+#include <com/sun/star/accessibility/XAccessibleContext.hpp>
+
+#include <vcl/svapp.hxx>
+#include <o3tl/char16_t2wchar_t.hxx>
+#include <comphelper/AccessibleImplementationHelper.hxx>
+
+#include "AccessibleKeyStroke.h"
+
+#include "acccommon.h"
+
+using namespace com::sun::star::accessibility::AccessibleRole;
+using namespace com::sun::star::accessibility;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::awt;
+
+
+// Construction/Destruction
+
+
+CAccActionBase::CAccActionBase()
+{}
+
+CAccActionBase::~CAccActionBase()
+{}
+
+/**
+ * Returns the number of action.
+ *
+ * @param nActions the number of action.
+ */
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccActionBase::nActions(/*[out,retval]*/long* nActions)
+{
+ SolarMutexGuard g;
+
+ try {
+
+ // #CHECK#
+ if( pRXAct.is() && nActions != nullptr )
+ {
+ *nActions = GetXInterface()->getAccessibleActionCount();
+ return S_OK;
+ }
+ *nActions = 0;
+
+ return S_OK;
+
+ } catch(...) { return E_FAIL; }
+}
+
+/**
+ * Performs specified action on the object.
+ *
+ * @param actionIndex the index of action.
+ */
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccActionBase::doAction(/* [in] */ long actionIndex)
+{
+ SolarMutexGuard g;
+
+ try {
+
+ if( pRXAct.is() )
+ {
+ return GetXInterface()->doAccessibleAction( actionIndex )?S_OK:E_FAIL;
+ }
+ return E_FAIL;
+
+ } catch(...) { return E_FAIL; }
+}
+
+/**
+ * Gets description of specified action.
+ *
+ * @param actionIndex the index of action.
+ * @param description the description string of the specified action.
+ */
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccActionBase::get_description(long actionIndex,BSTR __RPC_FAR *description)
+{
+ SolarMutexGuard g;
+
+ try {
+
+ // #CHECK#
+ if(description == nullptr)
+ return E_INVALIDARG;
+
+ // #CHECK XInterface#
+ if(!pRXAct.is())
+ return E_FAIL;
+
+ OUString ouStr = GetXInterface()->getAccessibleActionDescription(actionIndex);
+ // #CHECK#
+
+ SysFreeString(*description);
+ *description = SysAllocString(o3tl::toW(ouStr.getStr()));
+
+ return S_OK;
+
+ } catch(...) { return E_FAIL; }
+}
+
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccActionBase::get_name( long, BSTR __RPC_FAR *)
+{
+ return E_NOTIMPL;
+}
+
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccActionBase::get_localizedName( long, BSTR __RPC_FAR *)
+{
+ return E_NOTIMPL;
+}
+
+/**
+ * Returns key binding object (if any) associated with specified action
+ * key binding is string.
+ * e.g. "alt+d" (like IAccessible::get_accKeyboardShortcut).
+ *
+ * @param actionIndex the index of action.
+ * @param nMaxBinding the max number of key binding.
+ * @param keyBinding the key binding array.
+ * @param nBinding the actual number of key binding returned.
+ */
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccActionBase::get_keyBinding(
+ /* [in] */ long actionIndex,
+ /* [in] */ long,
+ /* [length_is][length_is][size_is][size_is][out] */ BSTR __RPC_FAR *__RPC_FAR *keyBinding,
+ /* [retval][out] */ long __RPC_FAR *nBinding)
+{
+ SolarMutexGuard g;
+
+ try {
+
+ if( !keyBinding || !nBinding)
+ return E_INVALIDARG;
+
+ if( !pRXAct.is() )
+ return E_FAIL;
+
+ Reference< XAccessibleKeyBinding > binding = GetXInterface()->getAccessibleActionKeyBinding(actionIndex);
+ if( !binding.is() )
+ return E_FAIL;
+
+ sal_Int32 nCount = binding->getAccessibleKeyBindingCount();
+
+ *keyBinding = static_cast<BSTR*>(::CoTaskMemAlloc(nCount*sizeof(BSTR)));
+
+ // #CHECK Memory Allocation#
+ if(*keyBinding == nullptr)
+ return E_FAIL;
+
+ for( sal_Int32 index = 0;index < nCount;index++ )
+ {
+ auto const wString = comphelper::GetkeyBindingStrByXkeyBinding(
+ binding->getAccessibleKeyBinding(index));
+
+ (*keyBinding)[index] = SysAllocString(o3tl::toW(wString.getStr()));
+ }
+
+ *nBinding = nCount;
+ return S_OK;
+
+ } catch(...) { return E_FAIL; }
+}
+
+/**
+ * Override of IUNOXWrapper.
+ *
+ * @param pXInterface the pointer of UNO interface.
+ */
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccActionBase::put_XInterface(hyper pXInterface)
+{
+ // internal IUNOXWrapper - no mutex meeded
+
+ try {
+
+ CUNOXWrapper::put_XInterface(pXInterface);
+
+ //special query.
+ if(pUNOInterface == nullptr)
+ return E_FAIL;
+ Reference<XAccessibleContext> pRContext = pUNOInterface->getAccessibleContext();
+ if( !pRContext.is() )
+ return E_FAIL;
+
+ Reference<XAccessibleAction> pRXI(pRContext,UNO_QUERY);
+ if( !pRXI.is() )
+ pRXAct = nullptr;
+ else
+ pRXAct = pRXI.get();
+ return S_OK;
+
+ } catch(...) { return E_FAIL; }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/winaccessibility/source/UAccCOM/AccActionBase.h b/winaccessibility/source/UAccCOM/AccActionBase.h
new file mode 100644
index 000000000..26d3e7d05
--- /dev/null
+++ b/winaccessibility/source/UAccCOM/AccActionBase.h
@@ -0,0 +1,74 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+// AccActionBase.h: interface for the CAccActionBase class.
+
+#pragma once
+
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/accessibility/XAccessibleAction.hpp>
+#include "UNOXWrapper.h"
+
+class ATL_NO_VTABLE CAccActionBase : public CUNOXWrapper
+{
+public:
+ CAccActionBase();
+ virtual ~CAccActionBase();
+
+ // IAccessibleAction
+public:
+ // IAccessibleAction
+
+ // Returns the number of action.
+ STDMETHOD(nActions)(/*[out,retval]*/ long* nActions);
+
+ // Performs specified action on the object.
+ STDMETHOD(doAction)(/* [in] */ long actionIndex);
+
+ // Gets description of specified action.
+ STDMETHOD(get_description)(long actionIndex, BSTR __RPC_FAR* description);
+
+ // added , 2006/06/28, for driver 07/11
+ // get the action name
+ STDMETHOD(get_name)(long actionIndex, BSTR __RPC_FAR* name);
+
+ // get the localized action Name
+ STDMETHOD(get_localizedName)(long actionIndex, BSTR __RPC_FAR* localizedName);
+
+ // Returns key binding object (if any) associated with specified action
+ // key binding is string.
+ // e.g. "alt+d" (like IAccessible::get_accKeyboardShortcut).
+ STDMETHOD(get_keyBinding)
+ (
+ /* [in] */ long actionIndex,
+ /* [in] */ long nMaxBinding,
+ /* [length_is][length_is][size_is][size_is][out] */ BSTR __RPC_FAR* __RPC_FAR* keyBinding,
+ /* [retval][out] */ long __RPC_FAR* nBinding);
+
+ // Override of IUNOXWrapper.
+ STDMETHOD(put_XInterface)(hyper pXInterface) override;
+
+protected:
+ css::uno::Reference<css::accessibility::XAccessibleAction> pRXAct;
+
+private:
+ css::accessibility::XAccessibleAction* GetXInterface() { return pRXAct.get(); }
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/winaccessibility/source/UAccCOM/AccComponent.cxx b/winaccessibility/source/UAccCOM/AccComponent.cxx
new file mode 100644
index 000000000..2ca64cd7d
--- /dev/null
+++ b/winaccessibility/source/UAccCOM/AccComponent.cxx
@@ -0,0 +1,66 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+/**
+ * AccComponent.cpp : Implementation of CUAccCOMApp and DLL registration.
+ */
+#include "stdafx.h"
+#include "AccComponent.h"
+
+#if defined __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wnon-virtual-dtor"
+#endif
+#include <UAccCOM.h>
+#if defined __clang__
+#pragma clang diagnostic pop
+#endif
+
+/**
+ * Returns the location of the upper left corner of the object's bounding
+ * box relative to the parent.
+ *
+ * @param Location the upper left corner of the object's bounding box.
+ */
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccComponent::get_locationInParent(long* x, long* y)
+{
+ return CAccComponentBase::get_locationInParent(x, y);
+}
+
+/**
+ * Returns the foreground color of this object.
+ *
+ * @param Color the color of foreground.
+ */
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccComponent::get_foreground(IA2Color* foreground)
+{
+ return CAccComponentBase::get_foreground(foreground);
+}
+
+/**
+ * Returns the background color of this object.
+ *
+ * @param Color the color of background.
+ */
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccComponent::get_background(IA2Color* background)
+{
+ return CAccComponentBase::get_background(background);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/winaccessibility/source/UAccCOM/AccComponent.h b/winaccessibility/source/UAccCOM/AccComponent.h
new file mode 100644
index 000000000..9a620a523
--- /dev/null
+++ b/winaccessibility/source/UAccCOM/AccComponent.h
@@ -0,0 +1,87 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include "Resource.h" // main symbols
+
+#include <com/sun/star/accessibility/XAccessible.hpp>
+#include <com/sun/star/accessibility/XAccessibleContext.hpp>
+#include <com/sun/star/accessibility/XAccessibleComponent.hpp>
+#include "UNOXWrapper.h"
+#include "AccComponentBase.h"
+
+
+/**
+ * CAccComponent implements IAccessibleComponent interface.
+ */
+class ATL_NO_VTABLE CAccComponent :
+ public CComObjectRoot,
+ public CComCoClass<CAccComponent,&CLSID_AccComponent>,
+ public IAccessibleComponent,
+ public CAccComponentBase
+{
+public:
+ CAccComponent()
+ {
+ }
+
+ BEGIN_COM_MAP(CAccComponent)
+ COM_INTERFACE_ENTRY(IAccessibleComponent)
+ COM_INTERFACE_ENTRY(IUNOXWrapper)
+ COM_INTERFACE_ENTRY_FUNC_BLIND(0,SmartQI_)
+#if defined __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Winconsistent-missing-override"
+#endif
+ END_COM_MAP()
+#if defined __clang__
+#pragma clang diagnostic pop
+#endif
+
+ static HRESULT WINAPI SmartQI_(void* pv,
+ REFIID iid, void** ppvObject, DWORD_PTR)
+ {
+ return static_cast<CAccComponent*>(pv)->SmartQI(iid,ppvObject);
+ }
+
+ HRESULT SmartQI(REFIID iid, void** ppvObject)
+ {
+ if( m_pOuterUnknown )
+ return OuterQueryInterface(iid,ppvObject);
+ return E_FAIL;
+ }
+
+ DECLARE_NO_REGISTRY()
+
+public:
+ // IAccessibleComponent
+
+ // Returns the location of the upper left corner of the object's bounding
+ // box relative to the parent.
+ STDMETHOD(get_locationInParent)(long *x, long *y) override;
+
+ // Returns the foreground color of this object.
+ STDMETHOD(get_foreground)(IA2Color * foreground) override;
+
+ // Returns the background color of this object.
+ STDMETHOD(get_background)(IA2Color * background) override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/winaccessibility/source/UAccCOM/AccComponentBase.cxx b/winaccessibility/source/UAccCOM/AccComponentBase.cxx
new file mode 100644
index 000000000..ed44c2c93
--- /dev/null
+++ b/winaccessibility/source/UAccCOM/AccComponentBase.cxx
@@ -0,0 +1,214 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "stdafx.h"
+#include "AccComponentBase.h"
+#include <com/sun/star/accessibility/XAccessible.hpp>
+#include <com/sun/star/accessibility/XAccessibleContext.hpp>
+#include <vcl/svapp.hxx>
+#include "MAccessible.h"
+
+using namespace com::sun::star::accessibility;
+using namespace com::sun::star::uno;
+
+// Construction/Destruction
+
+CAccComponentBase::CAccComponentBase() {}
+
+CAccComponentBase::~CAccComponentBase() {}
+
+/**
+ * Returns the location of the upper left corner of the object's bounding
+ * box relative to the parent.
+ *
+ * @param Location the upper left corner of the object's bounding box.
+ */
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccComponentBase::get_locationInParent(long* x, long* y)
+{
+ SolarMutexGuard g;
+
+ try
+ {
+ if (x == nullptr || y == nullptr)
+ return E_INVALIDARG;
+ // #CHECK XInterface#
+ if (!pRXComp.is())
+ return E_FAIL;
+
+ const css::awt::Point& pt = GetXInterface()->getLocation();
+ *x = pt.X;
+ *y = pt.Y;
+ return S_OK;
+ }
+ catch (...)
+ {
+ return E_FAIL;
+ }
+}
+
+/**
+ * Returns the location of the upper left corner of the object's bounding
+ * box in screen.
+ *
+ * @param Location the upper left corner of the object's bounding
+ * box in screen coordinates.
+ */
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccComponentBase::get_locationOnScreen(long* x, long* y)
+{
+ SolarMutexGuard g;
+
+ try
+ {
+ if (x == nullptr || y == nullptr)
+ return E_INVALIDARG;
+ // #CHECK XInterface#
+ if (!pRXComp.is())
+ return E_FAIL;
+
+ const css::awt::Point& pt = GetXInterface()->getLocationOnScreen();
+ *x = pt.X;
+ *y = pt.Y;
+ return S_OK;
+ }
+ catch (...)
+ {
+ return E_FAIL;
+ }
+}
+
+/**
+ * Grabs the focus to this object.
+ *
+ * @param success the boolean result to be returned.
+ */
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccComponentBase::grabFocus(boolean* success)
+{
+ SolarMutexGuard g;
+
+ try
+ {
+ if (success == nullptr)
+ return E_INVALIDARG;
+ // #CHECK XInterface#
+ if (!pRXComp.is())
+ {
+ return E_FAIL;
+ }
+ GetXInterface()->grabFocus();
+ *success = TRUE;
+
+ return S_OK;
+ }
+ catch (...)
+ {
+ return E_FAIL;
+ }
+}
+
+/**
+ * Returns the foreground color of this object.
+ *
+ * @param Color the color of foreground.
+ */
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccComponentBase::get_foreground(IA2Color* foreground)
+{
+ SolarMutexGuard g;
+
+ try
+ {
+ if (foreground == nullptr)
+ return E_INVALIDARG;
+ // #CHECK XInterface#
+ if (!pRXComp.is())
+ {
+ return E_FAIL;
+ }
+ *foreground = static_cast<long>(GetXInterface()->getForeground());
+
+ return S_OK;
+ }
+ catch (...)
+ {
+ return E_FAIL;
+ }
+}
+
+/**
+ * Returns the background color of this object.
+ *
+ * @param Color the color of background.
+ */
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccComponentBase::get_background(IA2Color* background)
+{
+ SolarMutexGuard g;
+
+ try
+ {
+ if (background == nullptr)
+ return E_INVALIDARG;
+ // #CHECK XInterface#
+ if (!pRXComp.is())
+ {
+ return E_FAIL;
+ }
+ *background = static_cast<long>(GetXInterface()->getBackground());
+
+ return S_OK;
+ }
+ catch (...)
+ {
+ return E_FAIL;
+ }
+}
+
+/**
+ * Override of IUNOXWrapper.
+ *
+ * @param pXInterface the pointer of UNO interface.
+ */
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccComponentBase::put_XInterface(hyper pXInterface)
+{
+ // internal IUNOXWrapper - no mutex meeded
+
+ try
+ {
+ CUNOXWrapper::put_XInterface(pXInterface);
+ //special query.
+ if (pUNOInterface == nullptr)
+ return E_FAIL;
+ Reference<XAccessibleContext> pRContext = pUNOInterface->getAccessibleContext();
+ if (!pRContext.is())
+ {
+ return E_FAIL;
+ }
+ Reference<XAccessibleComponent> pRXI(pRContext, UNO_QUERY);
+ if (!pRXI.is())
+ pRXComp = nullptr;
+ else
+ pRXComp = pRXI.get();
+
+ return S_OK;
+ }
+ catch (...)
+ {
+ return E_FAIL;
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/winaccessibility/source/UAccCOM/AccComponentBase.h b/winaccessibility/source/UAccCOM/AccComponentBase.h
new file mode 100644
index 000000000..83770ba2d
--- /dev/null
+++ b/winaccessibility/source/UAccCOM/AccComponentBase.h
@@ -0,0 +1,63 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+// AccComponentBase.h: interface for the CAccComponentBase class.
+
+#pragma once
+
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/accessibility/XAccessibleComponent.hpp>
+#include "UNOXWrapper.h"
+
+class ATL_NO_VTABLE CAccComponentBase : public CUNOXWrapper
+{
+public:
+ CAccComponentBase();
+ virtual ~CAccComponentBase();
+ // IAccessibleComponent
+public:
+ // IAccessibleComponent
+
+ // Returns the location of the upper left corner of the object's bounding
+ // box relative to the parent.
+ STDMETHOD(get_locationInParent)(long* x, long* y);
+
+ // Returns the location of the upper left corner of the object's bounding
+ // box in screen.
+ STDMETHOD(get_locationOnScreen)(long* x, long* y);
+
+ // Grabs the focus to this object.
+ STDMETHOD(grabFocus)(boolean* success);
+
+ // Returns the foreground color of this object.
+ STDMETHOD(get_foreground)(IA2Color* foreground);
+
+ // Returns the background color of this object.
+ STDMETHOD(get_background)(IA2Color* background);
+
+ // Override of IUNOXWrapper.
+ STDMETHOD(put_XInterface)(hyper pXInterface) override;
+
+protected:
+ css::uno::Reference<css::accessibility::XAccessibleComponent> pRXComp;
+
+ css::accessibility::XAccessibleComponent* GetXInterface() { return pRXComp.get(); }
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/winaccessibility/source/UAccCOM/AccEditableText.cxx b/winaccessibility/source/UAccCOM/AccEditableText.cxx
new file mode 100644
index 000000000..2bfd84366
--- /dev/null
+++ b/winaccessibility/source/UAccCOM/AccEditableText.cxx
@@ -0,0 +1,505 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+/**
+ * AccEditableText.cpp : Implementation of CUAccCOMApp and DLL registration.
+ */
+#include "stdafx.h"
+#include "AccEditableText.h"
+
+#if defined __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wnon-virtual-dtor"
+#endif
+#include <UAccCOM.h>
+#if defined __clang__
+#pragma clang diagnostic pop
+#endif
+
+#include <vcl/svapp.hxx>
+#include <o3tl/char16_t2wchar_t.hxx>
+
+#include <com/sun/star/accessibility/XAccessible.hpp>
+#include <com/sun/star/accessibility/XAccessibleContext.hpp>
+#include <com/sun/star/accessibility/XAccessibleText.hpp>
+#include <com/sun/star/awt/FontSlant.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/style/LineSpacing.hpp>
+#include <com/sun/star/style/TabStop.hpp>
+#include <vector>
+
+using namespace com::sun::star::accessibility;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::awt;
+using namespace com::sun::star::beans;
+
+/**
+ * Copy a range of text to the clipboard.
+ *
+ * @param startOffset the start offset of copying.
+ * @param endOffset the end offset of copying.
+ * @param success the boolean result to be returned.
+ */
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccEditableText::copyText(long startOffset, long endOffset)
+{
+ SolarMutexGuard g;
+
+ try {
+
+ // #CHECK XInterface#
+ if(!pRXEdtTxt.is())
+ {
+ return E_FAIL;
+ }
+
+ if ( GetXInterface()->copyText( startOffset, endOffset ) )
+ return S_OK;
+
+ return E_FAIL;
+
+ } catch(...) { return E_FAIL; }
+}
+
+/**
+ * Deletes a range of text.
+ *
+ * @param startOffset the start offset of deleting.
+ * @param endOffset the end offset of deleting.
+ * @param success the boolean result to be returned.
+ */
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccEditableText::deleteText(long startOffset, long endOffset)
+{
+ SolarMutexGuard g;
+
+ try {
+
+ if( !pRXEdtTxt.is() )
+ return E_FAIL;
+
+ if( GetXInterface()->deleteText( startOffset, endOffset ) )
+ return S_OK;
+
+ return E_FAIL;
+
+ } catch(...) { return E_FAIL; }
+}
+
+/**
+ * Inserts text at a specified offset.
+ *
+ * @param offset the offset of inserting.
+ * @param text the text to be inserted.
+ * @param success the boolean result to be returned.
+ */
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccEditableText::insertText(long offset, BSTR * text)
+{
+ SolarMutexGuard g;
+
+ try {
+
+ if (text == nullptr)
+ return E_INVALIDARG;
+
+ if( !pRXEdtTxt.is() )
+ return E_FAIL;
+
+ OUString ouStr(o3tl::toU(*text));
+
+ if( GetXInterface()->insertText( ouStr, offset ) )
+ return S_OK;
+
+ return E_FAIL;
+
+ } catch(...) { return E_FAIL; }
+}
+
+/**
+ * Cuts a range of text to the clipboard.
+ *
+ * @param startOffset the start offset of cutting.
+ * @param endOffset the end offset of cutting.
+ * @param success the boolean result to be returned.
+ */
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccEditableText::cutText(long startOffset, long endOffset)
+{
+ SolarMutexGuard g;
+
+ try {
+
+ if( !pRXEdtTxt.is() )
+ return E_FAIL;
+
+ if( GetXInterface()->cutText( startOffset, endOffset ) )
+ return S_OK;
+
+ return E_FAIL;
+
+ } catch(...) { return E_FAIL; }
+}
+
+/**
+ * Pastes text from clipboard at specified offset.
+ *
+ * @param offset the offset of pasting.
+ * @param success the boolean result to be returned.
+ */
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccEditableText::pasteText(long offset)
+{
+ SolarMutexGuard g;
+
+ try {
+
+ if( !pRXEdtTxt.is() )
+ return E_FAIL;
+
+ if( GetXInterface()->pasteText( offset ) )
+ return S_OK;
+
+ return E_FAIL;
+
+ } catch(...) { return E_FAIL; }
+}
+
+/**
+ * Replaces range of text with new text.
+ *
+ * @param startOffset the start offset of replacing.
+ * @param endOffset the end offset of replacing.
+ * @param text the replacing text.
+ * @param success the boolean result to be returned.
+ */
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccEditableText::replaceText(long startOffset, long endOffset, BSTR * text)
+{
+ SolarMutexGuard g;
+
+ try {
+
+ // #CHECK#
+ if (text == nullptr)
+ return E_INVALIDARG;
+ if( !pRXEdtTxt.is() )
+ return E_FAIL;
+
+ OUString ouStr(o3tl::toU(*text));
+
+ if( GetXInterface()->replaceText( startOffset,endOffset, ouStr) )
+ return S_OK;
+ return E_FAIL;
+
+ } catch(...) { return E_FAIL; }
+}
+
+/**
+ * Sets attributes of range of text.
+ *
+ * @param startOffset the start offset.
+ * @param endOffset the end offset.
+ * @param attributes the attribute text.
+ * @param success the boolean result to be returned.
+ */
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccEditableText::setAttributes(long startOffset, long endOffset, BSTR * attributes)
+{
+ SolarMutexGuard g;
+
+ try {
+
+ // #CHECK#
+ if (attributes == nullptr)
+ return E_INVALIDARG;
+ if( !pRXEdtTxt.is() )
+ return E_FAIL;
+
+ OUString ouStr(o3tl::toU(*attributes));
+
+ std::vector< OUString > vecAttr;
+ for (sal_Int32 nIndex {0}; nIndex >= 0; )
+ vecAttr.push_back(ouStr.getToken(0, ';', nIndex));
+
+ Sequence< PropertyValue > beanSeq(vecAttr.size());
+ auto beanSeqRange = asNonConstRange(beanSeq);
+ for(std::vector<OUString>::size_type i = 0; i < vecAttr.size(); i ++)
+ {
+ OUString attr = vecAttr[i];
+ sal_Int32 nPos = attr.indexOf(':');
+ if(nPos > -1)
+ {
+ OUString attrName = attr.copy(0, nPos);
+ OUString attrValue = attr.copy(nPos + 1);
+ beanSeqRange[i].Name = attrName;
+ get_AnyFromOLECHAR(attrName, attrValue, beanSeqRange[i].Value);
+ }
+ }
+
+ if( GetXInterface()->setAttributes( startOffset,endOffset, beanSeq) )
+ return S_OK;
+
+ return E_FAIL;
+
+ } catch(...) { return E_FAIL; }
+}
+
+/**
+ * Convert attributes string to Any type.
+ *
+ * @param ouName the string of attribute name.
+ * @param ouValue the string of attribute value.
+ * @param rAny the Any object to be returned.
+ */
+void CAccEditableText::get_AnyFromOLECHAR(std::u16string_view ouName, const OUString &ouValue, Any &rAny)
+{
+ if(ouName == u"CharBackColor" ||
+ ouName == u"CharColor" ||
+ ouName == u"ParaAdjust" ||
+ ouName == u"ParaFirstLineIndent" ||
+ ouName == u"ParaLeftMargin" ||
+ ouName == u"ParaRightMargin" ||
+ ouName == u"ParaTopMargin" ||
+ ouName == u"ParaBottomMargin" ||
+ ouName == u"CharFontPitch" )
+ {
+ // Convert to int.
+ // NOTE: CharFontPitch is not implemented in java file.
+ sal_Int32 nValue = ouValue.toInt32();
+ rAny.setValue(&nValue, cppu::UnoType<sal_Int32>::get());
+ }
+ else if(ouName == u"CharShadowed" ||
+ ouName == u"CharContoured" )
+ {
+ // Convert to boolean.
+ rAny <<= ouValue.toBoolean();
+ }
+ else if(ouName == u"CharEscapement" ||
+ ouName == u"CharStrikeout" ||
+ ouName == u"CharUnderline" ||
+ ouName == u"CharFontPitch" )
+ {
+ // Convert to short.
+ short nValue = static_cast<short>(ouValue.toInt32());
+ rAny.setValue(&nValue, cppu::UnoType<short>::get());
+ }
+ else if(ouName == u"CharHeight" ||
+ ouName == u"CharWeight" )
+ {
+ // Convert to float.
+ float fValue = ouValue.toFloat();
+ rAny.setValue(&fValue, cppu::UnoType<float>::get());
+ }
+ else if(ouName == u"CharFontName" )
+ {
+ // Convert to string.
+ rAny.setValue(&ouValue, cppu::UnoType<OUString>::get());
+ }
+ else if(ouName == u"CharPosture" )
+ {
+ // Convert to FontSlant.
+ css::awt::FontSlant fontSlant = static_cast<css::awt::FontSlant>(ouValue.toInt32());
+ rAny.setValue(&fontSlant, cppu::UnoType<css::awt::FontSlant>::get());
+ }
+ else if(ouName == u"ParaTabStops" )
+ {
+
+ // Convert to the Sequence with TabStop element.
+ std::vector< css::style::TabStop > vecTabStop;
+ css::style::TabStop tabStop;
+ OUString ouSubValue;
+ sal_Int32 pos = 0, posComma = 0;
+
+ do
+ {
+ // Position.
+ pos = ouValue.indexOf("Position=", pos);
+ if(pos != -1)
+ {
+ posComma = ouValue.indexOf(',', pos + 9); // 9 = length of "Position=".
+ if(posComma != -1)
+ {
+ ouSubValue = ouValue.copy(pos + 9, posComma - pos - 9);
+ tabStop.Position = ouSubValue.toInt32();
+ pos = posComma + 1;
+
+ // TabAlign.
+ pos = ouValue.indexOf("TabAlign=", pos);
+ if(pos != -1)
+ {
+ posComma = ouValue.indexOf(',', pos + 9); // 9 = length of "TabAlign=".
+ if(posComma != -1)
+ {
+ ouSubValue = ouValue.copy(pos + 9, posComma - pos - 9);
+ tabStop.Alignment = static_cast<css::style::TabAlign>(ouSubValue.toInt32());
+ pos = posComma + 1;
+
+ // DecimalChar.
+ pos = ouValue.indexOf("DecimalChar=", pos);
+ if(pos != -1)
+ {
+ posComma = ouValue.indexOf(',', pos + 11); // 11 = length of "TabAlign=".
+ if(posComma != -1)
+ {
+ ouSubValue = ouValue.copy(pos + 11, posComma - pos - 11);
+ tabStop.DecimalChar = ouSubValue.toChar();
+ pos = posComma + 1;
+
+ // FillChar.
+ pos = ouValue.indexOf("FillChar=", pos);
+ if(pos != -1)
+ {
+ posComma = ouValue.indexOf(',', pos + 9); // 9 = length of "TabAlign=".
+ if(posComma != -1)
+ {
+ ouSubValue = ouValue.copy(pos + 9, posComma - pos - 9);
+ tabStop.DecimalChar = ouSubValue.toChar();
+ pos = posComma + 1;
+
+ // Complete TabStop element.
+ vecTabStop.push_back(tabStop);
+ }
+ else
+ break; // No match comma.
+ }
+ else
+ break; // No match FillChar.
+ }
+ else
+ break; // No match comma.
+ }
+ else
+ break; // No match DecimalChar.
+ }
+ else
+ break; // No match comma.
+ }
+ else
+ break; // No match TabAlign.
+ }
+ else
+ break; // No match comma.
+ }
+ else
+ break; // No match Position.
+ }
+ while(pos < ouValue.getLength());
+
+
+ // Dump into Sequence.
+ int iSeqLen = vecTabStop.empty() ? 1 : vecTabStop.size();
+ Sequence< css::style::TabStop > seqTabStop(iSeqLen);
+ auto pseqTabStop = seqTabStop.getArray();
+
+ if (!vecTabStop.empty())
+ {
+ // Dump every element.
+ for(int i = 0; i < iSeqLen; i ++)
+ {
+ pseqTabStop[i] = vecTabStop[i];
+ }
+ }
+ else
+ {
+ // Create default value.
+ pseqTabStop[0].Position = 0;
+ pseqTabStop[0].Alignment = css::style::TabAlign_DEFAULT;
+ pseqTabStop[0].DecimalChar = '.';
+ pseqTabStop[0].FillChar = ' ';
+ }
+
+ // Assign to Any object.
+ rAny.setValue(&seqTabStop, cppu::UnoType<Sequence< css::style::TabStop >>::get());
+ }
+ else if(ouName == u"ParaLineSpacing" )
+ {
+ // Parse value string.
+ css::style::LineSpacing lineSpacing;
+ OUString ouSubValue;
+ sal_Int32 pos = 0, posComma = 0;
+
+ pos = ouValue.indexOf("Mode=", pos);
+ if(pos != -1)
+ {
+ posComma = ouValue.indexOf(',', pos + 5); // 5 = length of "Mode=".
+ if(posComma != -1)
+ {
+ ouSubValue = ouValue.copy(pos + 5, posComma - pos - 5);
+ lineSpacing.Mode = static_cast<sal_Int16>(ouSubValue.toInt32());
+ pos = posComma + 1;
+
+ pos = ouValue.indexOf("Height=", pos);
+ if(pos != -1)
+ {
+ ouSubValue = ouValue.copy(pos + 7);
+ lineSpacing.Height = static_cast<sal_Int16>(ouSubValue.toInt32());
+ }
+ else
+ {
+ lineSpacing.Height = sal_Int16(100); // Default height.
+ }
+ }
+ else
+ {
+ lineSpacing.Height = sal_Int16(100); // Default height.
+ }
+ }
+ else
+ {
+ // Default Mode and Height.
+ lineSpacing.Mode = sal_Int16(0);
+ lineSpacing.Height = sal_Int16(100); // Default height.
+ }
+
+ // Convert to Any object.
+ rAny.setValue(&lineSpacing, cppu::UnoType<css::style::LineSpacing>::get());
+ }
+ else
+ {
+ // Do nothing.
+ sal_Int32 nDefault = 0;
+ rAny.setValue(&nDefault, cppu::UnoType<sal_Int32>::get());
+ }
+}
+
+/**
+ * Override of IUNOXWrapper.
+ *
+ * @param pXInterface the pointer of UNO interface.
+ */
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccEditableText::put_XInterface(hyper pXInterface)
+{
+ // internal IUNOXWrapper - no mutex meeded
+
+ try {
+
+ CUNOXWrapper::put_XInterface(pXInterface);
+ //special query.
+ if(pUNOInterface == nullptr)
+ return E_FAIL;
+ Reference<XAccessibleContext> pRContext = pUNOInterface->getAccessibleContext();
+ if( !pRContext.is() )
+ {
+ return E_FAIL;
+ }
+ Reference<XAccessibleEditableText> pRXI(pRContext,UNO_QUERY);
+ if( !pRXI.is() )
+ pRXEdtTxt = nullptr;
+ else
+ pRXEdtTxt = pRXI.get();
+ return S_OK;
+
+ } catch(...) { return E_FAIL; }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/winaccessibility/source/UAccCOM/AccEditableText.h b/winaccessibility/source/UAccCOM/AccEditableText.h
new file mode 100644
index 000000000..244dc626b
--- /dev/null
+++ b/winaccessibility/source/UAccCOM/AccEditableText.h
@@ -0,0 +1,118 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <sal/config.h>
+
+#include <string_view>
+
+#include "Resource.h"
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/accessibility/XAccessibleEditableText.hpp>
+#include "UNOXWrapper.h"
+
+/**
+ * CAccEditableText implements IAccessibleEditableText interface.
+ */
+class CAccEditableText :
+ public CComObjectRoot,
+ public CComCoClass<CAccEditableText,&CLSID_AccEditableText>,
+ public IAccessibleEditableText,
+ public CUNOXWrapper
+{
+public:
+ CAccEditableText()
+ {
+
+ }
+ virtual ~CAccEditableText()
+ {
+
+ }
+
+ BEGIN_COM_MAP(CAccEditableText)
+ COM_INTERFACE_ENTRY(IAccessibleEditableText)
+ COM_INTERFACE_ENTRY(IUNOXWrapper)
+ COM_INTERFACE_ENTRY_FUNC_BLIND(0,SmartQI_)
+#if defined __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Winconsistent-missing-override"
+#endif
+ END_COM_MAP()
+#if defined __clang__
+#pragma clang diagnostic pop
+#endif
+
+ static HRESULT WINAPI SmartQI_(void* pv,
+ REFIID iid, void** ppvObject, DWORD_PTR)
+ {
+ return static_cast<CAccEditableText*>(pv)->SmartQI(iid,ppvObject);
+ }
+
+ HRESULT SmartQI(REFIID iid, void** ppvObject)
+ {
+ if( m_pOuterUnknown )
+ return OuterQueryInterface(iid,ppvObject);
+ return E_FAIL;
+ }
+
+ DECLARE_NO_REGISTRY()
+
+public:
+ // IAccessibleEditableText
+
+ // Copies a range of text to the clipboard.
+ STDMETHOD(copyText)(long startOffset, long endOffset) override;
+
+ // Deletes a range of text.
+ STDMETHOD(deleteText)(long startOffset, long endOffset) override;
+
+ // Inserts text at a specified offset.
+ STDMETHOD(insertText)(long offset, BSTR * text) override;
+
+ // Cuts a range of text to the clipboard.
+ STDMETHOD(cutText)(long startOffset, long endOffset) override;
+
+ // Pastes text from clipboard at specified offset.
+ STDMETHOD(pasteText)(long offset) override;
+
+ // Replaces range of text with new text.
+ STDMETHOD(replaceText)(long startOffset, long endOffset, BSTR * text) override;
+
+
+ // Sets attributes of range of text.
+ STDMETHOD(setAttributes)(long startOffset, long endOffset, BSTR * attributes) override;
+
+ // Override of IUNOXWrapper.
+ STDMETHOD(put_XInterface)(hyper pXInterface) override;
+
+private:
+
+ css::uno::Reference<css::accessibility::XAccessibleEditableText> pRXEdtTxt;
+
+ static void get_AnyFromOLECHAR(std::u16string_view ouName, const OUString &ouValue, css::uno::Any &rAny);
+
+ css::accessibility::XAccessibleEditableText* GetXInterface()
+ {
+ return pRXEdtTxt.get();
+ }
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/winaccessibility/source/UAccCOM/AccHyperLink.cxx b/winaccessibility/source/UAccCOM/AccHyperLink.cxx
new file mode 100644
index 000000000..6857540c3
--- /dev/null
+++ b/winaccessibility/source/UAccCOM/AccHyperLink.cxx
@@ -0,0 +1,300 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "stdafx.h"
+#include "AccHyperLink.h"
+
+#if defined __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wnon-virtual-dtor"
+#endif
+#include <UAccCOM.h>
+#if defined __clang__
+#pragma clang diagnostic pop
+#endif
+
+#include <vcl/svapp.hxx>
+
+#include <com/sun/star/accessibility/XAccessible.hpp>
+#include <com/sun/star/accessibility/XAccessibleAction.hpp>
+#include "MAccessible.h"
+
+using namespace com::sun::star::accessibility;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::awt;
+
+/**
+ * Returns the number of action.
+ *
+ * @param nActions the number of action.
+ */
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccHyperLink::nActions(/*[out,retval]*/long* nActions)
+{
+
+ return CAccActionBase::nActions(nActions);
+}
+
+/**
+ * Performs specified action on the object.
+ *
+ * @param actionIndex the index of action.
+ */
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccHyperLink::doAction(/* [in] */ long actionIndex)
+{
+
+ return CAccActionBase::doAction(actionIndex);
+}
+
+/**
+ * Gets description of specified action.
+ *
+ * @param actionIndex the index of action.
+ * @param description the description string of the specified action.
+ */
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccHyperLink::get_description(long actionIndex,BSTR __RPC_FAR *description)
+{
+
+ return CAccActionBase::get_description(actionIndex, description);
+}
+
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccHyperLink::get_name( long actionIndex, BSTR __RPC_FAR *name)
+{
+
+ return CAccActionBase::get_name(actionIndex, name);
+}
+
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccHyperLink::get_localizedName( long actionIndex, BSTR __RPC_FAR *localizedName)
+{
+
+ return CAccActionBase::get_name(actionIndex, localizedName);
+}
+
+/**
+ * Returns key binding object (if any) associated with specified action
+ * key binding is string.
+ * e.g. "alt+d" (like IAccessible::get_accKeyboardShortcut).
+ *
+ * @param actionIndex the index of action.
+ * @param nMaxBinding the max number of key binding.
+ * @param keyBinding the key binding array.
+ * @param nBinding the actual number of key binding returned.
+ */
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccHyperLink::get_keyBinding(
+ /* [in] */ long actionIndex,
+ /* [in] */ long nMaxBinding,
+ /* [length_is][length_is][size_is][size_is][out] */ BSTR __RPC_FAR *__RPC_FAR *keyBinding,
+ /* [retval][out] */ long __RPC_FAR *nBinding)
+{
+
+ return CAccActionBase::get_keyBinding(actionIndex, nMaxBinding, keyBinding, nBinding);
+}
+
+/**
+ * get an object
+ * @param
+ * @return Result.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccHyperLink::get_anchor(/* [in] */ long index,
+ /* [retval][out] */ VARIANT __RPC_FAR *anchor)
+{
+ SolarMutexGuard g;
+
+ try {
+
+ // #CHECK#
+ if(anchor == nullptr)
+ {
+ return E_INVALIDARG;
+ }
+ // #CHECK XInterface#
+ if(!pRXLink.is())
+ {
+ return E_FAIL;
+ }
+ // Get Any type value via pRXLink.
+ css::uno::Any anyVal = GetXInterface()->getAccessibleActionAnchor(index);
+ // Convert Any to VARIANT.
+ CMAccessible::ConvertAnyToVariant(anyVal, anchor);
+
+ return S_OK;
+
+ } catch(...) { return E_FAIL; }
+}
+
+/**
+ * get an object
+ * @param
+ * @return Result.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccHyperLink::get_anchorTarget(/* [in] */ long index,
+ /* [retval][out] */ VARIANT __RPC_FAR *anchorTarget)
+{
+ SolarMutexGuard g;
+
+ try {
+
+ // #CHECK#
+ if(anchorTarget == nullptr)
+ {
+ return E_INVALIDARG;
+ }
+ // #CHECK XInterface#
+ if(!pRXLink.is())
+ {
+ return E_FAIL;
+ }
+ // Get Any type value via pRXLink.
+ css::uno::Any anyVal = GetXInterface()->getAccessibleActionObject(index);
+ // Convert Any to VARIANT.
+ CMAccessible::ConvertAnyToVariant(anyVal, anchorTarget);
+
+ return S_OK;
+
+ } catch(...) { return E_FAIL; }
+}
+
+
+/**
+ * Get start index.
+ * @param index Variant to get start index.
+ * @return Result.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccHyperLink::get_startIndex(/* [retval][out] */ long __RPC_FAR *index)
+{
+ SolarMutexGuard g;
+
+ try {
+
+ // #CHECK#
+ if(index == nullptr)
+ {
+ return E_INVALIDARG;
+ }
+ *index = GetXInterface()->getStartIndex();
+
+ return S_OK;
+
+ } catch(...) { return E_FAIL; }
+}
+
+/**
+ * Get start index.
+ * @param index Variant to get end index.
+ * @return Result.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccHyperLink::get_endIndex(/* [retval][out] */ long __RPC_FAR *index)
+{
+ SolarMutexGuard g;
+
+ try {
+
+ // #CHECK#
+ if(index == nullptr)
+ {
+ return E_INVALIDARG;
+ }
+ // #CHECK XInterface#
+ if(!pRXLink.is())
+ {
+ return E_FAIL;
+ }
+ *index = GetXInterface()->getEndIndex();
+
+ return S_OK;
+
+ } catch(...) { return E_FAIL; }
+}
+
+/**
+ * Judge if the hyperlink is valid.
+ * @param valid Variant to get validity.
+ * @return Result.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccHyperLink::get_valid(/* [retval][out] */ boolean __RPC_FAR *valid)
+{
+ SolarMutexGuard g;
+
+ try {
+
+ // #CHECK#
+ if(valid == nullptr)
+ {
+ return E_INVALIDARG;
+ }
+ // #CHECK XInterface#
+ if(!pRXLink.is())
+ {
+ return E_FAIL;
+ }
+ *valid = GetXInterface()->isValid();
+
+ return S_OK;
+
+ } catch(...) { return E_FAIL; }
+}
+
+/**
+ * Put UNO interface.
+ * @param pXInterface XAccessibleContext interface.
+ * @return Result.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccHyperLink::put_XInterface(hyper pXInterface)
+{
+ // internal IUNOXWrapper - no mutex meeded
+
+ try {
+
+ CAccActionBase::put_XInterface(pXInterface);
+ //special query.
+ if(pUNOInterface != nullptr)
+ {
+ Reference<XAccessibleContext> pRContext = pUNOInterface->getAccessibleContext();
+ if( !pRContext.is() )
+ {
+ return E_FAIL;
+ }
+ Reference<XAccessibleHyperlink> pRXI(pRContext,UNO_QUERY);
+ if( !pRXI.is() )
+ {
+ pRXLink = nullptr;
+ }
+ else
+ pRXLink = pRXI.get();
+ }
+ return S_OK;
+
+ } catch(...) { return E_FAIL; }
+}
+
+/**
+ * Put UNO interface.
+ * @param pXSubInterface XAccessibleHyperlink interface.
+ * @return Result.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccHyperLink::put_XSubInterface(hyper pXSubInterface)
+{
+ // internal IUNOXWrapper - no mutex meeded
+
+ pRXLink = reinterpret_cast<XAccessibleHyperlink*>(pXSubInterface);
+ pRXAct = reinterpret_cast<XAccessibleAction*>(pXSubInterface);
+
+ return S_OK;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/winaccessibility/source/UAccCOM/AccHyperLink.h b/winaccessibility/source/UAccCOM/AccHyperLink.h
new file mode 100644
index 000000000..42d65a833
--- /dev/null
+++ b/winaccessibility/source/UAccCOM/AccHyperLink.h
@@ -0,0 +1,136 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include "Resource.h" // main symbols
+
+#include <com/sun/star/accessibility/XAccessibleHyperlink.hpp>
+#include "AccActionBase.h"
+#include "UNOXWrapper.h"
+
+/**
+ * CAccHyperLink implements IAccessibleHyperlink interface.
+ */
+class ATL_NO_VTABLE CAccHyperLink :
+ public CComObjectRoot,
+ public CComCoClass<CAccHyperLink,&CLSID_AccHyperLink>,
+ public IAccessibleHyperlink,
+ public CAccActionBase
+{
+public:
+ CAccHyperLink()
+ {
+ }
+
+ BEGIN_COM_MAP(CAccHyperLink)
+ COM_INTERFACE_ENTRY(IAccessibleAction)
+ COM_INTERFACE_ENTRY(IAccessibleHyperlink)
+ COM_INTERFACE_ENTRY(IUNOXWrapper)
+#if defined __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Winconsistent-missing-override"
+#endif
+ END_COM_MAP()
+#if defined __clang__
+#pragma clang diagnostic pop
+#endif
+
+ DECLARE_NO_REGISTRY()
+
+ static HRESULT WINAPI SmartQI_(void* pv,
+ REFIID iid, void** ppvObject, DWORD_PTR)
+ {
+ return static_cast<CAccHyperLink*>(pv)->SmartQI(iid,ppvObject);
+ }
+
+ HRESULT SmartQI(REFIID iid, void** ppvObject)
+ {
+ if( m_pOuterUnknown )
+ return OuterQueryInterface(iid,ppvObject);
+ return E_FAIL;
+ }
+
+ // IAccessibleHyperlink
+public:
+ // IAccessibleAction
+
+ // Returns the number of action.
+ STDMETHOD(nActions)(/*[out,retval]*/long* nActions) override;
+
+ // Performs specified action on the object.
+ STDMETHOD(doAction)(/* [in] */ long actionIndex) override;
+
+ // get the action name
+ STDMETHOD(get_name)( long actionIndex, BSTR __RPC_FAR *name) override;
+
+ // get the localized action name
+ STDMETHOD(get_localizedName)( long actionIndex, BSTR __RPC_FAR *localizedName) override;
+
+ // Gets description of specified action.
+ STDMETHOD(get_description)(long actionIndex,BSTR __RPC_FAR *description) override;
+
+ // Returns key binding object (if any) associated with specified action
+ // key binding is string.
+ // e.g. "alt+d" (like IAccessible::get_accKeyboardShortcut).
+ STDMETHOD(get_keyBinding)(
+ /* [in] */ long actionIndex,
+ /* [in] */ long nMaxBinding,
+ /* [length_is][length_is][size_is][size_is][out] */ BSTR __RPC_FAR *__RPC_FAR *keyBinding,
+ /* [retval][out] */ long __RPC_FAR *nBinding) override;
+
+ // IAccessibleHyperlink
+
+ // get an object, e.g. BSTR or image object, that is overloaded with link behavior
+ STDMETHOD(get_anchor)(/* [in] */ long index,
+ /* [retval][out] */ VARIANT __RPC_FAR *anchor) override;
+
+ // get an object representing the target of the link, usually a BSTR of the URI
+ STDMETHOD(get_anchorTarget)(/* [in] */ long index,
+ /* [retval][out] */ VARIANT __RPC_FAR *anchorTarget) override;
+
+ // Returns the index at which the textual representation of the
+ // hyperlink (group) starts.
+ STDMETHOD(get_startIndex)(/* [retval][out] */ long __RPC_FAR *index) override;
+
+ // Returns the index at which the textual representation of the
+ // hyperlink (group) ends.
+ STDMETHOD(get_endIndex)(/* [retval][out] */ long __RPC_FAR *index) override;
+
+ // Returns whether the document referenced by this links is still valid.
+ STDMETHOD(get_valid)(/* [retval][out] */ boolean __RPC_FAR *valid) override;
+
+ // Override of IUNOXWrapper.
+ STDMETHOD(put_XInterface)(hyper pXInterface) override;
+
+ // Override of IUNOXWrapper.
+ STDMETHOD(put_XSubInterface)(hyper pXSubInterface) override;
+
+private:
+
+ css::uno::Reference<css::accessibility::XAccessibleHyperlink> pRXLink;
+
+ css::accessibility::XAccessibleHyperlink* GetXInterface()
+ {
+ return pRXLink.get();
+ }
+
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/winaccessibility/source/UAccCOM/AccHypertext.cxx b/winaccessibility/source/UAccCOM/AccHypertext.cxx
new file mode 100644
index 000000000..722f13b5c
--- /dev/null
+++ b/winaccessibility/source/UAccCOM/AccHypertext.cxx
@@ -0,0 +1,401 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "stdafx.h"
+#include "AccHypertext.h"
+#include "AccHyperLink.h"
+#include "acccommon.h"
+
+#if defined __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wnon-virtual-dtor"
+#endif
+#include <UAccCOM.h>
+#if defined __clang__
+#pragma clang diagnostic pop
+#endif
+
+#include <vcl/svapp.hxx>
+
+
+using namespace com::sun::star::accessibility;
+using namespace com::sun::star::uno;
+
+
+/**
+ * Get special selection.
+ * @param startOffset Start selection offset.
+ * @param endOffset End selection offset.
+ * @param success Variant to accept the result of if the method call is successful.
+ * @return Result.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccHypertext::addSelection(long startOffset, long endOffset)
+{
+
+ return CAccTextBase::get_addSelection(startOffset, endOffset);
+}
+
+
+/**
+ * Get special attributes.
+ * @param offset Offset.
+ * @param startOffset Variant to accept start offset.
+ * @param endOffset Variant to accept end offset.
+ * @param textAttributes Variant to accept attributes.
+ * @return Result.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccHypertext::get_attributes(long offset, long * startOffset, long * endOffset, BSTR * textAttributes)
+{
+
+ return CAccTextBase::get_attributes(offset, startOffset, endOffset, textAttributes);
+}
+
+/**
+ * Get caret position.
+ * @param offset Variant to accept caret offset.
+ * @return Result.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccHypertext::get_caretOffset(long * offset)
+{
+
+ return CAccTextBase::get_caretOffset(offset);
+}
+
+/**
+ * Get character extents.
+ * @param offset Offset.
+ * @param x Variant to accept x position.
+ * @param y Variant to accept y position.
+ * @param width Variant to accept width.
+ * @param Height Variant to accept height.
+ * @return Result.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccHypertext::get_characterExtents(long offset, IA2CoordinateType coordType, long * x, long * y, long * width, long * height)
+{
+
+ return CAccTextBase::get_characterExtents(offset, coordType, x, y, width, height);
+}
+
+/**
+ * Get selections count.
+ * @param nSelections Variant to accept selections count.
+ * @return Result.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccHypertext::get_nSelections(long * nSelections)
+{
+
+ return CAccTextBase::get_nSelections(nSelections);
+}
+
+/**
+ * Get offset of some special point.
+ * @param x X position of one point.
+ * @param x Y position of one point.
+ * @param coordType Type.
+ * @param offset Variant to accept offset.
+ * @return Result.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccHypertext::get_offsetAtPoint(long x, long y, IA2CoordinateType coordType, long * offset)
+{
+ return CAccTextBase::get_offsetAtPoint(x, y, coordType, offset);
+}
+
+/**
+ * Get selection range.
+ * @param selection selection count.
+ * @param startOffset Variant to accept the start offset of special selection.
+ * @param endOffset Variant to accept the end offset of special selection.
+ * @return Result.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccHypertext::get_selection(long selection, long * startOffset, long * endOffset)
+{
+
+ return CAccTextBase::get_selection(selection, startOffset, endOffset);
+}
+
+/**
+ * Get special text.
+ * @param startOffset Start position of special range.
+ * @param endOffset End position of special range.
+ * @param text Variant to accept the text of special range.
+ * @return Result.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccHypertext::get_text(long startOffset, long endOffset, BSTR * text)
+{
+
+ return CAccTextBase::get_text(startOffset, endOffset, text);
+}
+
+/**
+ * Get special text before some position.
+ * @param offset Special position.
+ * @param boundaryType Boundary type.
+ * @param startOffset Variant to accept the start offset.
+ * @param endOffset Variant to accept the end offset.
+ * @param text Variant to accept the special text.
+ * @return Result.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccHypertext::get_textBeforeOffset(long offset, IA2TextBoundaryType boundaryType, long * startOffset, long * endOffset, BSTR * text)
+{
+
+ return CAccTextBase::get_textBeforeOffset(offset, boundaryType,
+ startOffset, endOffset, text);
+}
+
+/**
+ * Get special text after some position.
+ * @param offset Special position.
+ * @param boundaryType Boundary type.
+ * @param startOffset Variant to accept the start offset.
+ * @param endOffset Variant to accept the end offset.
+ * @param text Variant to accept the special text.
+ * @return Result.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccHypertext::get_textAfterOffset(long offset, IA2TextBoundaryType boundaryType, long * startOffset, long * endOffset, BSTR * text)
+{
+
+ return CAccTextBase::get_textAfterOffset(offset, boundaryType,
+ startOffset, endOffset, text);
+}
+
+/**
+ * Get special text at some position.
+ * @param offset Special position.
+ * @param boundaryType Boundary type.
+ * @param startOffset Variant to accept the start offset.
+ * @param endOffset Variant to accept the end offset.
+ * @param text Variant to accept the special text.
+ * @return Result.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccHypertext::get_textAtOffset(long offset, IA2TextBoundaryType boundaryType, long * startOffset, long * endOffset, BSTR * text)
+{
+
+ return CAccTextBase::get_textAtOffset(offset, boundaryType,
+ startOffset, endOffset, text);
+}
+
+/**
+ * Remove selection.
+ * @param selectionIndex Special selection index
+ * @param success Variant to accept the method called result.
+ * @return Result.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccHypertext::removeSelection(long selectionIndex)
+{
+
+ return CAccTextBase::removeSelection(selectionIndex);
+}
+
+/**
+ * Set caret position.
+ * @param offset Special position.
+ * @param success Variant to accept the method called result.
+ * @return Result.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccHypertext::setCaretOffset(long offset)
+{
+
+ return CAccTextBase::setCaretOffset(offset);
+}
+
+/**
+ * Set special selection.
+ * @param selectionIndex Special selection index.
+ * @param startOffset start position.
+ * @param endOffset end position.
+ * @param success Variant to accept the method called result.
+ * @return Result.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccHypertext::setSelection(long selectionIndex, long startOffset, long endOffset)
+{
+
+ return CAccTextBase::setSelection(selectionIndex, startOffset,
+ endOffset);
+}
+
+/**
+ * Get characters count.
+ * @param nCharacters Variant to accept the characters count.
+ * @return Result.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccHypertext::get_nCharacters(long * nCharacters)
+{
+
+ return CAccTextBase::get_nCharacters(nCharacters);
+}
+
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccHypertext::get_newText( IA2TextSegment *newText)
+{
+ return CAccTextBase::get_newText(newText);
+}
+
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccHypertext::get_oldText( IA2TextSegment *oldText)
+{
+ return CAccTextBase::get_oldText(oldText);
+}
+
+/**
+ * Scroll to special sub-string .
+ * @param startIndex Start index of sub string.
+ * @param endIndex End index of sub string.
+ * @return Result.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccHypertext::scrollSubstringToPoint(long startIndex, long endIndex,enum IA2CoordinateType coordinateType, long x, long y )
+{
+
+ return CAccTextBase::scrollSubstringToPoint(startIndex, endIndex, coordinateType, x, y);
+}
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccHypertext::scrollSubstringTo(long startIndex, long endIndex,enum IA2ScrollType scrollType)
+{
+
+ return CAccTextBase::scrollSubstringTo(startIndex, endIndex,scrollType);
+}
+
+/**
+ * Get hyperlink count.
+ * @param hyperlinkCount Variant to accept hyperlink count.
+ * @return Result.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccHypertext::get_nHyperlinks(long *hyperlinkCount)
+{
+ SolarMutexGuard g;
+
+ try {
+
+ // #CHECK#
+ if(hyperlinkCount == nullptr)
+ return E_INVALIDARG;
+ // #CHECK XInterface#
+ if(!pHyperText.is())
+ {
+ return E_FAIL;
+ }
+
+ *hyperlinkCount = pHyperText->getHyperLinkCount();
+ return S_OK;
+
+ } catch(...) { return E_FAIL; }
+}
+
+/**
+ * Get special hyperlink.
+ * @param index Special hyperlink index.
+ * @param hyperlink Variant to accept special hyperlink via index.
+ * @return Result.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccHypertext::get_hyperlink(long index,IAccessibleHyperlink **hyperlink)
+{
+ SolarMutexGuard g;
+
+ try {
+
+ // #CHECK#
+ if(hyperlink == nullptr)
+ return E_INVALIDARG;
+ // #CHECK XInterface#
+ if(!pHyperText.is())
+ {
+ return E_FAIL;
+ }
+
+ Reference<XAccessibleHyperlink> pRLink = pHyperText->getHyperLink(index);
+ if(!pRLink.is())
+ {
+ *hyperlink = nullptr;
+ return E_FAIL;
+ }
+
+ IAccessibleHyperlink* plink = nullptr;
+ HRESULT hr = createInstance<CAccHyperLink>(IID_IAccessibleHyperlink, &plink);
+ if( SUCCEEDED(hr) )
+ {
+ IUNOXWrapper* wrapper = nullptr;
+ plink->QueryInterface(IID_IUNOXWrapper, reinterpret_cast<void**>(&wrapper));
+ if(wrapper)
+ {
+ wrapper->put_XSubInterface(reinterpret_cast<hyper>(pRLink.get()));
+ wrapper->Release();
+ }
+ *hyperlink = plink;
+ return S_OK;
+ }
+
+ return E_FAIL;
+
+ } catch(...) { return E_FAIL; }
+}
+
+/**
+ * Returns the index of the hyperlink that is associated with this character index.
+ * @param charIndex Special char index.
+ * @param hyperlinkIndex Variant to accept special hyperlink index.
+ * @return Result.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccHypertext::get_hyperlinkIndex(long charIndex, long *hyperlinkIndex)
+{
+ SolarMutexGuard g;
+
+ try {
+
+ // #CHECK#
+ if(hyperlinkIndex == nullptr)
+ return E_INVALIDARG;
+ // #CHECK XInterface#
+ if(!pHyperText.is())
+ {
+ return E_FAIL;
+ }
+
+ *hyperlinkIndex = pHyperText->getHyperLinkIndex(charIndex);
+ return S_OK;
+
+ } catch(...) { return E_FAIL; }
+}
+
+/**
+ * Put UNO interface.
+ * @param pXInterface UNO interface.
+ * @return Result.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccHypertext::put_XInterface(hyper pXInterface)
+{
+ // internal IUNOXWrapper - no mutex meeded
+
+ try {
+
+ CAccTextBase::put_XInterface(pXInterface);
+ //special query.
+ if(pUNOInterface == nullptr)
+ return E_FAIL;
+ Reference<XAccessibleContext> pRContext = pUNOInterface->getAccessibleContext();
+ if( !pRContext.is() )
+ {
+ return E_FAIL;
+ }
+ Reference<XAccessibleHypertext> pRXI(pRContext,UNO_QUERY);
+ if( !pRXI.is() )
+ pHyperText = nullptr;
+ else
+ pHyperText = pRXI.get();
+ return S_OK;
+
+ } catch(...) { return E_FAIL; }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/winaccessibility/source/UAccCOM/AccHypertext.h b/winaccessibility/source/UAccCOM/AccHypertext.h
new file mode 100644
index 000000000..3a6dccfb1
--- /dev/null
+++ b/winaccessibility/source/UAccCOM/AccHypertext.h
@@ -0,0 +1,153 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include "Resource.h" // main symbols
+
+#include <com/sun/star/accessibility/XAccessible.hpp>
+#include <com/sun/star/accessibility/XAccessibleHypertext.hpp>
+#include "AccTextBase.h"
+
+/**
+ * CAccHypertext implements IAccessibleHypertext interface.
+ */
+class ATL_NO_VTABLE CAccHypertext :
+ public CComObjectRoot,
+ public CComCoClass<CAccHypertext,&CLSID_AccHypertext>,
+ public IAccessibleHypertext,
+ public CAccTextBase
+{
+public:
+ CAccHypertext()
+ {
+ }
+
+ BEGIN_COM_MAP(CAccHypertext)
+ COM_INTERFACE_ENTRY(IAccessibleText)
+ COM_INTERFACE_ENTRY(IAccessibleHypertext)
+ COM_INTERFACE_ENTRY(IUNOXWrapper)
+ COM_INTERFACE_ENTRY_FUNC_BLIND(0,SmartQI_)
+#if defined __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Winconsistent-missing-override"
+#endif
+ END_COM_MAP()
+#if defined __clang__
+#pragma clang diagnostic pop
+#endif
+
+ static HRESULT WINAPI SmartQI_(void* pv,
+ REFIID iid, void** ppvObject, DWORD_PTR)
+ {
+ return static_cast<CAccHypertext*>(pv)->SmartQI(iid,ppvObject);
+ }
+
+ HRESULT SmartQI(REFIID iid, void** ppvObject)
+ {
+ if( m_pOuterUnknown )
+ return OuterQueryInterface(iid,ppvObject);
+ return E_FAIL;
+ }
+
+ DECLARE_NO_REGISTRY()
+
+public:
+ // IAccessibleText
+
+ // Adds a text selection.
+ STDMETHOD(addSelection)(long startOffset, long endOffset) override;//, unsigned char * success)
+
+ // Gets text attributes.
+ STDMETHOD(get_attributes)(long offset, long * startOffset, long * endOffset, BSTR * textAttributes) override;
+
+ // Gets caret offset.
+ STDMETHOD(get_caretOffset)(long * offset) override;
+
+ // Gets bounding rect containing the glyph(s) representing the character
+ // at the specified text offset
+ STDMETHOD(get_characterExtents)(long offset, IA2CoordinateType coordType, long * x, long * y, long * width, long * height) override;
+
+ // Gets number of active non-contiguous selections.
+ STDMETHOD(get_nSelections)(long * nSelections) override;
+
+ // Gets bounding rect for the glyph at a certain point.
+ STDMETHOD(get_offsetAtPoint)(long x, long y, IA2CoordinateType coordType, long * offset) override;
+
+ // Gets character offsets of N-th active text selection.
+ STDMETHOD(get_selection)(long selection, long * startOffset, long * endOffset) override;
+
+ // Gets a range of text by offset NOTE: returned string may be longer
+ // than endOffset-startOffset bytes if text contains multi-byte characters.
+ STDMETHOD(get_text)(long startOffset, long endOffset, BSTR * text) override;
+
+ // Gets a specified amount of text that ends before a specified offset.
+ STDMETHOD(get_textBeforeOffset)(long offset, IA2TextBoundaryType boundaryType, long * startOffset, long * endOffset, BSTR * text) override;
+
+ // Gets a specified amount of text that spans the specified offset.
+ STDMETHOD(get_textAfterOffset)(long offset, IA2TextBoundaryType boundaryType, long * startOffset, long * endOffset, BSTR * text) override;
+
+ // Gets a specified amount of text that starts after a specified offset.
+ STDMETHOD(get_textAtOffset)(long offset, IA2TextBoundaryType boundaryType, long * startOffset, long * endOffset, BSTR * text) override;
+
+ // Unselects a range of text.
+ STDMETHOD(removeSelection)(long selectionIndex) override;
+
+ // Moves text caret.
+ STDMETHOD(setCaretOffset)(long offset) override;
+
+ // Changes the bounds of an existing selection.
+ STDMETHOD(setSelection)(long selectionIndex, long startOffset, long endOffset) override;
+
+ // Gets total number of characters.
+ // NOTE: this may be different than the total number of bytes required
+ // to store the text, if the text contains multi-byte characters.
+ STDMETHOD(get_nCharacters)(long * nCharacters) override;
+
+ // Makes specific part of string visible on screen.
+ STDMETHOD(scrollSubstringTo)(long startIndex, long endIndex,enum IA2ScrollType scrollType) override;
+
+ STDMETHOD(scrollSubstringToPoint)(long startIndex, long endIndex,enum IA2CoordinateType coordinateType, long x, long y ) override;
+
+ STDMETHOD(get_newText)( IA2TextSegment *newText) override;
+
+ STDMETHOD(get_oldText)( IA2TextSegment *oldText) override;
+
+ //IAccessibleHypertext
+
+ // Gets the number of hyperlink.
+ STDMETHOD(get_nHyperlinks)(long *hyperlinkCount) override;
+
+ // Gets the hyperlink object via specified index.
+ STDMETHOD(get_hyperlink)(long index,IAccessibleHyperlink **hyperlink) override;
+
+ // Returns the index of the hyperlink that is associated with this
+ // character index.
+ STDMETHOD(get_hyperlinkIndex)(long charIndex, long *hyperlinkIndex) override;
+
+ // Override of IUNOXWrapper.
+ STDMETHOD(put_XInterface)(hyper pXInterface) override;
+
+private:
+
+ css::uno::Reference<css::accessibility::XAccessibleHypertext> pHyperText;
+
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/winaccessibility/source/UAccCOM/AccImage.cxx b/winaccessibility/source/UAccCOM/AccImage.cxx
new file mode 100644
index 000000000..666524a71
--- /dev/null
+++ b/winaccessibility/source/UAccCOM/AccImage.cxx
@@ -0,0 +1,119 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "stdafx.h"
+#include "AccImage.h"
+
+#if defined __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wnon-virtual-dtor"
+#endif
+#include <UAccCOM.h>
+#if defined __clang__
+#pragma clang diagnostic pop
+#endif
+
+#include <vcl/svapp.hxx>
+#include <o3tl/char16_t2wchar_t.hxx>
+
+#include <com/sun/star/accessibility/XAccessible.hpp>
+#include <com/sun/star/accessibility/XAccessibleContext.hpp>
+
+using namespace css::accessibility;
+using namespace css::uno;
+
+/**
+ * Get description.
+ * @param description Variant to get description.
+ * @return Result.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccImage::get_description(BSTR* description)
+{
+ SolarMutexGuard g;
+
+ try
+ {
+ // #CHECK#
+ if (description == nullptr)
+ return E_INVALIDARG;
+ if (!pRXImg.is())
+ return E_FAIL;
+
+ OUString ouStr = GetXInterface()->getAccessibleImageDescription();
+ SysFreeString(*description);
+ *description = SysAllocString(o3tl::toW(ouStr.getStr()));
+
+ return S_OK;
+ }
+ catch (...)
+ {
+ return E_FAIL;
+ }
+}
+
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccImage::get_imagePosition(
+ /* [in] */ enum IA2CoordinateType,
+ /* [out] */ long __RPC_FAR*,
+ /* [retval][out] */ long __RPC_FAR*)
+{
+ return E_NOTIMPL;
+}
+
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccImage::get_imageSize(
+ /* [out] */ long __RPC_FAR*,
+ /* [retval][out] */ long __RPC_FAR*)
+{
+ return E_NOTIMPL;
+}
+
+/**
+ * Put UNO interface.
+ * @param pXInterface UNO interface.
+ * @return Result.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccImage::put_XInterface(hyper pXInterface)
+{
+ // internal IUNOXWrapper - no mutex meeded
+
+ try
+ {
+ CUNOXWrapper::put_XInterface(pXInterface);
+ //special query.
+ if (pUNOInterface == nullptr)
+ return E_FAIL;
+
+ Reference<XAccessibleContext> pRContext = pUNOInterface->getAccessibleContext();
+ if (!pRContext.is())
+ {
+ return E_FAIL;
+ }
+ Reference<XAccessibleImage> pRXI(pRContext, UNO_QUERY);
+ if (!pRXI.is())
+ pRXImg = nullptr;
+ else
+ pRXImg = pRXI.get();
+ return S_OK;
+ }
+ catch (...)
+ {
+ return E_FAIL;
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/winaccessibility/source/UAccCOM/AccImage.h b/winaccessibility/source/UAccCOM/AccImage.h
new file mode 100644
index 000000000..4e0708a18
--- /dev/null
+++ b/winaccessibility/source/UAccCOM/AccImage.h
@@ -0,0 +1,99 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include "Resource.h" // main symbols
+
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/accessibility/XAccessibleImage.hpp>
+#include "UNOXWrapper.h"
+
+/**
+ * CAccImage implements IAccessibleImage interface.
+ */
+class ATL_NO_VTABLE CAccImage :
+ public CComObjectRoot,
+ public CComCoClass<CAccImage,&CLSID_AccImage>,
+ public IAccessibleImage,
+ public CUNOXWrapper
+{
+public:
+ CAccImage()
+ {
+ }
+ virtual ~CAccImage()
+ {
+ }
+ BEGIN_COM_MAP(CAccImage)
+ COM_INTERFACE_ENTRY(IAccessibleImage)
+ COM_INTERFACE_ENTRY(IUNOXWrapper)
+ COM_INTERFACE_ENTRY_FUNC_BLIND(0,SmartQI_)
+#if defined __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Winconsistent-missing-override"
+#endif
+ END_COM_MAP()
+#if defined __clang__
+#pragma clang diagnostic pop
+#endif
+
+ static HRESULT WINAPI SmartQI_(void* pv,
+ REFIID iid, void** ppvObject, DWORD_PTR)
+ {
+ return static_cast<CAccImage*>(pv)->SmartQI(iid,ppvObject);
+ }
+
+ HRESULT SmartQI(REFIID iid, void** ppvObject)
+ {
+ if( m_pOuterUnknown )
+ return OuterQueryInterface(iid,ppvObject);
+ return E_FAIL;
+ }
+
+ DECLARE_NO_REGISTRY()
+
+public:
+ // IAccessibleImage
+
+ // Gets the description of the image.
+ STDMETHOD(get_description)(BSTR * description) override;
+
+ STDMETHOD(get_imagePosition)( enum IA2CoordinateType coordinateType,
+ long __RPC_FAR *x,
+ long __RPC_FAR *y) override;
+
+ STDMETHOD(get_imageSize)(
+ long __RPC_FAR *height,
+ long __RPC_FAR *width) override;
+
+ // Override of IUNOXWrapper.
+ STDMETHOD(put_XInterface)(hyper pXInterface) override;
+
+private:
+
+ css::uno::Reference<css::accessibility::XAccessibleImage> pRXImg;
+
+ css::accessibility::XAccessibleImage* GetXInterface()
+ {
+ return pRXImg.get();
+ }
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/winaccessibility/source/UAccCOM/AccRelation.cxx b/winaccessibility/source/UAccCOM/AccRelation.cxx
new file mode 100644
index 000000000..543a5b1ae
--- /dev/null
+++ b/winaccessibility/source/UAccCOM/AccRelation.cxx
@@ -0,0 +1,217 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "stdafx.h"
+#include "AccRelation.h"
+
+#if defined __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wnon-virtual-dtor"
+#endif
+#include <UAccCOM.h>
+#if defined __clang__
+#pragma clang diagnostic pop
+#endif
+
+#include <vcl/svapp.hxx>
+
+#include <com/sun/star/accessibility/AccessibleRelationType.hpp>
+#include <com/sun/star/accessibility/XAccessible.hpp>
+#include <com/sun/star/accessibility/XAccessibleContext.hpp>
+#include "MAccessible.h"
+
+using namespace com::sun::star::accessibility;
+using namespace com::sun::star::uno;
+
+/**
+ * Get relation type.
+ * @param relationType Variant to get relation type.
+ * @return Result.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccRelation::get_relationType(BSTR * relationType)
+{
+ SolarMutexGuard g;
+
+ try {
+
+ if (relationType == nullptr)
+ return E_INVALIDARG;
+
+ int type = relation.RelationType;
+ SysFreeString(*relationType);
+
+ *relationType = getRelationTypeBSTR(type);
+ return S_OK;
+
+ } catch(...) { return E_FAIL; }
+}
+
+// Gets what the type of localized relation is.
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccRelation::get_localizedRelationType(BSTR *)
+{
+
+
+ try {
+
+ return S_OK;
+
+ } catch(...) { return E_FAIL; }
+}
+
+/**
+ * Get targets length.
+ * @param nTargets Variant to get targets length.
+ * @return Result.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccRelation::get_nTargets(long * nTargets)
+{
+ SolarMutexGuard g;
+
+ try {
+
+ if (nTargets == nullptr)
+ return E_INVALIDARG;
+
+ Sequence< Reference< XInterface > > xTargets = relation.TargetSet;
+ *nTargets = xTargets.getLength();
+ return S_OK;
+
+ } catch(...) { return E_FAIL; }
+}
+
+/**
+ * Get special target.
+ * @param targetIndex target index.
+ * @param target Variant to get special target.
+ * @return Result.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccRelation::get_target(long targetIndex, IUnknown * * target)
+{
+ SolarMutexGuard g;
+
+ try {
+
+ if (target == nullptr)
+ return E_FAIL;
+
+ Sequence< Reference< XInterface > > xTargets = relation.TargetSet;
+ int nCount = xTargets.getLength();
+ if( targetIndex >= nCount )
+ return E_FAIL;
+
+ Reference<XAccessible> xRAcc(xTargets[targetIndex], UNO_QUERY);
+ IAccessible* pRet = nullptr;
+
+ bool isGet = CMAccessible::get_IAccessibleFromXAccessible(xRAcc.get(), &pRet);
+ if(isGet)
+ {
+ *target = /*(IAccessible2 *)*/pRet;
+ pRet->AddRef();
+ return S_OK;
+ }
+
+ return E_FAIL;
+
+ } catch(...) { return E_FAIL; }
+}
+
+/**
+ * Get special targets.
+ * @param maxTargets Special targets count.
+ * @param target Variant to get special target.
+ * @param nTargets Variant to accept actual target length.
+ * @return Result.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccRelation::get_targets(long, IUnknown * * target, long * nTargets)
+{
+ SolarMutexGuard g;
+
+ try {
+
+ // #CHECK#
+ if(target == nullptr)
+ return E_INVALIDARG;
+ if (nTargets == nullptr)
+ return E_INVALIDARG;
+
+ Sequence< Reference< XInterface > > xTargets = relation.TargetSet;
+ int nCount = xTargets.getLength();
+
+ *target = static_cast<IUnknown*>(::CoTaskMemAlloc(nCount*sizeof(IUnknown)));
+
+ // #CHECK Memory Allocation#
+ if(*target == nullptr)
+ {
+ return E_FAIL;
+ }
+
+ for(int i=0; i<nCount ; i++)
+ {
+ IUnknown* pAcc = nullptr;
+ HRESULT hr = get_target(i,&pAcc);
+ if(SUCCEEDED(hr))
+ target[i] = pAcc;
+ }
+
+ *nTargets = nCount;
+ return S_OK;
+
+ } catch(...) { return E_FAIL; }
+}
+
+/**
+ * Put UNO interface.
+ * @param pXSubInterface AccessibleRelation pointer.
+ * @return Result.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccRelation::put_XSubInterface(hyper pXSubInterface)
+{
+ // internal IUNOXWrapper - no mutex meeded
+
+ relation = *reinterpret_cast<AccessibleRelation*>(pXSubInterface);
+ return S_OK;
+}
+
+/**
+ * Get relation type string by type.
+ * @param type Relation type.
+ * @return relation type string.
+*/
+BSTR CAccRelation::getRelationTypeBSTR(int type)
+{
+ static LPCWSTR map[] =
+ {
+ L"INVALID", // AccessibleRelationType::INVALID
+ IA2_RELATION_FLOWS_FROM, // AccessibleRelationType::CONTENT_FLOWS_FROM
+ IA2_RELATION_FLOWS_TO, // AccessibleRelationType::CONTENT_FLOWS_TO
+ IA2_RELATION_CONTROLLED_BY, // AccessibleRelationType::CONTROLLED_BY
+ IA2_RELATION_CONTROLLER_FOR, // AccessibleRelationType::CONTROLLER_FOR
+ IA2_RELATION_LABEL_FOR, // AccessibleRelationType::LABEL_FOR
+ IA2_RELATION_LABELED_BY, // AccessibleRelationType::LABELED_BY
+ IA2_RELATION_MEMBER_OF, // AccessibleRelationType::MEMBER_OF
+ IA2_RELATION_SUBWINDOW_OF, // AccessibleRelationType::SUB_WINDOW_OF
+ IA2_RELATION_NODE_CHILD_OF, // AccessibleRelationType::NODE_CHILD_OF
+ IA2_RELATION_DESCRIBED_BY // AccessibleRelationType::DESCRIBED_BY
+ };
+
+ return ::SysAllocString( (type >= AccessibleRelationType::INVALID && type <= AccessibleRelationType::DESCRIBED_BY)
+ ? map[type] : L"");
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/winaccessibility/source/UAccCOM/AccRelation.h b/winaccessibility/source/UAccCOM/AccRelation.h
new file mode 100644
index 000000000..df258f709
--- /dev/null
+++ b/winaccessibility/source/UAccCOM/AccRelation.h
@@ -0,0 +1,91 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include "Resource.h" // main symbols
+
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/accessibility/XAccessibleRelationSet.hpp>
+#include "UNOXWrapper.h"
+
+/**
+ * CAccRelation implements IAccessibleRelation interface.
+ */
+class ATL_NO_VTABLE CAccRelation :
+ public CComObjectRoot,
+ public CComCoClass<CAccRelation, &CLSID_AccRelation>,
+ public IAccessibleRelation,
+ public CUNOXWrapper
+{
+public:
+ CAccRelation()
+ {
+ }
+ virtual ~CAccRelation()
+ {
+ }
+
+ DECLARE_NO_REGISTRY()
+
+ DECLARE_PROTECT_FINAL_CONSTRUCT()
+
+ BEGIN_COM_MAP(CAccRelation)
+ COM_INTERFACE_ENTRY(IAccessibleRelation)
+ COM_INTERFACE_ENTRY(IUNOXWrapper)
+#if defined __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Winconsistent-missing-override"
+#endif
+ END_COM_MAP()
+#if defined __clang__
+#pragma clang diagnostic pop
+#endif
+
+ // IAccessibleRelation
+public:
+ // IAccessibleRelation
+
+ // Gets what the type of relation is.
+ STDMETHOD(get_relationType)(BSTR * relationType) override;
+
+ // Gets what the type of localized relation is.
+ STDMETHOD(get_localizedRelationType)(BSTR * relationType) override;
+
+ // Gets how many targets this relation have.
+ STDMETHOD(get_nTargets)(long * nTargets) override;
+
+ // Gets one accessible relation target.
+ STDMETHOD(get_target)(long targetIndex, IUnknown * * target) override;
+
+ // Gets multiple accessible relation targets.
+ STDMETHOD(get_targets)(long maxTargets, IUnknown * * target, long * nTargets) override;
+
+ // Override of IUNOXWrapper.
+ STDMETHOD(put_XSubInterface)(hyper pXSubInterface) override;
+
+ //static OLECHAR* getRelationTypeOLECHAR(int type);
+ static BSTR getRelationTypeBSTR(int type);
+
+private:
+
+ css::accessibility::AccessibleRelation relation;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/winaccessibility/source/UAccCOM/AccTable.cxx b/winaccessibility/source/UAccCOM/AccTable.cxx
new file mode 100644
index 000000000..63f9edf7e
--- /dev/null
+++ b/winaccessibility/source/UAccCOM/AccTable.cxx
@@ -0,0 +1,1095 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+/**
+ * AccTable.cpp : Implementation of CAccTable.
+ */
+#include "stdafx.h"
+#include "AccTable.h"
+
+#if defined __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wnon-virtual-dtor"
+#endif
+#include <UAccCOM.h>
+#if defined __clang__
+#pragma clang diagnostic pop
+#endif
+
+#include <vcl/svapp.hxx>
+#include <o3tl/char16_t2wchar_t.hxx>
+
+#include <com/sun/star/accessibility/XAccessible.hpp>
+#include "MAccessible.h"
+
+#include <com/sun/star/accessibility/XAccessibleTableSelection.hpp>
+
+using namespace com::sun::star::accessibility;
+using namespace com::sun::star::uno;
+/**
+ * Gets accessible table cell.
+ *
+ * @param row the row of the specified cell.
+ * @param column the column of the specified cell.
+ * @param accessible the accessible object of the cell.
+ */
+
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTable::get_accessibleAt(long row, long column, IUnknown * * accessible)
+{
+ SolarMutexGuard g;
+
+ try {
+
+ // #CHECK#
+ if(accessible == nullptr)
+ return E_INVALIDARG;
+ // #CHECK XInterface#
+ if(!pRXTable.is())
+ return E_FAIL;
+
+ Reference<XAccessible> pRAcc = pRXTable->getAccessibleCellAt(row, column);
+
+ if(!pRAcc.is())
+ {
+ *accessible = nullptr;
+ return E_FAIL;
+ }
+
+ IAccessible* pRet = nullptr;
+
+ bool isTRUE = CMAccessible::get_IAccessibleFromXAccessible(pRAcc.get(), &pRet);
+ if(isTRUE)
+ {
+ *accessible = pRet;
+ pRet->AddRef();
+ return S_OK;
+ }
+ else if(pRAcc.is())
+ {
+ Reference<XAccessible> pxTable(pRXTable, UNO_QUERY);
+
+ CMAccessible::g_pAgent->InsertAccObj(pRAcc.get(),pxTable.get());
+ isTRUE = CMAccessible::get_IAccessibleFromXAccessible(pRAcc.get(), &pRet);
+
+ if(isTRUE)
+ {
+ *accessible = pRet;
+ pRet->AddRef();
+ return S_OK;
+ }
+ }
+ return E_FAIL;
+
+ } catch(...) { return E_FAIL; }
+}
+
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTable::get_cellAt(long row, long column, IUnknown * * cell)
+{
+ return get_accessibleAt(row, column, cell);
+}
+
+/**
+ * Gets accessible table caption.
+ *
+ * @param accessible the accessible object of table caption.
+ */
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTable::get_caption(IUnknown * *)
+{
+ return E_NOTIMPL;
+}
+
+/**
+ * Gets accessible column description (as string).
+ *
+ * @param column the column index.
+ * @param description the description of the specified column.
+ */
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTable::get_columnDescription(long column, BSTR * description)
+{
+ SolarMutexGuard g;
+
+ try {
+
+ // #CHECK#
+ if(description == nullptr)
+ return E_INVALIDARG;
+
+ // #CHECK XInterface#
+ if(!pRXTable.is())
+ return E_FAIL;
+
+ const OUString& ouStr = pRXTable->getAccessibleColumnDescription(column);
+ // #CHECK#
+
+ SysFreeString(*description);
+ *description = SysAllocString(o3tl::toW(ouStr.getStr()));
+ if (*description==nullptr)
+ return E_FAIL;
+ return S_OK;
+
+ } catch(...) { return E_FAIL; }
+}
+
+/**
+ * Gets number of columns spanned by table cell.
+ *
+ * @param row the row of the specified cell.
+ * @param column the column of the specified cell.
+ * @param spanColumns the column span of the specified cell.
+ */
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTable::get_columnExtentAt(long row, long column, long * nColumnsSpanned)
+{
+ SolarMutexGuard g;
+
+ try {
+
+ // Check pointer.
+ if(nColumnsSpanned == nullptr)
+ return E_INVALIDARG;
+
+ if(!pRXTable.is())
+ return E_FAIL;
+
+ *nColumnsSpanned = pRXTable->getAccessibleColumnExtentAt(row, column);
+ return S_OK;
+
+ } catch(...) { return E_FAIL; }
+}
+
+/**
+ * Gets accessible column header.
+ *
+ * @param column the column index.
+ * @param accessible the accessible object of the specified column.
+ */
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTable::get_columnHeader(IAccessibleTable __RPC_FAR *__RPC_FAR *accessibleTable, long *startingRowIndex)
+{
+ SolarMutexGuard g;
+
+ try {
+
+ // #CHECK#
+ if(accessibleTable == nullptr || startingRowIndex == nullptr)
+ return E_INVALIDARG;
+
+ // #CHECK XInterface#
+ if(!pRXTable.is())
+ return E_FAIL;
+
+ Reference<XAccessibleTable> pRColumnHeaderTable = pRXTable->getAccessibleColumnHeaders();
+ if(!pRColumnHeaderTable.is())
+ {
+ *accessibleTable = nullptr;
+ return E_FAIL;
+ }
+
+ Reference<XAccessible> pRXColumnHeader(pRColumnHeaderTable,UNO_QUERY);
+
+ if(!pRXColumnHeader.is())
+ {
+ *accessibleTable = nullptr;
+ return E_FAIL;
+ }
+ *startingRowIndex = 0 ;
+
+ IMAccessible* pIMacc = nullptr;
+ HRESULT hr = createInstance<CMAccessible>(IID_IMAccessible, &pIMacc);
+ if (!SUCCEEDED(hr))
+ {
+ return E_FAIL;
+ }
+ pIMacc->SetXAccessible(
+ reinterpret_cast<hyper>(pRXColumnHeader.get()));
+ pIMacc->QueryInterface(IID_IAccessibleTable,reinterpret_cast<void **>(accessibleTable));
+
+ return S_OK;
+
+ } catch(...) { return E_FAIL; }
+}
+
+/**
+ * Gets total number of columns in table.
+ *
+ * @param columnCount the number of columns in table.
+ */
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTable::get_nColumns(long * columnCount)
+{
+ SolarMutexGuard g;
+
+ try {
+
+ // #CHECK#
+ if(columnCount == nullptr)
+ return E_INVALIDARG;
+
+ // #CHECK XInterface#
+ if(!pRXTable.is())
+ return E_FAIL;
+
+ *columnCount = pRXTable->getAccessibleColumnCount();
+ return S_OK;
+
+ } catch(...) { return E_FAIL; }
+}
+
+/**
+ * Gets total number of rows in table.
+ *
+ * @param rowCount the number of rows in table.
+ */
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTable::get_nRows(long * rowCount)
+{
+ SolarMutexGuard g;
+
+ try {
+
+ // #CHECK#
+ if(rowCount == nullptr)
+ return E_INVALIDARG;
+
+ // #CHECK XInterface#
+ if(!pRXTable.is())
+ return E_FAIL;
+
+ *rowCount = pRXTable->getAccessibleRowCount();
+ return S_OK;
+
+ } catch(...) { return E_FAIL; }
+}
+
+/**
+ * Gets total number of selected columns.
+ *
+ * @param columnCount the number of selected columns.
+ */
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTable::get_nSelectedColumns(long * columnCount)
+{
+ SolarMutexGuard g;
+
+ try {
+
+ // #CHECK#
+ if(columnCount == nullptr)
+ return E_INVALIDARG;
+
+ // #CHECK XInterface#
+ if(!pRXTable.is())
+ return E_FAIL;
+
+ Sequence<long> pSelected = pRXTable->getSelectedAccessibleColumns();
+ *columnCount = pSelected.getLength();
+ return S_OK;
+
+ } catch(...) { return E_FAIL; }
+}
+
+/**
+ * Gets total number of selected rows.
+ *
+ * @param rowCount the number of selected rows.
+ */
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTable::get_nSelectedRows(long * rowCount)
+{
+ SolarMutexGuard g;
+
+ try {
+
+ // #CHECK#
+ if(rowCount == nullptr)
+ return E_INVALIDARG;
+
+ // #CHECK XInterface#
+ if(!pRXTable.is())
+ return E_FAIL;
+
+ Sequence<long> pSelected = pRXTable->getSelectedAccessibleRows();
+ *rowCount = pSelected.getLength();
+ return S_OK;
+
+ } catch(...) { return E_FAIL; }
+}
+
+/**
+ * Gets accessible row description (as string).
+ *
+ * @param row the row index.
+ * @param description the description of the specified row.
+ */
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTable::get_rowDescription(long row, BSTR * description)
+{
+ SolarMutexGuard g;
+
+ try {
+
+ // #CHECK#
+ if(description == nullptr)
+ return E_INVALIDARG;
+
+ // #CHECK XInterface#
+ if(!pRXTable.is())
+ return E_FAIL;
+
+ const OUString& ouStr = pRXTable->getAccessibleRowDescription(row);
+ // #CHECK#
+
+ SysFreeString(*description);
+ *description = SysAllocString(o3tl::toW(ouStr.getStr()));
+ if (*description==nullptr)
+ return E_FAIL;
+ return S_OK;
+
+ } catch(...) { return E_FAIL; }
+}
+
+/**
+ * Gets number of rows spanned by a table cell.
+ *
+ * @param row the row of the specified cell.
+ * @param column the column of the specified cell.
+ * @param spanRows the row span of the specified cell.
+ */
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTable::get_rowExtentAt(long row, long column, long * nRowsSpanned)
+{
+ SolarMutexGuard g;
+
+ try {
+
+ // Check pointer.
+ if(nRowsSpanned == nullptr)
+ return E_INVALIDARG;
+
+ if(!pRXTable.is())
+ return E_FAIL;
+
+ *nRowsSpanned= pRXTable->getAccessibleRowExtentAt(row, column);
+
+ return S_OK;
+
+ } catch(...) { return E_FAIL; }
+}
+
+/**
+ * Gets accessible row header.
+ *
+ * @param row the row index.
+ * @param accessible the accessible object of the row header.
+ */
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTable::get_rowHeader(IAccessibleTable __RPC_FAR *__RPC_FAR *accessibleTable, long *startingColumnIndex)
+{
+ SolarMutexGuard g;
+
+ try {
+
+ // #CHECK#
+ if(accessibleTable == nullptr || startingColumnIndex == nullptr)
+ return E_INVALIDARG;
+
+ // #CHECK XInterface#
+ if(!pRXTable.is())
+ return E_FAIL;
+
+ Reference<XAccessibleTable> pRRowHeaderTable = pRXTable->getAccessibleRowHeaders();
+ if(!pRRowHeaderTable.is())
+ {
+ *accessibleTable = nullptr;
+ return E_FAIL;
+ }
+
+ Reference<XAccessible> pRXRowHeader(pRRowHeaderTable,UNO_QUERY);
+
+ if(!pRXRowHeader.is())
+ {
+ *accessibleTable = nullptr;
+ return E_FAIL;
+ }
+ *startingColumnIndex = 0 ;
+
+ IMAccessible* pIMacc = nullptr;
+ HRESULT hr = createInstance<CMAccessible>(IID_IMAccessible, &pIMacc);
+ if (!SUCCEEDED(hr))
+ {
+ return E_FAIL;
+ }
+ pIMacc->SetXAccessible(
+ reinterpret_cast<hyper>(pRXRowHeader.get()));
+ pIMacc->QueryInterface(IID_IAccessibleTable,reinterpret_cast<void **>(accessibleTable));
+
+ return S_OK;
+
+ } catch(...) { return E_FAIL; }
+}
+
+/**
+ * Gets list of row indexes currently selected (0-based).
+ *
+ * @param accessible the accessible object array of the selected rows.
+ * @param nRows the actual size of the accessible object array.
+ */
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTable::get_selectedRows(long** rows, long* nRows)
+{
+ SolarMutexGuard g;
+
+ try {
+
+ // #CHECK#
+ if(rows == nullptr || nRows == nullptr)
+ return E_INVALIDARG;
+
+ // #CHECK XInterface#
+ if(!pRXTable.is())
+ return E_FAIL;
+
+ Sequence<long> pSelected = pRXTable->getSelectedAccessibleRows();
+ long count = pSelected.getLength() ;
+ *nRows = count;
+
+ *rows = static_cast<long*>(CoTaskMemAlloc(count * sizeof(long)));
+ // #CHECK Memory Allocation#
+ if(*rows == nullptr)
+ {
+ return E_FAIL;
+ }
+ for(int i=0; i<count; i++)
+ (*rows)[i] = pSelected[i];
+
+ return S_OK;
+
+ } catch(...) { return E_FAIL; }
+}
+
+/**
+ * Gets list of row indexes currently selected (0-based).
+ *
+ * @param maxRows This parameter is ignored.
+ * @param accessible the accessible object array of the selected rows.
+ * @param nRows the actual size of the accessible object array.
+ */
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTable::get_selectedRows(long, long ** rows, long * nRows)
+{
+ return get_selectedRows(rows, nRows);
+}
+
+/**
+ * Gets list of column indexes currently selected (0-based).
+ *
+ * @param accessible the accessible object array of the selected columns.
+ * @param numColumns the actual size of accessible object array.
+ */
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTable::get_selectedColumns(long ** columns, long * numColumns)
+{
+ SolarMutexGuard g;
+
+ try {
+
+ // #CHECK#
+ if(columns == nullptr || numColumns == nullptr)
+ return E_INVALIDARG;
+
+ // #CHECK XInterface#
+ if(!pRXTable.is())
+ return E_FAIL;
+
+ Sequence<long> pSelected = pRXTable->getSelectedAccessibleColumns();
+ long count = pSelected.getLength() ;
+ *numColumns = count;
+
+ *columns = static_cast<long*>(CoTaskMemAlloc(count * sizeof(long)));
+ // #CHECK Memory Allocation#
+ if(*columns == nullptr)
+ {
+ return E_FAIL;
+ }
+ for(int i=0; i<count; i++)
+ (*columns)[i] = pSelected[i];
+
+ return S_OK;
+
+ } catch(...) { return E_FAIL; }
+}
+
+/**
+ * Gets list of column indexes currently selected (0-based).
+ *
+ * @param maxColumns This parameter is ignored
+ * @param accessible the accessible object array of the selected columns.
+ * @param numColumns the actual size of accessible object array.
+ */
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTable::get_selectedColumns(long, long ** columns, long * numColumns)
+{
+ return get_selectedColumns(columns, numColumns);
+}
+
+/**
+ * Gets accessible table summary.
+ *
+ * @param accessible the accessible object of the summary.
+ */
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTable::get_summary(IUnknown * * accessible)
+{
+ SolarMutexGuard g;
+
+ try {
+
+ // #CHECK#
+ if(accessible == nullptr)
+ return E_INVALIDARG;
+
+ // #CHECK XInterface#
+ if(!pRXTable.is())
+ return E_FAIL;
+
+ Reference<XAccessible> pRAcc = pRXTable->getAccessibleSummary();
+
+ IAccessible* pRet = nullptr;
+ CMAccessible::get_IAccessibleFromXAccessible(pRAcc.get(), &pRet);
+
+ if(pRet)
+ {
+ *accessible = pRet;
+ pRet->AddRef();
+ return S_OK;
+ }
+
+ return E_FAIL;
+
+ } catch(...) { return E_FAIL; }
+}
+
+/**
+ * Determines if table column is selected.
+ *
+ * @param column the column index.
+ * @param isSelected the result.
+ */
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTable::get_isColumnSelected(long column, boolean * isSelected)
+{
+ SolarMutexGuard g;
+
+ try {
+
+ // #CHECK#
+ if(isSelected == nullptr)
+ return E_INVALIDARG;
+
+ // #CHECK XInterface#
+ if(!pRXTable.is())
+ return E_FAIL;
+
+ *isSelected = pRXTable->isAccessibleColumnSelected(column);
+ return S_OK;
+
+ } catch(...) { return E_FAIL; }
+}
+
+/**
+ * Determines if table row is selected.
+ *
+ * @param row the row index.
+ * @param isSelected the result.
+ */
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTable::get_isRowSelected(long row, boolean * isSelected)
+{
+ SolarMutexGuard g;
+
+ try {
+
+ // #CHECK#
+ if(isSelected == nullptr)
+ return E_INVALIDARG;
+
+ // #CHECK XInterface#
+ if(!pRXTable.is())
+ return E_FAIL;
+
+ *isSelected = pRXTable->isAccessibleRowSelected(row);
+ return S_OK;
+
+ } catch(...) { return E_FAIL; }
+}
+
+/**
+ * Determines if table cell is selected.
+ *
+ * @param row the row index.
+ * @param column the column index.
+ * @param isSelected the result.
+ */
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTable::get_isSelected(long row, long column, boolean * isSelected)
+{
+ SolarMutexGuard g;
+
+ try {
+
+ // #CHECK#
+ if(isSelected == nullptr)
+ return E_INVALIDARG;
+
+ // #CHECK XInterface#
+ if(!pRXTable.is())
+ return E_FAIL;
+
+ *isSelected = pRXTable->isAccessibleSelected(row, column);
+ return S_OK;
+
+ } catch(...) { return E_FAIL; }
+}
+
+/**
+ * Selects a row and unselect all previously selected rows.
+ *
+ * @param row the row index.
+ * @param success the result.
+ */
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTable::selectRow(long row)
+{
+ SolarMutexGuard g;
+
+ try {
+
+ // Check XAccessibleTable reference.
+ if(!pRXTable.is())
+ return E_FAIL;
+
+ Reference<XAccessibleTableSelection> pRTableExtent(pRXTable, UNO_QUERY);
+ if(pRTableExtent.is())
+ {
+ pRTableExtent->selectRow(row);
+ return S_OK;
+ }
+ else
+ {
+ // Get XAccessibleSelection.
+ Reference<XAccessibleSelection> pRSelection(pRXTable, UNO_QUERY);
+ if(!pRSelection.is())
+ return E_FAIL;
+
+ // Select row.
+ long lCol, lColumnCount;
+ lColumnCount = pRXTable->getAccessibleColumnCount();
+ for(lCol = 0; lCol < lColumnCount; lCol ++)
+ {
+ long lChildIndex = pRXTable->getAccessibleIndex(row, lCol);
+ pRSelection->selectAccessibleChild(lChildIndex);
+ }
+
+ return S_OK;
+ }
+
+ } catch(...) { return E_FAIL; }
+}
+
+/**
+ * Selects a column and unselect all previously selected columns.
+ *
+ * @param column the column index.
+ * @param success the result.
+ */
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTable::selectColumn(long column)
+{
+ SolarMutexGuard g;
+
+ try {
+
+ // Check XAccessibleTable reference.
+ if(!pRXTable.is())
+ return E_FAIL;
+
+ Reference<XAccessibleTableSelection> pRTableExtent(pRXTable, UNO_QUERY);
+ if(pRTableExtent.is())
+ {
+ pRTableExtent->selectColumn(column);
+ return S_OK;
+ }
+ else
+ {
+ // Get XAccessibleSelection.
+ Reference<XAccessibleSelection> pRSelection(pRXTable, UNO_QUERY);
+ if(!pRSelection.is())
+ return E_FAIL;
+
+ // Select column.
+ long lRow, lRowCount;
+ lRowCount = pRXTable->getAccessibleRowCount();
+ for(lRow = 0; lRow < lRowCount; lRow ++)
+ {
+ long lChildIndex = pRXTable->getAccessibleIndex(lRow, column);
+ pRSelection->selectAccessibleChild(lChildIndex);
+ }
+
+ return S_OK;
+ }
+ // End of added.
+
+ } catch(...) { return E_FAIL; }
+}
+
+/**
+ * Unselects one row, leaving other selected rows selected (if any).
+ *
+ * @param row the row index.
+ * @param success the result.
+ */
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTable::unselectRow(long row)
+{
+ SolarMutexGuard g;
+
+ try {
+
+ // Check XAccessibleTable reference.
+ if(!pRXTable.is())
+ return E_FAIL;
+
+ Reference<XAccessibleTableSelection> pRTableExtent(pRXTable, UNO_QUERY);
+ if(pRTableExtent.is())
+ {
+ if(pRTableExtent->unselectRow(row))
+ return S_OK;
+ else
+ return E_FAIL;
+ }
+ else
+ {
+ // Get XAccessibleSelection.
+ Reference<XAccessibleSelection> pRSelection(pRXTable, UNO_QUERY);
+ if(!pRSelection.is())
+ return E_FAIL;
+
+ // Select column.
+ long lColumn, lColumnCount;
+ lColumnCount = pRXTable->getAccessibleColumnCount();
+ for(lColumn = 0; lColumn < lColumnCount; lColumn ++)
+ {
+ long lChildIndex = pRXTable->getAccessibleIndex(row, lColumn);
+ pRSelection->deselectAccessibleChild(lChildIndex);
+ }
+
+ return S_OK;
+ }
+ // End of added.
+
+ } catch(...) { return E_FAIL; }
+}
+
+/**
+ * Unselects one column, leaving other selected columns selected (if any).
+ *
+ * @param column the column index.
+ * @param success the result.
+ */
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTable::unselectColumn(long column)
+{
+ SolarMutexGuard g;
+
+ try {
+
+ // Check XAccessibleTable reference.
+ if(!pRXTable.is())
+ return E_FAIL;
+
+ Reference<XAccessibleTableSelection> pRTableExtent(pRXTable, UNO_QUERY);
+ if(pRTableExtent.is())
+ {
+ if(pRTableExtent->unselectColumn(column))
+ return S_OK;
+ else
+ return E_FAIL;
+ }
+ else
+ {
+ // Get XAccessibleSelection.
+ Reference<XAccessibleSelection> pRSelection(pRXTable, UNO_QUERY);
+ if(!pRSelection.is())
+ return E_FAIL;
+
+ // Unselect columns.
+ long lRow, lRowCount;
+ lRowCount = pRXTable->getAccessibleRowCount();
+
+ for(lRow = 0; lRow < lRowCount; lRow ++)
+ {
+ long lChildIndex = pRXTable->getAccessibleIndex(lRow, column);
+ pRSelection->deselectAccessibleChild(lChildIndex);
+ }
+ return S_OK;
+ }
+
+ } catch(...) { return E_FAIL; }
+}
+
+/**
+ * Override of IUNOXWrapper.
+ *
+ * @param pXInterface the pointer of UNO interface.
+ */
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTable::put_XInterface(hyper pXInterface)
+{
+ // internal IUNOXWrapper - no mutex meeded
+
+ try {
+
+ CUNOXWrapper::put_XInterface(pXInterface);
+ //special query.
+ if(pUNOInterface == nullptr)
+ return E_INVALIDARG;
+
+ Reference<XAccessibleContext> pRContext = pUNOInterface->getAccessibleContext();
+ if( !pRContext.is() )
+ return E_FAIL;
+
+ Reference<XAccessibleTable> pRXI(pRContext,UNO_QUERY);
+ if( !pRXI.is() )
+ pRXTable = nullptr;
+ else
+ pRXTable = pRXI.get();
+ return S_OK;
+
+ } catch(...) { return E_FAIL; }
+}
+
+
+/**
+ * Gets columnIndex of childIndex.
+ *
+ * @param childIndex childIndex
+ */
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTable::get_columnIndex(long childIndex, long * columnIndex)
+{
+ SolarMutexGuard g;
+
+ try {
+
+ // #CHECK#
+ if(columnIndex == nullptr)
+ return E_INVALIDARG;
+
+ // #CHECK XInterface#
+ if(!pRXTable.is())
+ return E_FAIL;
+
+ *columnIndex = pRXTable->getAccessibleColumn(childIndex);
+ return S_OK;
+
+ } catch(...) { return E_FAIL; }
+}
+/**
+ * Gets rowIndex of childIndex.
+ *
+ * @param childIndex childIndex
+ */
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTable::get_rowIndex(long childIndex, long * rowIndex)
+{
+ SolarMutexGuard g;
+
+ try {
+
+ // #CHECK#
+ if(rowIndex == nullptr)
+ return E_INVALIDARG;
+
+ // #CHECK XInterface#
+ if(!pRXTable.is())
+ return E_FAIL;
+
+ *rowIndex = pRXTable->getAccessibleRow(childIndex);
+ return S_OK;
+
+ } catch(...) { return E_FAIL; }
+}
+
+/**
+ * Gets childIndex of childIndex.
+ *
+ * @param childIndex childIndex
+ */
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTable::get_childIndex(long RowIndex , long columnIndex, long * childIndex )
+{
+ SolarMutexGuard g;
+
+ try {
+
+ // #CHECK#
+ if(childIndex == nullptr)
+ return E_INVALIDARG;
+
+ // #CHECK XInterface#
+ if(!pRXTable.is())
+ return E_FAIL;
+
+ *childIndex = pRXTable->getAccessibleIndex(RowIndex, columnIndex);
+ return S_OK;
+
+ } catch(...) { return E_FAIL; }
+}
+
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTable::get_rowColumnExtentsAtIndex(long,
+ long *,
+ long *,
+ long *,
+ long *,
+ boolean *)
+{
+ return E_NOTIMPL;
+}
+
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTable::get_modelChange(IA2TableModelChange *)
+{
+ return E_NOTIMPL;
+}
+
+// @brief Returns the total number of selected children
+// @param [out] childCount
+// Number of children currently selected
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTable::get_nSelectedChildren(long *childCount)
+{
+ SolarMutexGuard g;
+
+ try {
+
+ // #CHECK#
+ if(childCount == nullptr)
+ return E_INVALIDARG;
+
+ // #CHECK XInterface#
+ if(!pRXTable.is())
+ return E_FAIL;
+
+ Reference<XAccessibleSelection> pRSelection(pRXTable, UNO_QUERY);
+ if(!pRSelection.is())
+ return E_FAIL;
+
+ *childCount = pRSelection->getSelectedAccessibleChildCount();
+ return S_OK;
+
+ } catch(...) { return E_FAIL; }
+}
+
+
+
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTable::get_nSelectedCells(long *cellCount)
+{
+ return get_nSelectedChildren(cellCount);
+}
+
+// @brief Returns a list of child indexes currently selected (0-based).
+// @param [in] maxChildren
+// Max children requested (possibly from IAccessibleTable::nSelectedChildren)
+// @param [out] children
+// array of indexes of selected children (each index is 0-based)
+// @param [out] nChildren
+// Length of array (not more than maxChildren)
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTable::get_selectedChildren(long, long **children, long *nChildren)
+{
+ SolarMutexGuard g;
+
+ try {
+
+ // #CHECK#
+ if(children == nullptr || nChildren == nullptr)
+ return E_INVALIDARG;
+
+ // #CHECK XInterface#
+ if(!pRXTable.is())
+ return E_FAIL;
+
+ Reference<XAccessibleSelection> pRSelection(pRXTable, UNO_QUERY);
+ if(!pRSelection.is())
+ return E_FAIL;
+
+ long childCount = pRSelection->getSelectedAccessibleChildCount() ;
+
+ *nChildren = childCount;
+
+ *children = static_cast<long*>(CoTaskMemAlloc(childCount * sizeof(long)));
+
+ for( long i = 0; i< childCount; i++)
+ {
+ Reference<XAccessible> pRAcc = pRSelection->getSelectedAccessibleChild(i);
+ if(pRAcc.is())
+ {
+ Reference<XAccessibleContext> pRContext(pRAcc, UNO_QUERY);
+ if( !pRContext.is() )
+ return E_FAIL;
+
+ long childIndex = pRContext->getAccessibleIndexInParent();
+ (*children)[i] = childIndex;
+ }
+ }
+
+ return S_OK;
+
+ } catch(...) { return E_FAIL; }
+
+}
+
+/**
+ * @brief Returns a list of accessibles currently selected.
+ * @param cells Pointer to an array of references to selected accessibles.
+ * The array is allocated by the server with CoTaskMemAlloc and
+ * freed by the client with CoTaskMemFree.
+ * @param nSelectedCells The number of accessibles returned; the size of the returned array.
+ * @return S_FALSE if there are none, [out] values are NULL and 0 respectively, otherwise S_OK
+ */
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTable::get_selectedCells(IUnknown * * * cells, long *nSelectedCells)
+{
+ SolarMutexGuard g;
+
+ try {
+
+ if (cells == nullptr || nSelectedCells == nullptr)
+ return E_INVALIDARG;
+
+ if (!pRXTable.is())
+ return E_FAIL;
+
+ Reference<XAccessibleSelection> xSelection(pRXTable, UNO_QUERY);
+ if (!xSelection.is())
+ return E_FAIL;
+
+ const long nSelected = xSelection->getSelectedAccessibleChildCount();
+ *nSelectedCells = nSelected;
+
+ *cells = static_cast<IUnknown**>(CoTaskMemAlloc(nSelected * sizeof(IUnknown*)));
+
+ for (long i = 0; i < nSelected; i++)
+ {
+ Reference<XAccessible> xAcc = xSelection->getSelectedAccessibleChild(i);
+ assert(xAcc.is());
+
+ IAccessible* pIAccessible;
+ bool bOK = CMAccessible::get_IAccessibleFromXAccessible(xAcc.get(), &pIAccessible);
+
+ if (!bOK)
+ {
+ Reference<XAccessible> xTable(pRXTable, UNO_QUERY);
+ CMAccessible::g_pAgent->InsertAccObj(xAcc.get(), xTable.get());
+ bOK = CMAccessible::get_IAccessibleFromXAccessible(xAcc.get(), &pIAccessible);
+ }
+
+ assert(bOK && "Couldn't retrieve IAccessible object");
+
+ pIAccessible->AddRef();
+ (*cells)[i] = pIAccessible;
+ }
+
+ return S_OK;
+
+ } catch(...) { return E_FAIL; }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/winaccessibility/source/UAccCOM/AccTable.h b/winaccessibility/source/UAccCOM/AccTable.h
new file mode 100644
index 000000000..d5805c3c0
--- /dev/null
+++ b/winaccessibility/source/UAccCOM/AccTable.h
@@ -0,0 +1,184 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include "Resource.h" // main symbols
+
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/accessibility/XAccessibleTable.hpp>
+#include "UNOXWrapper.h"
+
+/**
+ * CAccTable implements the IAccessibleTable and IAccessibleTable2 interfaces.
+ */
+class ATL_NO_VTABLE CAccTable :
+ public CComObjectRoot,
+ public CComCoClass<CAccTable, &CLSID_AccTable>,
+ public IAccessibleTable,
+ public IAccessibleTable2,
+ public CUNOXWrapper
+
+{
+public:
+ CAccTable()
+ {
+ }
+ virtual ~CAccTable()
+ {
+ }
+
+ BEGIN_COM_MAP(CAccTable)
+ COM_INTERFACE_ENTRY(IAccessibleTable)
+ COM_INTERFACE_ENTRY(IAccessibleTable2)
+ COM_INTERFACE_ENTRY(IUNOXWrapper)
+ COM_INTERFACE_ENTRY_FUNC_BLIND(0,SmartQI_)
+#if defined __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Winconsistent-missing-override"
+#endif
+ END_COM_MAP()
+#if defined __clang__
+#pragma clang diagnostic pop
+#endif
+
+ static HRESULT WINAPI SmartQI_(void* pv,
+ REFIID iid, void** ppvObject, DWORD_PTR)
+ {
+ return static_cast<CAccTable*>(pv)->SmartQI(iid,ppvObject);
+ }
+
+ HRESULT SmartQI(REFIID iid, void** ppvObject)
+ {
+ if( m_pOuterUnknown )
+ return OuterQueryInterface(iid,ppvObject);
+ return E_FAIL;
+ }
+
+ DECLARE_NO_REGISTRY()
+
+public:
+ // IAccessibleTable and IAccessibleTable2
+
+ // Gets accessible table cell (IAccessibleTable version).
+ STDMETHOD(get_accessibleAt)(long row, long column, IUnknown * * accessible) override;
+
+ // Gets accessible table cell (IAccessibleTable2 version).
+ STDMETHOD(get_cellAt)(long row, long column, IUnknown * * cell) override;
+
+ // Gets accessible table caption.
+ STDMETHOD(get_caption)(IUnknown * * accessible) override;
+
+ // Gets accessible column description (as string).
+ STDMETHOD(get_columnDescription)(long column, BSTR * description) override;
+
+ // Gets number of columns spanned by table cell.
+ STDMETHOD(get_columnExtentAt)(long row, long column, long * nColumnsSpanned) override;
+
+ // Gets accessible column header.
+ STDMETHOD(get_columnHeader)(IAccessibleTable __RPC_FAR *__RPC_FAR *accessibleTable, long *startingRowIndex) override;
+
+ // Gets total number of columns in table.
+ STDMETHOD(get_nColumns)(long * columnCount) override;
+
+ // Gets total number of rows in table.
+ STDMETHOD(get_nRows)(long * rowCount) override;
+
+ // Gets total number of selected columns.
+ STDMETHOD(get_nSelectedColumns)(long * columnCount) override;
+
+ // Gets total number of selected rows.
+ STDMETHOD(get_nSelectedRows)(long * rowCount) override;
+
+ // Gets accessible row description (as string).
+ STDMETHOD(get_rowDescription)(long row, BSTR * description) override;
+
+ // Gets number of rows spanned by a table cell.
+ STDMETHOD(get_rowExtentAt)(long row, long column, long * nRowsSpanned) override;
+
+ // Gets accessible row header.
+ STDMETHOD(get_rowHeader)(IAccessibleTable __RPC_FAR *__RPC_FAR *accessibleTable, long *startingColumnIndex) override;
+
+ // Gets list of row indexes currently selected (0-based).
+ STDMETHOD(get_selectedRows)(long **rows, long * nRows) override;
+ STDMETHOD(get_selectedRows)(long maxRows, long **rows, long * nRows) override;
+
+ // Gets list of column indexes currently selected (0-based).
+ STDMETHOD(get_selectedColumns)(long **columns, long * numColumns) override;
+ STDMETHOD(get_selectedColumns)(long maxColumns, long **columns, long * numColumns) override;
+
+ // Gets accessible table summary.
+ STDMETHOD(get_summary)(IUnknown * * accessible) override;
+
+ // Determines if table column is selected.
+ STDMETHOD(get_isColumnSelected)(long column, boolean * isSelected) override;
+
+ // Determines if table row is selected.
+ STDMETHOD(get_isRowSelected)(long row, boolean * isSelected) override;
+
+ // Determines if table cell is selected.
+ STDMETHOD(get_isSelected)(long row, long column, boolean * isSelected) override;
+
+ // Selects a row and unselect all previously selected rows.
+ STDMETHOD(selectRow)(long row ) override;
+
+
+ // Selects a column and unselect all previously selected columns.
+
+ STDMETHOD(selectColumn)(long column) override;
+
+ // Unselects one row, leaving other selected rows selected (if any).
+ STDMETHOD(unselectRow)(long row) override;
+
+ // Unselects one column, leaving other selected columns selected (if any).
+ STDMETHOD(unselectColumn)(long column) override;
+
+ //get Column index
+ STDMETHOD(get_columnIndex)(long childIndex, long * columnIndex) override;
+
+ STDMETHOD(get_rowIndex)(long childIndex, long * rowIndex) override;
+
+ STDMETHOD(get_childIndex)(long rowIndex,long columnIndex, long * childIndex) override;
+
+ // get total number of selected cells
+ STDMETHOD(get_nSelectedChildren)(long *childCount) override;
+ STDMETHOD(get_nSelectedCells)(long *childCount) override;
+
+ STDMETHOD(get_selectedChildren)(long maxChildren, long **children, long *nChildren) override;
+
+ // Returns a list of accessibles currently selected
+ STDMETHOD(get_selectedCells)(IUnknown * * * cells, long *nSelectedCells) override;
+
+ STDMETHOD(get_rowColumnExtentsAtIndex)( long index,
+ long *row,
+ long *column,
+ long *rowExtents,
+ long *columnExtents,
+ boolean *isSelected) override;
+
+ STDMETHOD(get_modelChange)(IA2TableModelChange *modelChange) override;
+
+ // Override of IUNOXWrapper.
+ STDMETHOD(put_XInterface)(hyper pXInterface) override;
+
+private:
+ css::uno::Reference<css::accessibility::XAccessibleTable> pRXTable;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/winaccessibility/source/UAccCOM/AccTableCell.cxx b/winaccessibility/source/UAccCOM/AccTableCell.cxx
new file mode 100644
index 000000000..90c450735
--- /dev/null
+++ b/winaccessibility/source/UAccCOM/AccTableCell.cxx
@@ -0,0 +1,186 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "AccTableCell.h"
+
+#include <vcl/svapp.hxx>
+#include <com/sun/star/accessibility/XAccessible.hpp>
+
+using namespace com::sun::star::accessibility;
+using namespace com::sun::star::uno;
+
+CAccTableCell::CAccTableCell()
+ : m_nIndexInParent(0)
+{
+}
+
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTableCell::put_XInterface(hyper pXInterface)
+{
+ // internal IUNOXWrapper - no mutex meeded
+
+ try
+ {
+ CUNOXWrapper::put_XInterface(pXInterface);
+ if (pUNOInterface == nullptr)
+ return E_INVALIDARG;
+
+ Reference<XAccessibleContext> xContext = pUNOInterface->getAccessibleContext();
+ if (!xContext.is())
+ return E_FAIL;
+
+ // retrieve reference to table (parent of the cell)
+ Reference<XAccessibleContext> xParentContext
+ = xContext->getAccessibleParent()->getAccessibleContext();
+ Reference<XAccessibleTable> xTable(xParentContext, UNO_QUERY);
+
+ if (!xTable.is())
+ {
+ m_xTable.clear();
+ return E_FAIL;
+ }
+
+ m_xTable = xTable;
+ m_nIndexInParent = xContext->getAccessibleIndexInParent();
+ return S_OK;
+ }
+ catch (...)
+ {
+ return E_FAIL;
+ }
+}
+
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTableCell::get_columnExtent(long* pColumnsSpanned)
+{
+ SolarMutexGuard g;
+
+ try
+ {
+ if (pColumnsSpanned == nullptr)
+ return E_INVALIDARG;
+
+ if (!m_xTable.is())
+ return E_FAIL;
+
+ long nRow = 0, nColumn = 0;
+ get_rowIndex(&nRow);
+ get_columnIndex(&nColumn);
+
+ *pColumnsSpanned = m_xTable->getAccessibleColumnExtentAt(nRow, nColumn);
+ return S_OK;
+ }
+ catch (...)
+ {
+ return E_FAIL;
+ }
+}
+
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTableCell::get_columnIndex(long* pColumnIndex)
+{
+ SolarMutexGuard g;
+
+ try
+ {
+ if (pColumnIndex == nullptr)
+ return E_INVALIDARG;
+
+ if (!m_xTable.is())
+ return E_FAIL;
+
+ *pColumnIndex = m_xTable->getAccessibleColumn(m_nIndexInParent);
+ return S_OK;
+ }
+ catch (...)
+ {
+ return E_FAIL;
+ }
+}
+
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTableCell::get_rowExtent(long* pRowsSpanned)
+{
+ SolarMutexGuard g;
+
+ try
+ {
+ if (pRowsSpanned == nullptr)
+ return E_INVALIDARG;
+
+ if (!m_xTable.is())
+ return E_FAIL;
+
+ long nRow = 0, nColumn = 0;
+ get_rowIndex(&nRow);
+ get_columnIndex(&nColumn);
+
+ *pRowsSpanned = m_xTable->getAccessibleRowExtentAt(nRow, nColumn);
+
+ return S_OK;
+ }
+ catch (...)
+ {
+ return E_FAIL;
+ }
+}
+
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTableCell::get_rowIndex(long* pRowIndex)
+{
+ SolarMutexGuard g;
+
+ try
+ {
+ if (pRowIndex == nullptr)
+ return E_INVALIDARG;
+
+ if (!m_xTable.is())
+ return E_FAIL;
+
+ *pRowIndex = m_xTable->getAccessibleRow(m_nIndexInParent);
+ return S_OK;
+ }
+ catch (...)
+ {
+ return E_FAIL;
+ }
+}
+
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTableCell::get_isSelected(boolean* pIsSelected)
+{
+ SolarMutexGuard g;
+
+ try
+ {
+ if (pIsSelected == nullptr)
+ return E_INVALIDARG;
+
+ if (!m_xTable.is())
+ return E_FAIL;
+
+ long nRow = 0, nColumn = 0;
+ get_rowIndex(&nRow);
+ get_columnIndex(&nColumn);
+
+ *pIsSelected = m_xTable->isAccessibleSelected(nRow, nColumn);
+ return S_OK;
+ }
+ catch (...)
+ {
+ return E_FAIL;
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/winaccessibility/source/UAccCOM/AccTableCell.h b/winaccessibility/source/UAccCOM/AccTableCell.h
new file mode 100644
index 000000000..2c7d1a79a
--- /dev/null
+++ b/winaccessibility/source/UAccCOM/AccTableCell.h
@@ -0,0 +1,87 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include "Resource.h"
+
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/accessibility/XAccessibleTable.hpp>
+#include "UNOXWrapper.h"
+
+/**
+ * CAccTableCell implements the IAccessibleTableCell interface.
+ */
+class ATL_NO_VTABLE CAccTableCell : public CComObjectRoot,
+ public CComCoClass<CAccTableCell, &CLSID_AccTableCell>,
+ public IAccessibleTableCell,
+ public CUNOXWrapper
+
+{
+public:
+ CAccTableCell();
+ virtual ~CAccTableCell() {}
+
+ BEGIN_COM_MAP(CAccTableCell)
+ COM_INTERFACE_ENTRY(IAccessibleTableCell)
+ COM_INTERFACE_ENTRY(IUNOXWrapper)
+ COM_INTERFACE_ENTRY_FUNC_BLIND(0, SmartQI_)
+#if defined __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Winconsistent-missing-override"
+#endif
+ END_COM_MAP()
+#if defined __clang__
+#pragma clang diagnostic pop
+#endif
+
+ static HRESULT WINAPI SmartQI_(void* pv, REFIID iid, void** ppvObject, DWORD_PTR)
+ {
+ return static_cast<CAccTableCell*>(pv)->SmartQI(iid, ppvObject);
+ }
+
+ HRESULT SmartQI(REFIID iid, void** ppvObject)
+ {
+ if (m_pOuterUnknown)
+ return OuterQueryInterface(iid, ppvObject);
+ return E_FAIL;
+ }
+
+ DECLARE_NO_REGISTRY()
+
+public:
+ STDMETHOD(put_XInterface)(hyper pXInterface) override;
+
+ // IAccessibleTableCell interfaces
+ STDMETHOD(get_columnExtent)(long*) override;
+ STDMETHOD(get_columnHeaderCells)(IUnknown***, long*) override { return E_FAIL; }
+ STDMETHOD(get_columnIndex)(long*) override;
+ STDMETHOD(get_rowExtent)(long*) override;
+ STDMETHOD(get_rowHeaderCells)(IUnknown***, long*) override { return E_FAIL; }
+ STDMETHOD(get_rowIndex)(long*) override;
+ STDMETHOD(get_isSelected)(boolean*) override;
+ STDMETHOD(get_rowColumnExtents)(long*, long*, long*, long*, boolean*) { return E_FAIL; }
+ STDMETHOD(get_table)(IUnknown**) { return E_FAIL; }
+
+private:
+ css::uno::Reference<css::accessibility::XAccessibleTable> m_xTable;
+ sal_Int32 m_nIndexInParent;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/winaccessibility/source/UAccCOM/AccText.cxx b/winaccessibility/source/UAccCOM/AccText.cxx
new file mode 100644
index 000000000..fc6c39285
--- /dev/null
+++ b/winaccessibility/source/UAccCOM/AccText.cxx
@@ -0,0 +1,267 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "stdafx.h"
+#include "AccText.h"
+
+#if defined __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wnon-virtual-dtor"
+#endif
+#include <UAccCOM.h>
+#if defined __clang__
+#pragma clang diagnostic pop
+#endif
+
+using namespace com::sun::star::accessibility;
+using namespace com::sun::star::uno;
+
+/**
+ * Get special selection.
+ * @param startOffset Start selection offset.
+ * @param endOffset End selection offset.
+ * @param success Variant to accept the result of if the method call is successful.
+ * @return Result.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccText::addSelection(long startOffset, long endOffset)//, unsigned char * success)
+{
+
+ return CAccTextBase::get_addSelection(startOffset, endOffset);//, success);
+}
+
+/**
+ * Get special attributes.
+ * @param offset Offset.
+ * @param startOffset Variant to accept start offset.
+ * @param endOffset Variant to accept end offset.
+ * @param textAttributes Variant to accept attributes.
+ * @return Result.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccText::get_attributes(long offset, long * startOffset, long * endOffset, BSTR * textAttributes)
+{
+
+ return CAccTextBase::get_attributes(offset, startOffset, endOffset, textAttributes);
+}
+
+/**
+ * Get caret position.
+ * @param offset Variant to accept caret offset.
+ * @return Result.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccText::get_caretOffset(long * offset)
+{
+
+ return CAccTextBase::get_caretOffset(offset);
+}
+
+/**
+ * Get character extents.
+ * @param offset Offset.
+ * @param x Variant to accept x position.
+ * @param y Variant to accept y position.
+ * @param width Variant to accept width.
+ * @param Height Variant to accept height.
+ * @return Result.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccText::get_characterExtents(long offset, IA2CoordinateType coordType, long * x, long * y, long * width, long * height)
+{
+
+ return CAccTextBase::get_characterExtents(offset, coordType, x, y, width, height);
+}
+
+/**
+ * Get selections count.
+ * @param nSelections Variant to accept selections count.
+ * @return Result.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccText::get_nSelections(long * nSelections)
+{
+
+ return CAccTextBase::get_nSelections(nSelections);
+}
+
+/**
+ * Get offset of some special point.
+ * @param x X position of one point.
+ * @param x Y position of one point.
+ * @param coordType Type.
+ * @param offset Variant to accept offset.
+ * @return Result.
+*/
+
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccText::get_offsetAtPoint(long x, long y, IA2CoordinateType coordType, long * offset)
+{
+
+ return CAccTextBase::get_offsetAtPoint(x, y, coordType, offset);
+}
+
+/**
+ * Get selection range.
+ * @param selection selection count.
+ * @param startOffset Variant to accept the start offset of special selection.
+ * @param endOffset Variant to accept the end offset of special selection.
+ * @return Result.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccText::get_selection(long selection, long * startOffset, long * endOffset)
+{
+
+ return CAccTextBase::get_selection(selection, startOffset, endOffset);
+}
+
+/**
+ * Get special text.
+ * @param startOffset Start position of special range.
+ * @param endOffset End position of special range.
+ * @param text Variant to accept the text of special range.
+ * @return Result.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccText::get_text(long startOffset, long endOffset, BSTR * text)
+{
+
+ return CAccTextBase::get_text(startOffset, endOffset, text);
+}
+
+/**
+ * Get special text before some position.
+ * @param offset Special position.
+ * @param boundaryType Boundary type.
+ * @param startOffset Variant to accept the start offset.
+ * @param endOffset Variant to accept the end offset.
+ * @param text Variant to accept the special text.
+ * @return Result.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccText::get_textBeforeOffset(long offset, IA2TextBoundaryType boundaryType, long * startOffset, long * endOffset, BSTR * text)
+{
+
+ return CAccTextBase::get_textBeforeOffset(offset, boundaryType,
+ startOffset, endOffset, text);
+}
+
+/**
+ * Get special text after some position.
+ * @param offset Special position.
+ * @param boundaryType Boundary type.
+ * @param startOffset Variant to accept the start offset.
+ * @param endOffset Variant to accept the end offset.
+ * @param text Variant to accept the special text.
+ * @return Result.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccText::get_textAfterOffset(long offset, IA2TextBoundaryType boundaryType, long * startOffset, long * endOffset, BSTR * text)
+{
+
+ return CAccTextBase::get_textAfterOffset(offset, boundaryType,
+ startOffset, endOffset, text);
+}
+
+/**
+ * Get special text at some position.
+ * @param offset Special position.
+ * @param boundaryType Boundary type.
+ * @param startOffset Variant to accept the start offset.
+ * @param endOffset Variant to accept the end offset.
+ * @param text Variant to accept the special text.
+ * @return Result.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccText::get_textAtOffset(long offset, IA2TextBoundaryType boundaryType, long * startOffset, long * endOffset, BSTR * text)
+{
+
+ return CAccTextBase::get_textAtOffset(offset, boundaryType,
+ startOffset, endOffset, text);
+}
+
+/**
+ * Remove selection.
+ * @param selectionIndex Special selection index
+ * @param success Variant to accept the method called result.
+ * @return Result.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccText::removeSelection(long selectionIndex)//, unsigned char * success)
+{
+
+ return CAccTextBase::removeSelection(selectionIndex);//, success);
+}
+
+/**
+ * Set caret position.
+ * @param offset Special position.
+ * @param success Variant to accept the method called result.
+ * @return Result.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccText::setCaretOffset(long offset)
+{
+
+ return CAccTextBase::setCaretOffset(offset);
+}
+
+/**
+ * Set special selection.
+ * @param selectionIndex Special selection index.
+ * @param startOffset start position.
+ * @param endOffset end position.
+ * @param success Variant to accept the method called result.
+ * @return Result.
+*/
+
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccText::setSelection(long selectionIndex, long startOffset, long endOffset)
+{
+
+ return CAccTextBase::setSelection(selectionIndex, startOffset,
+ endOffset);
+}
+
+/**
+ * Get characters count.
+ * @param nCharacters Variant to accept the characters count.
+ * @return Result.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccText::get_nCharacters(long * nCharacters)
+{
+
+ return CAccTextBase::get_nCharacters(nCharacters);
+}
+
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccText::get_newText( IA2TextSegment *newText)
+{
+ return CAccTextBase::get_newText(newText);
+}
+
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccText::get_oldText( IA2TextSegment *oldText)
+{
+ return CAccTextBase::get_oldText(oldText);
+}
+
+/**
+ * Scroll to special sub-string .
+ * @param startIndex Start index of sub string.
+ * @param endIndex End index of sub string.
+ * @return Result.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccText::scrollSubstringToPoint(long startIndex, long endIndex,enum IA2CoordinateType coordinateType, long x, long y )
+{
+
+ return CAccTextBase::scrollSubstringToPoint(startIndex, endIndex, coordinateType, x, y);
+}
+
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccText::scrollSubstringTo(long startIndex, long endIndex,enum IA2ScrollType scrollType)
+{
+
+ return CAccTextBase::scrollSubstringTo(startIndex, endIndex,scrollType);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/winaccessibility/source/UAccCOM/AccText.h b/winaccessibility/source/UAccCOM/AccText.h
new file mode 100644
index 000000000..eba821aae
--- /dev/null
+++ b/winaccessibility/source/UAccCOM/AccText.h
@@ -0,0 +1,129 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include "Resource.h" // main symbols
+
+#include "AccTextBase.h"
+
+/**
+ * CAccText implements IAccessibleText interface.
+ */
+class ATL_NO_VTABLE CAccText :
+ public CComObjectRoot,
+ public CComCoClass<CAccText,&CLSID_AccText>,
+ public IAccessibleText,
+ public CAccTextBase
+{
+public:
+ CAccText()
+ {
+ }
+
+ BEGIN_COM_MAP(CAccText)
+ COM_INTERFACE_ENTRY(IAccessibleText)
+ COM_INTERFACE_ENTRY(IUNOXWrapper)
+ COM_INTERFACE_ENTRY_FUNC_BLIND(0,SmartQI_)
+#if defined __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Winconsistent-missing-override"
+#endif
+ END_COM_MAP()
+#if defined __clang__
+#pragma clang diagnostic pop
+#endif
+
+ static HRESULT WINAPI SmartQI_(void* pv,
+ REFIID iid, void** ppvObject, DWORD_PTR)
+ {
+ return static_cast<CAccText*>(pv)->SmartQI(iid,ppvObject);
+ }
+
+ HRESULT SmartQI(REFIID iid, void** ppvObject)
+ {
+ if( m_pOuterUnknown )
+ return OuterQueryInterface(iid,ppvObject);
+ return E_FAIL;
+ }
+
+ DECLARE_NO_REGISTRY()
+
+public:
+ // IAccessibleText
+
+ // Adds a text selection.
+ STDMETHOD(addSelection)(long startOffset, long endOffset) override;//, unsigned char * success);
+
+ // Gets text attributes.
+ STDMETHOD(get_attributes)(long offset, long * startOffset, long * endOffset, BSTR * textAttributes) override;
+
+ // Gets caret offset.
+ STDMETHOD(get_caretOffset)(long * offset) override;
+
+ // Gets bounding rect containing the glyph(s) representing the character
+ // at the specified text offset
+ STDMETHOD(get_characterExtents)(long offset, IA2CoordinateType coordType, long * x, long * y, long * width, long * height) override;
+
+ // Gets number of active non-contiguous selections.
+ STDMETHOD(get_nSelections)(long * nSelections) override;
+
+ // Gets bounding rect for the glyph at a certain point.
+ STDMETHOD(get_offsetAtPoint)(long x, long y, IA2CoordinateType coordType, long * offset) override;
+
+ // Gets character offsets of N-th active text selection.
+ STDMETHOD(get_selection)(long selection, long * startOffset, long * endOffset) override;
+
+ // Gets a range of text by offset NOTE: returned string may be longer
+ // than endOffset-startOffset bytes if text contains multi-byte characters.
+ STDMETHOD(get_text)(long startOffset, long endOffset, BSTR * text) override;
+
+ // Gets a specified amount of text that ends before a specified offset.
+ STDMETHOD(get_textBeforeOffset)(long offset, IA2TextBoundaryType boundaryType, long * startOffset, long * endOffset, BSTR * text) override;
+
+ // Gets a specified amount of text that spans the specified offset.
+ STDMETHOD(get_textAfterOffset)(long offset, IA2TextBoundaryType boundaryType, long * startOffset, long * endOffset, BSTR * text) override;
+
+ // Gets a specified amount of text that starts after a specified offset.
+ STDMETHOD(get_textAtOffset)(long offset, IA2TextBoundaryType boundaryType, long * startOffset, long * endOffset, BSTR * text) override;
+
+ // Unselects a range of text.
+ STDMETHOD(removeSelection)(long selectionIndex) override;//, unsigned char * success);
+
+ // Moves text caret.
+ STDMETHOD(setCaretOffset)(long offset) override;//, unsigned char * success);
+
+ // Changes the bounds of an existing selection.
+ STDMETHOD(setSelection)(long selectionIndex, long startOffset, long endOffset) override;//, unsigned char * success);
+
+ // Gets total number of characters.
+ // NOTE: this may be different than the total number of bytes required
+ // to store the text, if the text contains multi-byte characters.
+ STDMETHOD(get_nCharacters)(long * nCharacters) override;
+
+ // Makes specific part of string visible on screen.
+ STDMETHOD(scrollSubstringTo)(long startIndex, long endIndex,enum IA2ScrollType scrollType) override;
+ STDMETHOD(scrollSubstringToPoint)(long startIndex, long endIndex,enum IA2CoordinateType coordinateType, long x, long y ) override;
+
+ STDMETHOD(get_newText)( IA2TextSegment *newText) override;
+
+ STDMETHOD(get_oldText)( IA2TextSegment *oldText) override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/winaccessibility/source/UAccCOM/AccTextBase.cxx b/winaccessibility/source/UAccCOM/AccTextBase.cxx
new file mode 100644
index 000000000..a1f371a47
--- /dev/null
+++ b/winaccessibility/source/UAccCOM/AccTextBase.cxx
@@ -0,0 +1,911 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+
+// AccTextBase.cpp: implementation of the CAccTextBase class.
+
+#include "stdafx.h"
+
+#include "AccTextBase.h"
+
+#include <rtl/ustrbuf.hxx>
+#include <sal/log.hxx>
+#include <vcl/svapp.hxx>
+#include <o3tl/char16_t2wchar_t.hxx>
+
+#include <com/sun/star/accessibility/AccessibleScrollType.hpp>
+#include <com/sun/star/accessibility/AccessibleTextType.hpp>
+#include <com/sun/star/accessibility/XAccessible.hpp>
+#include <com/sun/star/accessibility/XAccessibleContext.hpp>
+#include <com/sun/star/accessibility/XAccessibleComponent.hpp>
+#include <com/sun/star/accessibility/XAccessibleTextSelection.hpp>
+#include "MAccessible.h"
+
+using namespace css::accessibility;
+using namespace css::uno;
+
+namespace
+{
+sal_Int16 lcl_matchIA2TextBoundaryType(IA2TextBoundaryType boundaryType)
+{
+ switch (boundaryType)
+ {
+ case IA2_TEXT_BOUNDARY_CHAR:
+ return com::sun::star::accessibility::AccessibleTextType::CHARACTER;
+ case IA2_TEXT_BOUNDARY_WORD:
+ return com::sun::star::accessibility::AccessibleTextType::WORD;
+ case IA2_TEXT_BOUNDARY_SENTENCE:
+ return com::sun::star::accessibility::AccessibleTextType::SENTENCE;
+ case IA2_TEXT_BOUNDARY_PARAGRAPH:
+ return com::sun::star::accessibility::AccessibleTextType::PARAGRAPH;
+ case IA2_TEXT_BOUNDARY_LINE:
+ return com::sun::star::accessibility::AccessibleTextType::LINE;
+ case IA2_TEXT_BOUNDARY_ALL:
+ // assert here, better handle it directly at call site
+ assert(false
+ && "No match for IA2_TEXT_BOUNDARY_ALL, handle at call site.");
+ break;
+ default:
+ break;
+ }
+
+ SAL_WARN("iacc2", "Unmatched text boundary type: " << boundaryType);
+ return -1;
+}
+}
+
+
+// Construction/Destruction
+
+
+static OUString ReplaceFourChar(OUString const & oldOUString);
+
+CAccTextBase::CAccTextBase()
+{}
+
+CAccTextBase::~CAccTextBase()
+{}
+
+
+/**
+ * Get special selection.
+ * @param startOffset Start selection offset.
+ * @param endOffset End selection offset.
+ * @param success Variant to accept the result of if the method call is successful.
+ * @return Result.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTextBase::get_addSelection(long startOffset, long endOffset)
+{
+ SolarMutexGuard g;
+
+ try {
+
+ // #CHECK XInterface#
+ if(pUNOInterface == nullptr)
+ return E_FAIL;
+
+ Reference<XAccessibleContext> pRContext = pUNOInterface->getAccessibleContext();
+
+ Reference< XAccessibleTextSelection > pRExtension(pRContext,UNO_QUERY);
+
+ if( pRExtension.is() )
+ {
+ pRExtension->addSelection(0, startOffset, endOffset);
+ return S_OK;
+ }
+ else
+ {
+ GetXInterface()->setSelection(startOffset, endOffset);
+ return S_OK;
+ }
+
+ } catch(...) { return E_FAIL; }
+}
+
+/**
+ * Get special attributes.
+ * @param offset Offset.
+ * @param startOffset Variant to accept start offset.
+ * @param endOffset Variant to accept end offset.
+ * @param textAttributes Variant to accept attributes.
+ * @return Result.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTextBase::get_attributes(long offset, long * startOffset, long * endOffset, BSTR * textAttributes)
+{
+ SolarMutexGuard g;
+
+ try {
+
+ if (startOffset == nullptr || endOffset == nullptr || textAttributes == nullptr)
+ return E_INVALIDARG;
+ // #CHECK XInterface#
+ if(!pRXText.is())
+ {
+ return E_FAIL;
+ }
+
+ if( offset < 0 || offset > GetXInterface()->getCharacterCount() )
+ return E_FAIL;
+
+ OUStringBuffer strAttrs("Version:1;");
+
+ Sequence< css::beans::PropertyValue > pValues = GetXInterface()->getCharacterAttributes(offset, Sequence< OUString >());
+ int nCount = pValues.getLength();
+
+ sal_Int16 numberingLevel = 0;
+ OUString numberingPrefix;
+ Any anyNumRule;
+ bool bHaveNumberingPrefixAttr = false;
+ bool bHaveNumberingLevel = false;
+ bool bHaveNumberingRules = false;
+ for(int i =0; i<nCount; i++)
+ {
+
+ const css::beans::PropertyValue &pValue = pValues[i];
+ if(pValue.Name == "NumberingLevel")
+ {
+ if (pValue.Value != Any())
+ pValue.Value >>= numberingLevel;
+ else
+ numberingLevel = -1;
+ bHaveNumberingLevel = true;
+ continue;
+ }
+ if(pValue.Name == "NumberingPrefix")
+ {
+ pValue.Value >>=numberingPrefix;
+ bHaveNumberingPrefixAttr = true;
+ continue;
+ }
+ if(pValue.Name == "NumberingRules")
+ {
+ bHaveNumberingRules = true;
+ anyNumRule = pValue.Value;
+ continue;
+ }
+ if (bHaveNumberingLevel && bHaveNumberingRules && bHaveNumberingPrefixAttr)
+ {
+ strAttrs.append(';');
+ numberingPrefix = ReplaceFourChar(numberingPrefix);
+ strAttrs.append(CMAccessible::get_String4Numbering(anyNumRule,numberingLevel,numberingPrefix));
+ bHaveNumberingLevel = false;
+ bHaveNumberingRules = false;
+ }
+ if( (bHaveNumberingPrefixAttr && i > 1 ) ||
+ (!bHaveNumberingPrefixAttr && i > 0 ) ) //element 0 is NumberingPrefix, not write alone
+ {
+ strAttrs.append(';');
+ }
+ strAttrs.append(pValue.Name);
+ strAttrs.append(':');
+
+ if (pValue.Name == "CharBackColor" ||
+ pValue.Name == "CharColor" ||
+ pValue.Name == "CharUnderlineColor" )
+ {
+ unsigned long nColor;
+ pValue.Value >>= nColor;
+ strAttrs.append('#');
+ OUString const hex = OUString::number(nColor, 16).toAsciiUpperCase();
+ for (sal_Int32 j = hex.getLength(); j < 8; ++j) {
+ strAttrs.append('0');
+ }
+ strAttrs.append(hex);
+ }
+ else
+ {
+ strAttrs.append(CMAccessible::get_StringFromAny(pValue.Value));
+ }
+ }
+ strAttrs.append(';');
+ // #CHECK#
+ if(*textAttributes)
+ SysFreeString(*textAttributes);
+ *textAttributes = SysAllocString(o3tl::toW(strAttrs.makeStringAndClear().getStr()));
+
+ if( offset < GetXInterface()->getCharacterCount() )
+ {
+ TextSegment textSeg = GetXInterface()->getTextAtIndex(offset, AccessibleTextType::ATTRIBUTE_RUN);
+ *startOffset = textSeg.SegmentStart;
+ *endOffset = textSeg.SegmentEnd;
+ }
+ else
+ {
+ *startOffset = offset;
+ *endOffset = offset;
+ }
+
+ return S_OK;
+
+ } catch(...) { return E_FAIL; }
+}
+
+/**
+ * Get caret position.
+ * @param offset Variant to accept caret offset.
+ * @return Result.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTextBase::get_caretOffset(long * offset)
+{
+ SolarMutexGuard g;
+
+ try {
+
+ if (offset == nullptr)
+ return E_INVALIDARG;
+ // #CHECK XInterface#
+ if(!pRXText.is())
+ {
+ *offset = 0;
+ return S_OK;
+ }
+
+ *offset = GetXInterface()->getCaretPosition();
+ return S_OK;
+
+ } catch(...) { return E_FAIL; }
+}
+
+/**
+ * Get character count.
+ * @param nCharacters Variant to accept character count.
+ * @return Result.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTextBase::get_characterCount(long * nCharacters)
+{
+ SolarMutexGuard g;
+
+ try {
+
+ if (nCharacters == nullptr)
+ return E_INVALIDARG;
+ // #CHECK XInterface#
+ if(!pRXText.is())
+ {
+ *nCharacters = 0;
+ return S_OK;
+ }
+
+ *nCharacters = GetXInterface()->getCharacterCount();
+ return S_OK;
+
+ } catch(...) { return E_FAIL; }
+}
+
+/**
+ * Get character extents.
+ * @param offset Offset.
+ * @param x Variant to accept x position.
+ * @param y Variant to accept y position.
+ * @param width Variant to accept width.
+ * @param Height Variant to accept height.
+ * @return Result.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTextBase::get_characterExtents(long offset, IA2CoordinateType coordType, long * x, long * y, long * width, long * height)
+{
+ SolarMutexGuard g;
+
+ try {
+
+ if (x == nullptr || height == nullptr || y == nullptr || width == nullptr)
+ return E_INVALIDARG;
+ // #CHECK XInterface#
+ if(!pRXText.is())
+ return E_FAIL;
+
+ if(offset < 0 || offset > GetXInterface()->getCharacterCount() )
+ return E_FAIL;
+
+ css::awt::Rectangle rectangle;
+ rectangle = GetXInterface()->getCharacterBounds(offset);
+
+ //IA2Point aPoint;
+ css::awt::Point aPoint;
+
+ Reference<XAccessibleContext> pRContext = pUNOInterface->getAccessibleContext();
+ if( !pRContext.is() )
+ {
+ return E_FAIL;
+ }
+ Reference<XAccessibleComponent> pRComp(pRContext,UNO_QUERY);
+ if( pRComp.is() )
+ {
+ if(coordType == IA2_COORDTYPE_SCREEN_RELATIVE)
+ {
+ css::awt::Point pt = pRComp->getLocationOnScreen();
+ aPoint.X = pt.X;
+ aPoint.Y = pt.Y;
+ }
+ else if(coordType == IA2_COORDTYPE_PARENT_RELATIVE)
+ {
+ css::awt::Point pt = pRComp->getLocation();
+ aPoint.X = pt.X;
+ aPoint.Y = pt.Y;
+ }
+ }
+ rectangle.X = rectangle.X + aPoint.X;
+ rectangle.Y = rectangle.Y + aPoint.Y;
+
+ *x = rectangle.X;
+ *y = rectangle.Y;
+
+ // GetXInterface()->getCharacterBounds() have different implement in different acc component
+ // But we need return the width/height == 1 for every component when offset == text length.
+ // So we ignore the return result of GetXInterface()->getCharacterBounds() when offset == text length.
+ if( offset == GetXInterface()->getCharacterCount() )
+ {
+ *width = 1;
+ *height = 1;
+ }
+ else
+ {
+ *width = rectangle.Width;
+ *height = rectangle.Height;
+ }
+
+ return S_OK;
+
+ } catch(...) { return E_FAIL; }
+}
+
+/**
+ * Get selections count.
+ * @param nSelections Variant to accept selections count.
+ * @return Result.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTextBase::get_nSelections(long * nSelections)
+{
+ SolarMutexGuard g;
+
+ try {
+
+ if (nSelections == nullptr)
+ return E_INVALIDARG;
+ // #CHECK XInterface#
+ if(pUNOInterface == nullptr)
+ {
+ *nSelections = 0;
+ return S_OK;
+ }
+
+ Reference<XAccessibleContext> pRContext = pUNOInterface->getAccessibleContext();
+
+ Reference< XAccessibleTextSelection > pRExtension(pRContext,UNO_QUERY);
+
+ if( pRExtension.is() )
+ {
+ *nSelections = pRExtension->getSelectedPortionCount();
+ return S_OK;
+ }
+
+ long iLength = GetXInterface()->getSelectedText().getLength();
+ if( iLength> 0)
+ {
+ *nSelections = 1;
+ return S_OK;
+ }
+
+ *nSelections = 0;
+ return S_OK;
+
+ } catch(...) { return E_FAIL; }
+}
+
+/**
+ * Get offset of some special point.
+ * @param x X position of one point.
+ * @param x Y position of one point.
+ * @param coordType Type.
+ * @param offset Variant to accept offset.
+ * @return Result.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTextBase::get_offsetAtPoint(long x, long y, IA2CoordinateType, long * offset)
+{
+ SolarMutexGuard g;
+
+ try {
+
+ if (offset == nullptr)
+ return E_INVALIDARG;
+ // #CHECK XInterface#
+ if(!pRXText.is())
+ return E_FAIL;
+
+ css::awt::Point point;
+ point.X = x;
+ point.Y = y;
+ *offset = GetXInterface()->getIndexAtPoint(point);
+ return S_OK;
+
+ } catch(...) { return E_FAIL; }
+}
+
+/**
+ * Get selection range.
+ * @param selection selection count.
+ * @param startOffset Variant to accept the start offset of special selection.
+ * @param endOffset Variant to accept the end offset of special selection.
+ * @return Result.
+*/
+
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTextBase::get_selection(long selectionIndex, long * startOffset, long * endOffset)
+{
+ SolarMutexGuard g;
+
+ try {
+
+ if (startOffset == nullptr || endOffset == nullptr )
+ return E_INVALIDARG;
+ // #CHECK XInterface#
+ if(pUNOInterface == nullptr )
+ return E_FAIL;
+
+ long nSelection = 0;
+ get_nSelections(&nSelection);
+
+ if(selectionIndex >= nSelection || selectionIndex < 0 )
+ return E_FAIL;
+
+ Reference<XAccessibleContext> pRContext = pUNOInterface->getAccessibleContext();
+
+ Reference< XAccessibleTextSelection > pRExtension(pRContext,UNO_QUERY);
+
+ if( pRExtension.is() )
+ {
+ *startOffset = pRExtension->getSeletedPositionStart(selectionIndex);
+ *endOffset = pRExtension->getSeletedPositionEnd(selectionIndex);
+ return S_OK;
+ }
+ else if(GetXInterface()->getSelectionEnd() > -1)
+ {
+ *startOffset = GetXInterface()->getSelectionStart();
+ *endOffset = GetXInterface()->getSelectionEnd();
+ return S_OK;
+ }
+
+ *startOffset = 0;
+ *endOffset = 0;
+ return E_FAIL;
+
+ } catch(...) { return E_FAIL; }
+}
+
+/**
+ * Get special text.
+ * @param startOffset Start position of special range.
+ * @param endOffset End position of special range.
+ * @param text Variant to accept the text of special range.
+ * @return Result.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTextBase::get_text(long startOffset, long endOffset, BSTR * text)
+{
+ SolarMutexGuard g;
+
+ try {
+
+ if (text == nullptr)
+ return E_INVALIDARG;
+ // #CHECK XInterface#
+ if(!pRXText.is())
+ return E_FAIL;
+
+ if (endOffset < -1 || endOffset < startOffset )
+ {
+ return E_FAIL;
+ }
+
+ OUString ouStr;
+ if (endOffset == -1 )
+ {
+ long nLen=0;
+ if(SUCCEEDED(get_characterCount(&nLen)))
+ {
+ ouStr = GetXInterface()->getTextRange( 0, nLen );
+ }
+ }
+ else
+ {
+ ouStr = GetXInterface()->getTextRange( startOffset, endOffset );
+ }
+
+ SysFreeString(*text);
+ *text = SysAllocString(o3tl::toW(ouStr.getStr()));
+ return S_OK;
+
+ } catch(...) { return E_FAIL; }
+}
+
+/**
+ * Get special text before some position.
+ * @param offset Special position.
+ * @param boundaryType Boundary type.
+ * @param startOffset Variant to accept the start offset.
+ * @param endOffset Variant to accept the end offset.
+ * @param text Variant to accept the special text.
+ * @return Result.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTextBase::get_textBeforeOffset(long offset, IA2TextBoundaryType boundaryType, long * startOffset, long * endOffset, BSTR * text)
+{
+ SolarMutexGuard g;
+
+ try {
+
+ // #CHECK#
+ if (startOffset == nullptr || endOffset == nullptr || text == nullptr)
+ return E_INVALIDARG;
+ // #CHECK XInterface#
+ if(!pRXText.is())
+ return E_FAIL;
+
+ if (boundaryType == IA2_TEXT_BOUNDARY_ALL)
+ {
+ long nChar;
+ get_nCharacters( &nChar );
+ *startOffset = 0;
+ *endOffset = nChar;
+ return get_text(0, nChar, text);
+ }
+
+ const sal_Int16 nUnoBoundaryType = lcl_matchIA2TextBoundaryType(boundaryType);
+ if (nUnoBoundaryType < 0)
+ return E_FAIL;
+
+ TextSegment segment = GetXInterface()->getTextBeforeIndex(offset, nUnoBoundaryType);
+ OUString ouStr = segment.SegmentText;
+ SysFreeString(*text);
+ *text = SysAllocString(o3tl::toW(ouStr.getStr()));
+ *startOffset = segment.SegmentStart;
+ *endOffset = segment.SegmentEnd;
+
+ return S_OK;
+
+ } catch(...) { return E_FAIL; }
+}
+
+/**
+ * Get special text after some position.
+ * @param offset Special position.
+ * @param boundaryType Boundary type.
+ * @param startOffset Variant to accept the start offset.
+ * @param endOffset Variant to accept the end offset.
+ * @param text Variant to accept the special text.
+ * @return Result.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTextBase::get_textAfterOffset(long offset, IA2TextBoundaryType boundaryType, long * startOffset, long * endOffset, BSTR * text)
+{
+ SolarMutexGuard g;
+
+ try {
+
+ if (startOffset == nullptr || endOffset == nullptr || text == nullptr)
+ return E_INVALIDARG;
+ // #CHECK XInterface#
+ if(!pRXText.is())
+ return E_FAIL;
+
+ if (boundaryType == IA2_TEXT_BOUNDARY_ALL)
+ {
+ long nChar;
+ get_nCharacters( &nChar );
+ *startOffset = 0;
+ *endOffset = nChar;
+ return get_text(0, nChar, text);
+ }
+
+ const sal_Int16 nUnoBoundaryType = lcl_matchIA2TextBoundaryType(boundaryType);
+ if (nUnoBoundaryType < 0)
+ return E_FAIL;
+
+ TextSegment segment = GetXInterface()->getTextBehindIndex(offset, nUnoBoundaryType);
+ OUString ouStr = segment.SegmentText;
+ SysFreeString(*text);
+ *text = SysAllocString(o3tl::toW(ouStr.getStr()));
+ *startOffset = segment.SegmentStart;
+ *endOffset = segment.SegmentEnd;
+
+ return S_OK;
+
+ } catch(...) { return E_FAIL; }
+}
+
+/**
+ * Get special text at some position.
+ * @param offset Special position.
+ * @param boundaryType Boundary type.
+ * @param startOffset Variant to accept the start offset.
+ * @param endOffset Variant to accept the end offset.
+ * @param text Variant to accept the special text.
+ * @return Result.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTextBase::get_textAtOffset(long offset, IA2TextBoundaryType boundaryType, long * startOffset, long * endOffset, BSTR * text)
+{
+ SolarMutexGuard g;
+
+ try {
+
+ if (startOffset == nullptr || text == nullptr ||endOffset == nullptr)
+ return E_INVALIDARG;
+ // #CHECK XInterface#
+ if(!pRXText.is())
+ return E_FAIL;
+
+ if (boundaryType == IA2_TEXT_BOUNDARY_ALL)
+ {
+ long nChar;
+ get_nCharacters( &nChar );
+ *startOffset = 0;
+ *endOffset = nChar;
+ return get_text(0, nChar, text);
+ }
+
+ const sal_Int16 nUnoBoundaryType = lcl_matchIA2TextBoundaryType(boundaryType);
+ if (nUnoBoundaryType < 0)
+ return E_FAIL;
+
+ TextSegment segment = GetXInterface()->getTextAtIndex(offset, nUnoBoundaryType);
+ OUString ouStr = segment.SegmentText;
+ SysFreeString(*text);
+ *text = SysAllocString(o3tl::toW(ouStr.getStr()));
+ *startOffset = segment.SegmentStart;
+ *endOffset = segment.SegmentEnd;
+
+ return S_OK;
+
+ } catch(...) { return E_FAIL; }
+}
+
+/**
+ * Remove selection.
+ * @param selectionIndex Special selection index
+ * @param success Variant to accept the method called result.
+ * @return Result.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTextBase::removeSelection(long selectionIndex)
+{
+ SolarMutexGuard g;
+
+ try {
+
+ // #CHECK XInterface#
+ if(pUNOInterface == nullptr)
+ {
+ return E_FAIL;
+ }
+
+ Reference<XAccessibleContext> pRContext = pUNOInterface->getAccessibleContext();
+
+ Reference< XAccessibleTextSelection > pRExtension(pRContext,UNO_QUERY);
+
+ if( pRExtension.is() )
+ {
+ pRExtension->removeSelection(selectionIndex);
+ return S_OK;
+ }
+ else
+ {
+ GetXInterface()->setSelection(0, 0);
+ return S_OK;
+ }
+
+ } catch(...) { return E_FAIL; }
+}
+
+/**
+ * Set caret position.
+ * @param offset Special position.
+ * @param success Variant to accept the method called result.
+ * @return Result.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTextBase::setCaretOffset(long offset)
+{
+ SolarMutexGuard g;
+
+ try {
+
+ // #CHECK XInterface#
+ if(!pRXText.is())
+ return E_FAIL;
+
+ GetXInterface()->setCaretPosition( offset);
+
+ return S_OK;
+
+ } catch(...) { return E_FAIL; }
+}
+
+/**
+ * Set special selection.
+ * @param selectionIndex Special selection index.
+ * @param startOffset start position.
+ * @param endOffset end position.
+ * @param success Variant to accept the method called result.
+ * @return Result.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTextBase::setSelection(long, long startOffset, long endOffset)
+{
+ SolarMutexGuard g;
+
+ try {
+
+ // #CHECK XInterface#
+ if(!pRXText.is())
+ {
+ return E_FAIL;
+ }
+
+ GetXInterface()->setSelection( startOffset, endOffset );
+
+ return S_OK;
+
+ } catch(...) { return E_FAIL; }
+}
+
+/**
+ * Get characters count.
+ * @param nCharacters Variant to accept the characters count.
+ * @return Result.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTextBase::get_nCharacters(long * nCharacters)
+{
+ SolarMutexGuard g;
+
+ try {
+
+ if (nCharacters == nullptr)
+ return E_INVALIDARG;
+ // #CHECK XInterface#
+ if(!pRXText.is())
+ {
+ *nCharacters = 0;
+ return S_OK;
+ }
+
+ *nCharacters = GetXInterface()->getCharacterCount();
+
+ return S_OK;
+
+ } catch(...) { return E_FAIL; }
+}
+
+// added by qiuhd, 2006/07/03, for direver 07/11
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTextBase::get_newText( IA2TextSegment *)
+{
+ return E_NOTIMPL;
+}
+
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTextBase::get_oldText( IA2TextSegment *)
+{
+ return E_NOTIMPL;
+}
+
+/**
+ * Scroll to special sub-string .
+ * @param startIndex Start index of sub string.
+ * @param endIndex End index of sub string.
+ * @return Result.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTextBase::scrollSubstringToPoint(long, long, IA2CoordinateType, long, long )
+{
+ return E_NOTIMPL;
+}
+
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTextBase::scrollSubstringTo(long startIndex, long endIndex, IA2ScrollType type)
+{
+ SolarMutexGuard g;
+
+ try {
+
+ // #CHECK XInterface#
+ if(!pRXText.is())
+ return E_FAIL;
+
+ AccessibleScrollType lUnoType;
+
+ switch(type)
+ {
+ case IA2_SCROLL_TYPE_TOP_LEFT:
+ lUnoType = AccessibleScrollType_SCROLL_TOP_LEFT;
+ break;
+ case IA2_SCROLL_TYPE_BOTTOM_RIGHT:
+ lUnoType = AccessibleScrollType_SCROLL_BOTTOM_RIGHT;
+ break;
+ case IA2_SCROLL_TYPE_TOP_EDGE:
+ lUnoType = AccessibleScrollType_SCROLL_TOP_EDGE;
+ break;
+ case IA2_SCROLL_TYPE_BOTTOM_EDGE:
+ lUnoType = AccessibleScrollType_SCROLL_BOTTOM_EDGE;
+ break;
+ case IA2_SCROLL_TYPE_LEFT_EDGE:
+ lUnoType = AccessibleScrollType_SCROLL_LEFT_EDGE;
+ break;
+ case IA2_SCROLL_TYPE_RIGHT_EDGE:
+ lUnoType = AccessibleScrollType_SCROLL_RIGHT_EDGE;
+ break;
+ case IA2_SCROLL_TYPE_ANYWHERE:
+ lUnoType = AccessibleScrollType_SCROLL_ANYWHERE;
+ break;
+ default:
+ return E_NOTIMPL;
+ }
+
+ if( GetXInterface()->scrollSubstringTo(startIndex, endIndex, lUnoType) )
+ return S_OK;
+
+ return E_NOTIMPL;
+
+ } catch(...) { return E_FAIL; }
+}
+
+/**
+ * Put UNO interface.
+ * @param pXInterface UNO interface.
+ * @return Result.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTextBase::put_XInterface(hyper pXInterface)
+{
+ // internal IUNOXWrapper - no mutex meeded
+
+ try {
+
+ CUNOXWrapper::put_XInterface(pXInterface);
+ //special query.
+ if(pUNOInterface == nullptr)
+ return E_FAIL;
+ Reference<XAccessibleContext> pRContext = pUNOInterface->getAccessibleContext();
+ if( !pRContext.is() )
+ {
+ return E_FAIL;
+ }
+ Reference<XAccessibleText> pRXI(pRContext,UNO_QUERY);
+ if( !pRXI.is() )
+ pRXText = nullptr;
+ else
+ pRXText = pRXI;
+ return S_OK;
+
+ } catch(...) { return E_FAIL; }
+}
+
+static OUString ReplaceOneChar(OUString const & oldOUString, sal_Unicode replacedChar, std::u16string_view replaceStr)
+{
+ auto s = oldOUString;
+ int iReplace = s.lastIndexOf(replacedChar);
+ if (iReplace > -1)
+ {
+ for(;iReplace>-1;)
+ {
+ s = s.replaceAt(iReplace,1, replaceStr);
+ iReplace=s.lastIndexOf(replacedChar,iReplace);
+ }
+ }
+ return s;
+}
+
+static OUString ReplaceFourChar(OUString const & oldOUString)
+{
+ auto s = oldOUString;
+ s = ReplaceOneChar(s, '\\', u"\\\\");
+ s = ReplaceOneChar(s, ';', u"\\;");
+ s = ReplaceOneChar(s, '=', u"\\=");
+ s = ReplaceOneChar(s, ',', u"\\,");
+ s = ReplaceOneChar(s, ':', u"\\:");
+ return s;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/winaccessibility/source/UAccCOM/AccTextBase.h b/winaccessibility/source/UAccCOM/AccTextBase.h
new file mode 100644
index 000000000..66f008756
--- /dev/null
+++ b/winaccessibility/source/UAccCOM/AccTextBase.h
@@ -0,0 +1,113 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+// AccTextBase.h: interface for the CAccTextBase class.
+
+#pragma once
+
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/accessibility/XAccessibleText.hpp>
+#include "UNOXWrapper.h"
+
+class ATL_NO_VTABLE CAccTextBase : public CUNOXWrapper
+{
+public:
+ CAccTextBase();
+ virtual ~CAccTextBase();
+
+ // IAccessibleText
+public:
+ // IAccessibleText
+
+ // Adds a text selection.
+ STDMETHOD(get_addSelection)(long startOffset, long endOffset);
+
+ // Gets text attributes.
+ STDMETHOD(get_attributes)
+ (long offset, long* startOffset, long* endOffset, BSTR* textAttributes);
+
+ // Gets caret offset.
+ STDMETHOD(get_caretOffset)(long* offset);
+
+ // Gets total number of characters.
+ STDMETHOD(get_characterCount)(long* nCharacters);
+
+ // Gets bounding rect containing the glyph(s) representing the character
+ // at the specified text offset
+ STDMETHOD(get_characterExtents)
+ (long offset, IA2CoordinateType coordType, long* x, long* y, long* width, long* height);
+
+ // Gets number of active non-contiguous selections.
+ STDMETHOD(get_nSelections)(long* nSelections);
+
+ // Gets bounding rect for the glyph at a certain point.
+ STDMETHOD(get_offsetAtPoint)(long x, long y, IA2CoordinateType coordType, long* offset);
+
+ // Gets character offsets of N-th active text selection.
+ STDMETHOD(get_selection)(long selectionIndex, long* startOffset, long* endOffset);
+
+ // Gets a range of text by offset NOTE: returned string may be longer
+ // than endOffset-startOffset bytes if text contains multi-byte characters.
+ STDMETHOD(get_text)(long startOffset, long endOffset, BSTR* text);
+
+ // Gets a specified amount of text that ends before a specified offset.
+ STDMETHOD(get_textBeforeOffset)
+ (long offset, IA2TextBoundaryType boundaryType, long* startOffset, long* endOffset, BSTR* text);
+
+ // Gets a specified amount of text that spans the specified offset.
+ STDMETHOD(get_textAfterOffset)
+ (long offset, IA2TextBoundaryType boundaryType, long* startOffset, long* endOffset, BSTR* text);
+
+ // Gets a specified amount of text that starts after a specified offset.
+ STDMETHOD(get_textAtOffset)
+ (long offset, IA2TextBoundaryType boundaryType, long* startOffset, long* endOffset, BSTR* text);
+
+ // Unselects a range of text.
+ STDMETHOD(removeSelection)(long selectionIndex);
+
+ // Moves text caret.
+ STDMETHOD(setCaretOffset)(long offset);
+
+ // Changes the bounds of an existing selection.
+ STDMETHOD(setSelection)(long selectionIndex, long startOffset, long endOffset);
+
+ // Gets total number of characters.
+ // NOTE: this may be different than the total number of bytes required
+ // to store the text, if the text contains multi-byte characters.
+ STDMETHOD(get_nCharacters)(long* nCharacters);
+
+ STDMETHOD(get_newText)(IA2TextSegment* newText);
+
+ STDMETHOD(get_oldText)(IA2TextSegment* oldText);
+
+ // Makes specific part of string visible on screen.
+ STDMETHOD(scrollSubstringTo)(long startIndex, long endIndex, enum IA2ScrollType scrollType);
+ STDMETHOD(scrollSubstringToPoint)
+ (long startIndex, long endIndex, enum IA2CoordinateType coordinateType, long x, long y);
+
+ // Override of IUNOXWrapper.
+ STDMETHOD(put_XInterface)(hyper pXInterface) override;
+
+private:
+ css::uno::Reference<css::accessibility::XAccessibleText> pRXText;
+
+ css::accessibility::XAccessibleText* GetXInterface() { return pRXText.get(); }
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/winaccessibility/source/UAccCOM/AccValue.cxx b/winaccessibility/source/UAccCOM/AccValue.cxx
new file mode 100644
index 000000000..c18440e65
--- /dev/null
+++ b/winaccessibility/source/UAccCOM/AccValue.cxx
@@ -0,0 +1,245 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "stdafx.h"
+#include "AccValue.h"
+#include "MAccessible.h"
+
+#if defined __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wnon-virtual-dtor"
+#endif
+#include <UAccCOM.h>
+#if defined __clang__
+#pragma clang diagnostic pop
+#endif
+
+#include <vcl/svapp.hxx>
+
+#include <com/sun/star/accessibility/XAccessible.hpp>
+#include <com/sun/star/accessibility/XAccessibleContext.hpp>
+
+using namespace com::sun::star::accessibility;
+using namespace com::sun::star::uno;
+
+/**
+ * Get current value.
+ * @param currentValue Variant that accepts current value.
+ * @return Result.
+ */
+
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccValue::get_currentValue(VARIANT* currentValue)
+{
+ SolarMutexGuard g;
+
+ try
+ {
+ if (currentValue == nullptr)
+ return E_INVALIDARG;
+ if (!pRXVal.is())
+ return E_FAIL;
+
+ // Get Any type value from UNO.
+ css::uno::Any anyVal = GetXInterface()->getCurrentValue();
+ // Convert Any to VARIANT.
+ CMAccessible::ConvertAnyToVariant(anyVal, currentValue);
+
+ return S_OK;
+ }
+ catch (...)
+ {
+ return E_FAIL;
+ }
+}
+
+/**
+ * Set current value.
+ * @param Value New value should be set.
+ * @param success If the method is successfully called.
+ * @return Result.
+ */
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccValue::setCurrentValue(VARIANT value)
+{
+ SolarMutexGuard g;
+
+ try
+ {
+ if (!pRXVal.is())
+ return E_FAIL;
+
+ HRESULT hRet = S_OK;
+ css::uno::Any anyVal;
+
+ // Set value according to value type.
+ switch (value.vt)
+ {
+ case VT_UI1:
+ {
+ anyVal <<= sal_Unicode(value.bVal);
+ }
+ break;
+
+ case VT_BOOL:
+ {
+ css::uno::Type typeInfo(TypeClass_BOOLEAN, "bool");
+ anyVal.setValue(&value.boolVal, typeInfo);
+ }
+ break;
+
+ case VT_I2:
+ {
+ css::uno::Type typeInfo(TypeClass_SHORT, "short");
+ anyVal.setValue(&value.iVal, typeInfo);
+ }
+ break;
+
+ case VT_I4:
+ {
+ css::uno::Type typeInfo(TypeClass_LONG, "long");
+ anyVal.setValue(&value.lVal, typeInfo);
+ }
+ break;
+
+ case VT_R4:
+ {
+ css::uno::Type typeInfo(TypeClass_FLOAT, "float");
+ anyVal.setValue(&value.fltVal, typeInfo);
+ }
+ break;
+
+ case VT_R8:
+ {
+ css::uno::Type typeInfo(TypeClass_DOUBLE, "double");
+ anyVal.setValue(&value.dblVal, typeInfo);
+ }
+ break;
+
+ default:
+ {
+ // Unsupported type conversion.
+ hRet = E_FAIL;
+ }
+ break;
+ }
+
+ if (hRet == S_OK)
+ {
+ hRet = pRXVal->setCurrentValue(anyVal) ? S_OK : E_FAIL;
+ }
+
+ return hRet;
+ }
+ catch (...)
+ {
+ return E_FAIL;
+ }
+}
+
+/**
+ * Get maximum value.
+ * @param maximumValue Variant that accepts maximum value.
+ * @return Result.
+ */
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccValue::get_maximumValue(VARIANT* maximumValue)
+{
+ SolarMutexGuard g;
+
+ try
+ {
+ if (maximumValue == nullptr)
+ return E_INVALIDARG;
+ if (!pRXVal.is())
+ return E_FAIL;
+
+ // Get Any type value from UNO.
+ css::uno::Any anyVal = GetXInterface()->getMaximumValue();
+ // Convert Any to VARIANT.
+ CMAccessible::ConvertAnyToVariant(anyVal, maximumValue);
+
+ return S_OK;
+ }
+ catch (...)
+ {
+ return E_FAIL;
+ }
+}
+
+/**
+ * Get minimum value.
+ * @param minimumValue Variant that accepts minimum value.
+ * @return Result.
+ */
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccValue::get_minimumValue(VARIANT* minimumValue)
+{
+ SolarMutexGuard g;
+
+ try
+ {
+ if (minimumValue == nullptr)
+ return E_FAIL;
+ if (!pRXVal.is())
+ return E_FAIL;
+
+ // Get Any type value from UNO.
+ css::uno::Any anyVal = GetXInterface()->getMinimumValue();
+ // Convert Any to VARIANT.
+ CMAccessible::ConvertAnyToVariant(anyVal, minimumValue);
+
+ return S_OK;
+ }
+ catch (...)
+ {
+ return E_FAIL;
+ }
+}
+
+/**
+ * Put valid UNO interface into com class.
+ * @param pXInterface UNO interface.
+ * @return Result.
+ */
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccValue::put_XInterface(hyper pXInterface)
+{
+ // internal IUNOXWrapper - no mutex meeded
+
+ try
+ {
+ CUNOXWrapper::put_XInterface(pXInterface);
+ //special query.
+ if (pUNOInterface == nullptr)
+ return E_FAIL;
+ Reference<XAccessibleContext> pRContext = pUNOInterface->getAccessibleContext();
+ if (!pRContext.is())
+ {
+ return E_FAIL;
+ }
+ Reference<XAccessibleValue> pRXI(pRContext, UNO_QUERY);
+ if (!pRXI.is())
+ pRXVal = nullptr;
+ else
+ pRXVal = pRXI.get();
+ return S_OK;
+ }
+ catch (...)
+ {
+ return E_FAIL;
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/winaccessibility/source/UAccCOM/AccValue.h b/winaccessibility/source/UAccCOM/AccValue.h
new file mode 100644
index 000000000..056eeb261
--- /dev/null
+++ b/winaccessibility/source/UAccCOM/AccValue.h
@@ -0,0 +1,102 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include "Resource.h" // main symbols
+
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/accessibility/XAccessibleValue.hpp>
+#include "UNOXWrapper.h"
+
+/**
+ * CAccValue implements IAccessibleValue interface.
+ */
+class CAccValue :
+ public CComObjectRoot,
+ public CComCoClass<CAccValue,&CLSID_AccValue>,
+ public IAccessibleValue,
+ public CUNOXWrapper
+{
+public:
+ CAccValue()
+ {
+ }
+ virtual ~CAccValue()
+ {
+ }
+
+ BEGIN_COM_MAP(CAccValue)
+ COM_INTERFACE_ENTRY(IAccessibleValue)
+ COM_INTERFACE_ENTRY(IUNOXWrapper)
+ COM_INTERFACE_ENTRY_FUNC_BLIND(0,SmartQI_)
+#if defined __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Winconsistent-missing-override"
+#endif
+ END_COM_MAP()
+#if defined __clang__
+#pragma clang diagnostic pop
+#endif
+
+ static HRESULT WINAPI SmartQI_(void* pv,
+ REFIID iid, void** ppvObject, DWORD_PTR)
+ {
+ return static_cast<CAccValue*>(pv)->SmartQI(iid,ppvObject);
+ }
+
+ HRESULT SmartQI(REFIID iid, void** ppvObject)
+ {
+ if( m_pOuterUnknown )
+ return OuterQueryInterface(iid,ppvObject);
+ return E_FAIL;
+ }
+
+ DECLARE_NO_REGISTRY()
+
+public:
+ // IAccessibleValue
+
+ // Returns the value of this object as a number.
+ STDMETHOD(get_currentValue)(VARIANT *currentValue) override;
+
+ // Sets the value of this object to the given number.
+ STDMETHOD(setCurrentValue)(VARIANT value) override;
+
+ // Returns the maximal value that can be represented by this object.
+ STDMETHOD(get_maximumValue)(VARIANT *maximumValue) override;
+
+ // Returns the minimal value that can be represented by this object.
+ STDMETHOD(get_minimumValue)(VARIANT *minimumValue) override;
+
+ // Override of IUNOXWrapper.
+ STDMETHOD(put_XInterface)(hyper pXInterface) override;
+
+private:
+
+ css::uno::Reference<css::accessibility::XAccessibleValue> pRXVal;
+
+ css::accessibility::XAccessibleValue* GetXInterface()
+ {
+ return pRXVal.get();
+ }
+
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/winaccessibility/source/UAccCOM/AccessibleKeyStroke.h b/winaccessibility/source/UAccCOM/AccessibleKeyStroke.h
new file mode 100644
index 000000000..db3903cbd
--- /dev/null
+++ b/winaccessibility/source/UAccCOM/AccessibleKeyStroke.h
@@ -0,0 +1,152 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+struct ACCESSIBLE_KEYSTROKE
+{
+ short modifiers;
+ short keyCode;
+ char keyChar;
+ short keyFunc;
+};
+
+const short MODIFIER_SHIFT = 1;
+const short MODIFIER_CTRL = 2;
+const short MODIFIER_ALT = 4;
+
+const short KEYCODE_NUM0 = 256;
+const short KEYCODE_NUM1 = 257;
+const short KEYCODE_NUM2 = 258;
+const short KEYCODE_NUM3 = 259;
+const short KEYCODE_NUM4 = 260;
+const short KEYCODE_NUM5 = 261;
+const short KEYCODE_NUM6 = 262;
+const short KEYCODE_NUM7 = 263;
+const short KEYCODE_NUM8 = 264;
+const short KEYCODE_NUM9 = 265;
+const short KEYCODE_A = 512;
+const short KEYCODE_B = 513;
+const short KEYCODE_C = 514;
+const short KEYCODE_D = 515;
+const short KEYCODE_E = 516;
+const short KEYCODE_F = 517;
+const short KEYCODE_G = 518;
+const short KEYCODE_H = 519;
+const short KEYCODE_I = 520;
+const short KEYCODE_J = 521;
+const short KEYCODE_K = 522;
+const short KEYCODE_L = 523;
+const short KEYCODE_M = 524;
+const short KEYCODE_N = 525;
+const short KEYCODE_O = 526;
+const short KEYCODE_P = 527;
+const short KEYCODE_Q = 528;
+const short KEYCODE_R = 529;
+const short KEYCODE_S = 530;
+const short KEYCODE_T = 531;
+const short KEYCODE_U = 532;
+const short KEYCODE_V = 533;
+const short KEYCODE_W = 534;
+const short KEYCODE_X = 535;
+const short KEYCODE_Y = 536;
+const short KEYCODE_Z = 537;
+const short KEYCODE_F1 = 768;
+const short KEYCODE_F2 = 769;
+const short KEYCODE_F3 = 770;
+const short KEYCODE_F4 = 771;
+const short KEYCODE_F5 = 772;
+const short KEYCODE_F6 = 773;
+const short KEYCODE_F7 = 774;
+const short KEYCODE_F8 = 775;
+const short KEYCODE_F9 = 776;
+const short KEYCODE_F10 = 777;
+const short KEYCODE_F11 = 778;
+const short KEYCODE_F12 = 779;
+const short KEYCODE_F13 = 780;
+const short KEYCODE_F14 = 781;
+const short KEYCODE_F15 = 782;
+const short KEYCODE_F16 = 783;
+const short KEYCODE_F17 = 784;
+const short KEYCODE_F18 = 785;
+const short KEYCODE_F19 = 786;
+const short KEYCODE_F20 = 787;
+const short KEYCODE_F21 = 788;
+const short KEYCODE_F22 = 789;
+const short KEYCODE_F23 = 790;
+const short KEYCODE_F24 = 791;
+const short KEYCODE_F25 = 792;
+const short KEYCODE_F26 = 793;
+const short KEYCODE_DOWN = 1024;
+const short KEYCODE_UP = 1025;
+const short KEYCODE_LEFT = 1026;
+const short KEYCODE_RIGHT = 1027;
+const short KEYCODE_HOME = 1028;
+const short KEYCODE_END = 1029;
+const short KEYCODE_PAGEUP = 1030;
+const short KEYCODE_PAGEDOWN = 1031;
+const short KEYCODE_RETURN = 1280;
+const short KEYCODE_ESCAPE = 1281;
+const short KEYCODE_TAB = 1282;
+const short KEYCODE_BACKSPACE = 1283;
+const short KEYCODE_SPACE = 1284;
+const short KEYCODE_INSERT = 1285;
+const short KEYCODE_DELETE = 1286;
+const short KEYCODE_ADD = 1287;
+const short KEYCODE_SUBTRACT = 1288;
+const short KEYCODE_MULTIPLY = 1289;
+const short KEYCODE_DIVIDE = 1290;
+const short KEYCODE_POINT = 1291;
+const short KEYCODE_COMMA = 1292;
+const short KEYCODE_LESS = 1293;
+const short KEYCODE_GREATER = 1294;
+const short KEYCODE_EQUAL = 1295;
+const short KEYCODE_OPEN = 1296;
+const short KEYCODE_CUT = 1297;
+const short KEYCODE_COPY = 1298;
+const short KEYCODE_PASTE = 1299;
+const short KEYCODE_UNDO = 1300;
+const short KEYCODE_REPEAT = 1301;
+const short KEYCODE_FIND = 1302;
+const short KEYCODE_PROPERTIES = 1303;
+const short KEYCODE_FRONT = 1304;
+const short KEYCODE_CONTEXTMENU = 1305;
+const short KEYCODE_HELP = 1306;
+
+const short SHORTCUT_DONTKNOW = 0;
+const short NEW = 1;
+const short OPEN = 2;
+const short SAVE = 3;
+const short SAVEAS = 4;
+const short PRINT = 5;
+const short CLOSE = 6;
+const short QUIT = 7;
+const short CUT = 8;
+const short COPY = 9;
+const short PASTE = 10;
+const short UNDO = 11;
+const short REDO = 12;
+const short UNODELETE = 13;
+const short REPEAT = 14;
+const short FIND = 15;
+const short FINDBACKWARD = 16;
+const short PROPERTIES = 17;
+const short FRONT = 18;
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/winaccessibility/source/UAccCOM/EnumVariant.cxx b/winaccessibility/source/UAccCOM/EnumVariant.cxx
new file mode 100644
index 000000000..26cd75b25
--- /dev/null
+++ b/winaccessibility/source/UAccCOM/EnumVariant.cxx
@@ -0,0 +1,245 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "stdafx.h"
+#include "EnumVariant.h"
+#include "MAccessible.h"
+
+#if defined __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wnon-virtual-dtor"
+#endif
+#include <UAccCOM.h>
+#if defined __clang__
+#pragma clang diagnostic pop
+#endif
+
+#include <vcl/svapp.hxx>
+
+using namespace com::sun::star::uno;
+using namespace com::sun::star::accessibility;
+
+
+// CEnumVariant
+
+
+/**
+ * enumerate method,get next element
+ * @param cElements The number of elements to be returned.
+ * @param pvar An array of at least size celt in which the elements are to be returned.
+ * @param pcElementFetched Pointer to the number of elements returned in rgVar, or Null
+ * @return Result.
+ */
+HRESULT STDMETHODCALLTYPE CEnumVariant::Next(ULONG cElements,VARIANT __RPC_FAR *pvar,ULONG __RPC_FAR *pcElementFetched)
+{
+ SolarMutexGuard g;
+
+ long l1;
+ ULONG l2;
+
+ if (pvar == nullptr)
+ return E_INVALIDARG;
+
+ if (pcElementFetched != nullptr)
+ *pcElementFetched = 0;
+
+ // Retrieve the next cElements.
+ for (l1=m_lCurrent, l2=0; l1<m_pXAccessibleSelection->getSelectedAccessibleChildCount() &&
+ l2<cElements; l1++, l2++)
+ {
+ Reference< XAccessible > pRXAcc = m_pXAccessibleSelection->getSelectedAccessibleChild(l1);
+ IAccessible* pChild = nullptr;
+ bool isGet = CMAccessible::get_IAccessibleFromXAccessible(pRXAcc.get(),
+ &pChild);
+ if(isGet)
+ {
+ pvar[l2].vt = VT_DISPATCH;
+ pvar[l2].pdispVal = pChild;
+ pChild->AddRef();
+ }
+ else if(pRXAcc.is())
+ {
+ if(CMAccessible::g_pAgent)
+ CMAccessible::g_pAgent->InsertAccObj(pRXAcc.get(),pUNOInterface);
+ isGet = CMAccessible::get_IAccessibleFromXAccessible(
+ pRXAcc.get(), &pChild);
+ if(isGet)
+ {
+ pvar[l2].vt = VT_DISPATCH;
+ pvar[l2].pdispVal = pChild;
+ pChild->AddRef();
+ }
+ }
+ }
+ // Set count of elements retrieved.
+ if (pcElementFetched != nullptr)
+ *pcElementFetched = l2;
+ m_lCurrent = l1;
+
+ return (l2 < cElements) ? S_FALSE : NOERROR;
+}
+
+/**
+ * skip the elements in the given range when enumerate elements
+ * @param cElements The number of elements to skip.
+ * @return Result.
+ */
+HRESULT STDMETHODCALLTYPE CEnumVariant::Skip(ULONG cElements)
+{
+ SolarMutexGuard g;
+
+ m_lCurrent += cElements;
+ if (m_lCurrent > static_cast<long>(m_lLBound+m_pXAccessibleSelection->getSelectedAccessibleChildCount()))
+ {
+ m_lCurrent = m_lLBound+m_pXAccessibleSelection->getSelectedAccessibleChildCount();
+ return E_FAIL;
+ }
+ else
+ return NOERROR;
+}
+
+
+/**
+ * reset the enumaration position to initial value
+ * @param
+ * @return Result.
+ */
+HRESULT STDMETHODCALLTYPE CEnumVariant::Reset()
+{
+ SolarMutexGuard g;
+
+ m_lCurrent = m_lLBound;
+ return NOERROR;
+}
+
+
+/**
+ *create a new IEnumVariant object,
+ *copy current enumaration container and its state to
+ *the new object
+ *AT will use the copy object to get elements
+ * @param ppenum On return, pointer to the location of the clone enumerator
+ * @return Result.
+ */
+HRESULT STDMETHODCALLTYPE CEnumVariant::Clone(IEnumVARIANT __RPC_FAR *__RPC_FAR *ppenum)
+{
+ SolarMutexGuard g;
+
+ CEnumVariant * penum = nullptr;
+ HRESULT hr;
+ if (ppenum == nullptr)
+ return E_INVALIDARG;
+
+ *ppenum = nullptr;
+
+ hr = Create(&penum);
+ if( hr == S_OK )
+ {
+ penum->PutSelection(reinterpret_cast<hyper>(pUNOInterface));
+ *ppenum = penum;
+ }
+ else
+ {
+ if (penum)
+ penum->Release();
+ }
+ return hr;
+}
+
+/**
+ *Static public method to create a CLSID_EnumVariant com object.
+ * @param ppenum Pointer to accept com object.
+ * @return Result.
+ */
+HRESULT STDMETHODCALLTYPE CEnumVariant::Create(CEnumVariant __RPC_FAR *__RPC_FAR *ppenum)
+{
+ SolarMutexGuard g;
+
+ HRESULT hr = createInstance<CEnumVariant>(IID_IEnumVariant, ppenum);
+ if (S_OK != hr)
+ {
+ return E_FAIL;
+ }
+
+ return S_OK;
+}
+
+/**
+ *Return count of elements in current container
+ * @param.
+ * @return count of elements in current container.
+ */
+long CEnumVariant::GetCountOfElements()
+{
+ if(m_pXAccessibleSelection.is())
+ return m_pXAccessibleSelection->getSelectedAccessibleChildCount();
+ return 0;
+}
+
+/**
+ * Set member m_pXAccessibleSelection to NULL and m_lCurrent to m_lLBound.
+ * @param.
+ * @return Result
+ */
+COM_DECLSPEC_NOTHROW STDMETHODIMP CEnumVariant::ClearEnumeration()
+{
+ // internal IEnumVariant - no mutex meeded
+
+ pUNOInterface = nullptr;
+ m_pXAccessibleSelection = nullptr;
+ m_lCurrent = m_lLBound;
+ return S_OK;
+}
+
+/**
+ *Static method to fetch XAccessibleSelection
+ * @param pXAcc XAccessible interface.
+ * @return XAccessibleSelection interface.
+ */
+static Reference<XAccessibleSelection> GetXAccessibleSelection(XAccessible* pXAcc)
+{
+ if( pXAcc == nullptr)
+ return nullptr;
+
+ Reference< XAccessibleContext > pRContext = pXAcc->getAccessibleContext();
+ if( !pRContext.is() )
+ return nullptr;
+
+ Reference< XAccessibleSelection > pRSelection(pRContext,UNO_QUERY);
+ if( !pRSelection.is() )
+ return nullptr;
+
+ return pRSelection;
+}
+
+/**
+ * Put valid UNO XAccessible interface.
+ * @param pXSelection XAccessible interface.
+ * @return Result...
+ */
+STDMETHODIMP CEnumVariant::PutSelection(hyper pXSelection)
+{
+ // internal IEnumVariant - no mutex meeded
+
+ pUNOInterface = reinterpret_cast<XAccessible*>(pXSelection);
+ m_pXAccessibleSelection = GetXAccessibleSelection(pUNOInterface);
+ return S_OK;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/winaccessibility/source/UAccCOM/EnumVariant.h b/winaccessibility/source/UAccCOM/EnumVariant.h
new file mode 100644
index 000000000..d82bd771f
--- /dev/null
+++ b/winaccessibility/source/UAccCOM/EnumVariant.h
@@ -0,0 +1,109 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include "Resource.h" // main symbols
+#include <com/sun/star/accessibility/XAccessible.hpp>
+#include <com/sun/star/accessibility/XAccessibleSelection.hpp>
+#include <AccObjectManagerAgent.hxx>
+
+#if defined __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wnon-virtual-dtor"
+#endif
+#include <UAccCOM.h>
+#if defined __clang__
+#pragma clang diagnostic pop
+#endif
+
+/**
+ * CEnumVariant implements IEnumVARIANT interface.
+ */
+class ATL_NO_VTABLE CEnumVariant :
+ public CComObjectRootEx<CComMultiThreadModel>,
+ public CComCoClass<CEnumVariant, &CLSID_EnumVariant>,
+ public IDispatchImpl<IEnumVariant, &IID_IEnumVariant, &LIBID_UACCCOMLib>
+{
+public:
+ CEnumVariant()
+ :m_lLBound(0),
+ pUNOInterface(nullptr)
+ {
+ m_lCurrent = m_lLBound;
+ }
+
+ virtual ~CEnumVariant() {};
+
+ DECLARE_NO_REGISTRY()
+
+ DECLARE_PROTECT_FINAL_CONSTRUCT()
+
+ BEGIN_COM_MAP(CEnumVariant)
+ COM_INTERFACE_ENTRY(IEnumVariant)
+ COM_INTERFACE_ENTRY(IEnumVARIANT)
+#if defined __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Winconsistent-missing-override"
+#endif
+ END_COM_MAP()
+#if defined __clang__
+#pragma clang diagnostic pop
+#endif
+
+ // IEnumVariant
+public:
+
+ STDMETHOD(ClearEnumeration)() override;
+
+ // IEnumVARIANT
+
+
+ HRESULT STDMETHODCALLTYPE Next(ULONG cElements,VARIANT __RPC_FAR *pvar,ULONG __RPC_FAR *pcElementFetched) override;
+
+
+ HRESULT STDMETHODCALLTYPE Skip(ULONG cElements) override;
+
+
+ HRESULT STDMETHODCALLTYPE Reset( void) override;
+
+
+ HRESULT STDMETHODCALLTYPE Clone(IEnumVARIANT __RPC_FAR *__RPC_FAR *ppenum) override;
+
+ // IEnumVariant
+
+
+ HRESULT STDMETHODCALLTYPE PutSelection(hyper pXSelection) override;
+
+
+ static HRESULT STDMETHODCALLTYPE Create(CEnumVariant __RPC_FAR *__RPC_FAR *ppenum);
+
+
+ long GetCountOfElements();
+
+private:
+
+ long m_lCurrent;
+ long m_lLBound;
+ css::accessibility::XAccessible* pUNOInterface;
+ css::uno::Reference<css::accessibility::XAccessibleSelection>
+ m_pXAccessibleSelection;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/winaccessibility/source/UAccCOM/MAccessible.cxx b/winaccessibility/source/UAccCOM/MAccessible.cxx
new file mode 100644
index 000000000..848960ff7
--- /dev/null
+++ b/winaccessibility/source/UAccCOM/MAccessible.cxx
@@ -0,0 +1,3162 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "MAccessible.h"
+
+#if defined __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wnon-virtual-dtor"
+#endif
+#include <UAccCOM.h>
+#if defined __clang__
+#pragma clang diagnostic pop
+#endif
+
+#include <algorithm>
+#include <cstddef>
+
+#include "AccAction.h"
+#include "AccRelation.h"
+#include "AccComponent.h"
+#include "AccText.h"
+#include "AccEditableText.h"
+#include "AccImage.h"
+#include "AccTable.h"
+#include "AccTableCell.h"
+#include "AccValue.h"
+#include "AccHypertext.h"
+#include "AccHyperLink.h"
+
+#include <rtl/ustrbuf.hxx>
+#include <vcl/svapp.hxx>
+#include <o3tl/char16_t2wchar_t.hxx>
+#include <comphelper/AccessibleImplementationHelper.hxx>
+
+#include <com/sun/star/accessibility/XAccessibleText.hpp>
+#include <com/sun/star/accessibility/XAccessibleEditableText.hpp>
+#include <com/sun/star/accessibility/XAccessibleImage.hpp>
+#include <com/sun/star/accessibility/XAccessibleTable.hpp>
+#include <com/sun/star/accessibility/XAccessibleExtendedComponent.hpp>
+#include <com/sun/star/accessibility/XAccessibleAction.hpp>
+#include <com/sun/star/accessibility/XAccessibleKeyBinding.hpp>
+#include <com/sun/star/accessibility/XAccessibleHypertext.hpp>
+#include <com/sun/star/accessibility/XAccessibleHyperlink.hpp>
+#include <com/sun/star/accessibility/XAccessibleRelationSet.hpp>
+#include <com/sun/star/accessibility/AccessibleStateType.hpp>
+#include <com/sun/star/accessibility/AccessibleRole.hpp>
+#include <com/sun/star/accessibility/XAccessibleGroupPosition.hpp>
+#include <com/sun/star/accessibility/XAccessibleValue.hpp>
+#include <com/sun/star/accessibility/XAccessibleExtendedAttributes.hpp>
+#include <com/sun/star/style/LineSpacing.hpp>
+#include <com/sun/star/style/TabStop.hpp>
+#include <com/sun/star/container/XIndexReplace.hpp>
+
+
+using namespace com::sun::star::uno;
+using namespace com::sun::star::accessibility;
+using namespace com::sun::star::accessibility::AccessibleStateType;
+
+namespace {
+
+enum class XInterfaceType {
+ XI_COMPONENT,
+ XI_TEXT,
+ XI_TABLE,
+ XI_TABLECELL,
+ XI_EDITABLETEXT,
+ XI_IMAGE,
+ XI_SELECTION,
+ XI_EXTENDEDCOMP,
+ XI_VALUE,
+ XI_KEYBINDING,
+ XI_ACTION,
+ XI_HYPERTEXT,
+ XI_HYPERLINK,
+ XI_ATTRIBUTE
+};
+
+template <class Interface>
+bool queryXInterface(XAccessible* pXAcc, XInterface** ppXI)
+{
+ if (!pXAcc)
+ return false;
+
+ Reference<XAccessibleContext> pRContext = pXAcc->getAccessibleContext();
+ if (!pRContext.is())
+ return false;
+
+ Reference<Interface> pRXI(pRContext, UNO_QUERY);
+ if (!pRXI.is())
+ return false;
+
+ *ppXI = pRXI.get();
+ return true;
+}
+
+// Since there's no specific XInterface for table cells, this
+// method checks that the accessible's parent is a table
+// (implements XAccessibleTable) and pXAcc's context implements
+// XAccessibleComponent.
+bool queryTableCell(XAccessible* pXAcc, XInterface** ppXI)
+{
+ XInterface* pXInterface = nullptr;
+
+ const bool bSupportsInterface = queryXInterface<XAccessibleComponent>(pXAcc, &pXInterface);
+ if (!bSupportsInterface)
+ return false;
+
+ // check whether parent is a table (its accessible context implements XAccessibleTable)
+ XInterface* pParentXInterface = nullptr;
+ Reference<XAccessible> xParentAcc = pXAcc->getAccessibleContext()->getAccessibleParent();
+ const bool bParentIsTable = queryXInterface<XAccessibleTable>(xParentAcc.get(), &pParentXInterface);
+
+ if (!bParentIsTable)
+ return false;
+
+ *ppXI = pXInterface;
+ return true;
+}
+
+}
+
+// IA2 states mapping, and name
+// maintenance the consistency, change one array, change the three all
+long const IA2_STATES[] =
+{
+ IA2_STATE_ACTIVE, // = 0x1;
+ IA2_STATE_ARMED, // = 0x2;
+ IA2_STATE_DEFUNCT, // = 0x4;
+ IA2_STATE_EDITABLE, // = 0x8;
+ IA2_STATE_HORIZONTAL, // = 0x10;
+ IA2_STATE_ICONIFIED, // = 0x20;
+ IA2_STATE_INVALID_ENTRY, // = 0x80;
+ IA2_STATE_MANAGES_DESCENDANTS, // = 0x100;
+ IA2_STATE_MODAL, // = 0x200;
+ IA2_STATE_MULTI_LINE, // = 0x400;
+ IA2_STATE_OPAQUE, // = 0x800;
+ IA2_STATE_REQUIRED, // = 0x2000;
+ IA2_STATE_SELECTABLE_TEXT, // = 0x3000;
+ IA2_STATE_SINGLE_LINE, // = 0x4000;
+ IA2_STATE_STALE, // = 0x8000;
+ IA2_STATE_SUPPORTS_AUTOCOMPLETION, // = 0x10000;
+ IA2_STATE_TRANSIENT, //= 0x20000;
+ IA2_STATE_VERTICAL // = 0x40000;
+};
+/*
+
+<=== map ===>
+
+*/
+short const UNO_STATES[] =
+{
+ ACTIVE, // = (sal_Int16)1;
+ ARMED, // = (sal_Int16)2;
+ DEFUNC, // = (sal_Int16)5;
+ EDITABLE, // = (sal_Int16)6;
+ HORIZONTAL, // = (sal_Int16)12;
+ ICONIFIED, // = (sal_Int16)13;
+ -1, //IA2_STATE_INVALID_ENTRY
+ MANAGES_DESCENDANTS, // = (sal_Int16)15;
+ MODAL, // = (sal_Int16)16;
+ MULTI_LINE, // = (sal_Int16)17;
+ OPAQUE, // = (sal_Int16)19;
+ -1, //IA2_STATE_REQUIRED
+ -1, //IA2_STATE_SELECTABLE_TEXT
+ SINGLE_LINE, // = (sal_Int16)26;
+ STALE, // = (sal_Int16)27;
+ -1, //IA2_STATE_SUPPORTS_AUTOCOMPLETION
+ TRANSIENT, //IA2_STATE_TRANSIENT
+ VERTICAL // = (sal_Int16)29;
+};
+
+using namespace com::sun::star::accessibility::AccessibleRole;
+
+
+AccObjectManagerAgent* CMAccessible::g_pAgent = nullptr;
+
+CMAccessible::CMAccessible():
+m_pszName(nullptr),
+m_pszValue(nullptr),
+m_pszActionDescription(nullptr),
+m_iRole(0x00),
+m_dState(0x00),
+m_pIParent(nullptr),
+m_dChildID(0x00),
+m_dFocusChildID(UACC_NO_FOCUS),
+m_hwnd(nullptr),
+m_isDestroy(false)
+{
+ m_sLocation.m_dLeft=0;
+ m_sLocation.m_dTop = 0;
+ m_sLocation.m_dWidth=0;
+ m_sLocation.m_dHeight=0;
+ CEnumVariant::Create(&m_pEnumVar);
+ m_containedObjects.clear();
+}
+
+CMAccessible::~CMAccessible()
+{
+ SolarMutexGuard g;
+
+ if(m_pszName!=nullptr)
+ {
+ SysFreeString(std::exchange(m_pszName, nullptr));
+ }
+ if(m_pszValue!=nullptr)
+ {
+ SysFreeString(std::exchange(m_pszValue, nullptr));
+ }
+
+ if(m_pszActionDescription!=nullptr)
+ {
+ SysFreeString(std::exchange(m_pszActionDescription, nullptr));
+ }
+
+ if(m_pIParent)
+ {
+ m_pIParent->Release();
+ m_pIParent=nullptr;
+ }
+ m_pEnumVar->Release();
+ m_containedObjects.clear();
+}
+
+/**
+* Returns the Parent IAccessible interface pointer to AT.
+* It should add reference, and the client should release the component.
+* It should return E_FAIL when the parent point is null.
+* @param ppdispParent [in,out] used to return the parent interface point.
+* when the point is null, should return null.
+* @return S_OK if successful and E_FAIL if the m_pIParent is NULL.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::get_accParent(IDispatch **ppdispParent)
+{
+ SolarMutexGuard g;
+
+ try {
+ if (m_isDestroy) return S_FALSE;
+ // #CHECK#
+ if(ppdispParent == nullptr)
+ {
+ return E_INVALIDARG;
+ }
+
+ if(m_pIParent)
+ {
+ *ppdispParent = m_pIParent;
+ (*ppdispParent)->AddRef();
+ return S_OK;
+ }
+ else if(m_hwnd)
+ {
+ HRESULT hr = AccessibleObjectFromWindow(m_hwnd, OBJID_WINDOW, IID_IAccessible, reinterpret_cast<void**>(ppdispParent));
+ if (!SUCCEEDED(hr) || !*ppdispParent)
+ {
+ return S_FALSE;
+ }
+ return S_OK;
+ }
+ return S_FALSE;
+
+ } catch(...) { return E_FAIL; }
+}
+
+/**
+* Returns child count of current COM object.
+* @param pcountChildren [in,out] used to return the children count.
+* @return S_OK if successful.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::get_accChildCount(long *pcountChildren)
+{
+ SolarMutexGuard g;
+
+ try {
+ if (m_isDestroy) return S_FALSE;
+ // #CHECK#
+ if(pcountChildren == nullptr)
+ {
+ return E_INVALIDARG;
+ }
+
+ if (!m_xAccessible.is())
+ return S_FALSE;
+
+ Reference<XAccessibleContext> const pRContext =
+ m_xAccessible->getAccessibleContext();
+ if( pRContext.is() )
+ {
+ *pcountChildren = pRContext->getAccessibleChildCount();
+ }
+
+ return S_OK;
+
+ } catch(...) { return E_FAIL; }
+}
+
+/**
+* Returns child interface pointer for AT according to input child ID.
+* @param varChild, vt member of varChild must be VT_I4,and lVal member stores the child ID,
+* the child ID specify child index from 0 to children count, 0 stands for object self.
+* @param ppdispChild, [in,out] use to return the child interface point.
+* @return S_OK if successful and S_FALSE if failure.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::get_accChild(VARIANT varChild, IDispatch **ppdispChild)
+{
+ SolarMutexGuard g;
+
+ try {
+ if (m_isDestroy) return S_FALSE;
+ // #CHECK#
+ if(ppdispChild == nullptr)
+ {
+ return E_INVALIDARG;
+ }
+ if(varChild.vt==VT_I4)
+ {
+ //get child interface pointer due to child ID
+ if(varChild.lVal==CHILDID_SELF)
+ {
+ AddRef();
+ *ppdispChild = this;
+ return S_OK;
+ }
+ *ppdispChild = GetChildInterface(varChild.lVal);
+ if((*ppdispChild) == nullptr)
+ return E_FAIL;
+ (*ppdispChild)->AddRef();
+ return S_OK;
+ }
+ return S_FALSE;
+
+ } catch(...) { return E_FAIL; }
+}
+
+/**
+* Returns the accessible name of the current COM object self or its one child to AT.
+* @param varChild, vt member of varChild must be VT_I4,and lVal member stores the child ID,
+* the child ID specify child index from 0 to children count, 0 stands for object self.
+* @param pszName, [in,out] use to return the name of the proper object.
+* @return S_OK if successful and S_FALSE if failure.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::get_accName(VARIANT varChild, BSTR *pszName)
+{
+ SolarMutexGuard g;
+
+ try {
+ if (m_isDestroy) return S_FALSE;
+ // #CHECK#
+ if(pszName == nullptr)
+ {
+ return E_INVALIDARG;
+ }
+ if(varChild.vt==VT_I4)
+ {
+ if(varChild.lVal==CHILDID_SELF)
+ {
+ SysFreeString(*pszName);
+ *pszName = SysAllocString(m_pszName);
+ return S_OK;
+ }
+
+ long lVal = varChild.lVal;
+ varChild.lVal = CHILDID_SELF;
+ IMAccessible *pChild = this->GetChildInterface(lVal);
+ if(!pChild)
+ return E_FAIL;
+ return pChild->get_accName(varChild,pszName);
+ }
+ return S_FALSE;
+
+ } catch(...) { return E_FAIL; }
+}
+
+/**
+* Returns the accessible value of the current COM object self or its one child to AT.
+* @param varChild, vt member of varChild must be VT_I4,and lVal member stores the child ID,
+* the child ID specify child index from 0 to children count, 0 stands for object self.
+* @param pszValue, [in,out] use to return the value of the proper object.
+* @return S_OK if successful and S_FALSE if failure.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::get_accValue(VARIANT varChild, BSTR *pszValue)
+{
+ SolarMutexGuard g;
+
+ try {
+ if (m_isDestroy) return S_FALSE;
+ // #CHECK#
+ if( pszValue == nullptr )
+ {
+ return E_INVALIDARG;
+ }
+ if( varChild.vt==VT_I4 )
+ {
+ if(varChild.lVal==CHILDID_SELF)
+ {
+ if(m_dState & STATE_SYSTEM_PROTECTED)
+ return E_ACCESSDENIED;
+
+ if ( m_pszValue !=nullptr && wcslen(m_pszValue) == 0 )
+ return S_OK;
+
+ SysFreeString(*pszValue);
+ *pszValue = SysAllocString(m_pszValue);
+ return S_OK;
+ }
+
+ long lVal = varChild.lVal;
+ varChild.lVal = CHILDID_SELF;
+ IMAccessible *pChild = this->GetChildInterface(lVal);
+ if(!pChild)
+ return E_FAIL;
+ return pChild->get_accValue(varChild,pszValue);
+ }
+ return S_FALSE;
+
+ } catch(...) { return E_FAIL; }
+}
+
+/**
+* Returns the accessible description of the current COM object self or its one child to AT.
+* @param varChild, vt member of varChild must be VT_I4,and lVal member stores the child ID,
+* the child ID specify child index from 0 to children count, 0 stands for object self.
+* @param pszDescription, [in,out] use to return the description of the proper object.
+* @return S_OK if successful and E_FAIL if failure.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::get_accDescription(VARIANT varChild, BSTR *pszDescription)
+{
+ SolarMutexGuard g;
+
+ try {
+ if (m_isDestroy) return S_FALSE;
+ // #CHECK#
+ if(pszDescription == nullptr)
+ {
+ return E_INVALIDARG;
+ }
+ if(varChild.vt==VT_I4)
+ {
+ if(varChild.lVal==CHILDID_SELF)
+ {
+ if (!m_xAccessible.is())
+ return S_FALSE;
+
+ Reference<XAccessibleContext> xContext = m_xAccessible->getAccessibleContext();
+ if (!xContext.is())
+ return S_FALSE;
+
+ const OUString sDescription = xContext->getAccessibleDescription();
+ SysFreeString(*pszDescription);
+ *pszDescription = SysAllocString(o3tl::toW(sDescription.getStr()));
+ return S_OK;
+ }
+
+ long lVal = varChild.lVal;
+ varChild.lVal = CHILDID_SELF;
+ IMAccessible *pChild = this->GetChildInterface(lVal);
+ if(!pChild)
+ return E_FAIL;
+ return pChild->get_accDescription(varChild,pszDescription);
+ }
+ return S_FALSE;
+
+ } catch(...) { return E_FAIL; }
+}
+
+/**
+* Returns the accessible role of the current COM object self or its one child to AT.
+* @param varChild, vt member of varChild must be VT_I4,and lVal member stores the child ID,
+* the child ID specify child index from 0 to children count, 0 stands for object self.
+* @param pvarRole, [in,out] use to return the role of the proper object.
+* @return S_OK if successful and S_FALSE if failure.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::get_accRole(VARIANT varChild, VARIANT *pvarRole)
+{
+ SolarMutexGuard g;
+
+ try {
+ if (m_isDestroy) return S_FALSE;
+ // #CHECK#
+ if(pvarRole == nullptr)
+ {
+ return E_INVALIDARG;
+ }
+ if(varChild.vt == VT_I4)
+ {
+
+ if(varChild.lVal == CHILDID_SELF)
+ {
+ VariantInit(pvarRole);
+ pvarRole->vt = VT_I4;
+
+ if (m_iRole < IA2_ROLE_CAPTION)
+ pvarRole->lVal = m_iRole;
+ else
+ pvarRole->lVal = ROLE_SYSTEM_CLIENT;
+
+ return S_OK;
+ }
+
+
+ long lVal = varChild.lVal;
+ varChild.lVal = CHILDID_SELF;
+ IMAccessible *pChild = this->GetChildInterface(lVal);
+ if(!pChild)
+ return E_FAIL;
+ return pChild->get_accRole(varChild,pvarRole);
+ }
+ return S_FALSE;
+
+ } catch(...) { return E_FAIL; }
+}
+
+/**
+* Returns the accessible state of the current COM object self or its one child to AT.
+* @param varChild, vt member of varChild must be VT_I4,and lVal member stores the child ID,
+* the child ID specify child index from 0 to children count, 0 stands for object self.
+* @param pvarState, [in,out] use to return the state of the proper object.
+* @return S_OK if successful and S_FALSE if failure.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::get_accState(VARIANT varChild, VARIANT *pvarState)
+{
+ SolarMutexGuard g;
+
+ try {
+ if (m_isDestroy) return S_FALSE;
+ // #CHECK#
+ if(pvarState == nullptr)
+ {
+ return E_INVALIDARG;
+ }
+ if(varChild.vt==VT_I4)
+ {
+ if(varChild.lVal == CHILDID_SELF)
+ {
+ if (m_xAccessible.is())
+ {
+ Reference<XAccessibleContext> const pContext =
+ m_xAccessible->getAccessibleContext();
+ if(pContext.is())
+ {
+ // add the STATE_SYSTEM_LINKED state
+ Reference< XAccessibleHypertext > pRHypertext(pContext,UNO_QUERY);
+ if(pRHypertext.is())
+ {
+ if( pRHypertext->getHyperLinkCount() > 0 )
+ m_dState |= STATE_SYSTEM_LINKED;
+ else
+ m_dState &= ~STATE_SYSTEM_LINKED;
+ }
+ else
+ m_dState &= ~STATE_SYSTEM_LINKED;
+ }
+ }
+
+ VariantInit(pvarState);
+ pvarState->vt = VT_I4;
+ pvarState->lVal = m_dState;
+ return S_OK;
+ }
+
+ long lVal = varChild.lVal;
+ varChild.lVal = CHILDID_SELF;
+ IMAccessible *pChild = this->GetChildInterface(lVal);
+ if(!pChild)
+ return E_FAIL;
+ return pChild->get_accState(varChild,pvarState);
+ }
+ return S_FALSE;
+
+ } catch(...) { return E_FAIL; }
+}
+
+/**
+* Returns the accessible helpString of the current COM object self or its one child to AT.
+* @param varChild, vt member of varChild must be VT_I4,and lVal member stores the child ID,
+* the child ID specify child index from 0 to children count, 0 stands for object self.
+* @param pszHelp, [in,out] use to return the helpString of the proper object.
+* @return S_OK if successful and E_FAIL if failure.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::get_accHelp(VARIANT, BSTR *)
+{
+ return E_NOTIMPL;
+}
+
+/**
+* Returns the accessible HelpTopic of the current COM object self or its one child to AT.
+* @param varChild, vt member of varChild must be VT_I4,and lVal member stores the child ID,
+* the child ID specify child index from 0 to children count, 0 stands for object self.
+* @param pszHelpFile, [in,out] use to return the HelpTopic of the proper object.
+* @param pidTopic, use to return the HelpTopic ID of the proper object.
+* @return S_OK if successful and E_FAIL if failure.
+* Not implemented yet
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::get_accHelpTopic(BSTR *, VARIANT, long *)
+{
+ return E_NOTIMPL;
+}
+
+static bool GetMnemonicChar( const OUString& aStr, sal_Unicode* wStr)
+{
+ for (sal_Int32 i = 0;; i += 2) {
+ i = aStr.indexOf('~', i);
+ if (i == -1 || i == aStr.getLength() - 1) {
+ return false;
+ }
+ auto c = aStr[i + 1];
+ if (c != '~') {
+ *wStr = c;
+ return true;
+ }
+ }
+}
+
+/**
+* Returns the accessible keyboard shortcut of the current COM object self or its one child to AT.
+* @param varChild, vt member of varChild must be VT_I4,and lVal member stores the child ID,
+* the child ID specify child index from 0 to children count, 0 stands for object self.
+* @param pszKeyboardShortcut, [in,out] use to return the kbshortcut of the proper object.
+* @return S_OK if successful and E_FAIL if failure.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::get_accKeyboardShortcut(VARIANT varChild, BSTR *pszKeyboardShortcut)
+{
+ SolarMutexGuard g;
+
+ try {
+
+ if (m_isDestroy) return S_FALSE;
+ // #CHECK#
+ if(pszKeyboardShortcut == nullptr)
+ {
+ return E_INVALIDARG;
+ }
+
+ if(varChild.vt==VT_I4)
+ {
+ if(varChild.lVal == CHILDID_SELF)
+ {
+ if (m_xAccessible.is())
+ {
+ Reference<XAccessibleContext> const pRContext =
+ m_xAccessible->getAccessibleContext();
+ if( !pRContext.is() )
+ return S_FALSE;
+
+ Reference<XAccessibleAction> pRXI(pRContext,UNO_QUERY);
+
+ OUString wString;
+
+ if( pRXI.is() && pRXI->getAccessibleActionCount() >= 1)
+ {
+ Reference< XAccessibleKeyBinding > binding = pRXI->getAccessibleActionKeyBinding(0);
+ if( binding.is() )
+ {
+ long nCount = binding->getAccessibleKeyBindingCount();
+ if(nCount >= 1)
+ {
+ wString = comphelper::GetkeyBindingStrByXkeyBinding( binding->getAccessibleKeyBinding(0) );
+ }
+ }
+ }
+ if(wString.isEmpty())
+ {
+ Reference<XAccessibleRelationSet> pRrelationSet = pRContext->getAccessibleRelationSet();
+ if(!pRrelationSet.is())
+ {
+ return S_FALSE;
+ }
+
+ long nRelCount = pRrelationSet->getRelationCount();
+
+ // Modified by Steve Yin, for SODC_1552
+ if( /*nRelCount <= 0 &&*/ m_iRole == ROLE_SYSTEM_TEXT )
+ {
+ VARIANT varParentRole;
+ VariantInit( &varParentRole );
+
+ if (m_pIParent
+ && SUCCEEDED(m_pIParent->get_accRole(varChild, &varParentRole))
+ && varParentRole.lVal == ROLE_SYSTEM_COMBOBOX) // edit in comboBox
+ {
+ m_pIParent->get_accKeyboardShortcut(varChild, pszKeyboardShortcut);
+ return S_OK;
+ }
+ }
+
+ AccessibleRelation *paccRelation = nullptr;
+ AccessibleRelation accRelation;
+ for(int i=0; i<nRelCount ; i++)
+ {
+ if( pRrelationSet->getRelation(i).RelationType == 6 )
+ {
+ accRelation = pRrelationSet->getRelation(i);
+ paccRelation = &accRelation;
+ }
+ }
+
+ if(paccRelation == nullptr)
+ return S_FALSE;
+
+ Sequence< Reference< XInterface > > xTargets = paccRelation->TargetSet;
+ Reference<XInterface> pRAcc = xTargets[0];
+
+ XAccessible* pXAcc = static_cast<XAccessible*>(pRAcc.get());
+
+ Reference<XAccessibleContext> pRLebelContext = pXAcc->getAccessibleContext();
+ if(!pRLebelContext.is())
+ return S_FALSE;
+
+ pRrelationSet = pRLebelContext->getAccessibleRelationSet();
+ nRelCount = pRrelationSet->getRelationCount();
+
+ paccRelation = nullptr;
+ for(int j=0; j<nRelCount ; j++)
+ {
+ if( pRrelationSet->getRelation(j).RelationType == 5 )
+ {
+ accRelation = pRrelationSet->getRelation(j);
+ paccRelation = &accRelation;
+ }
+ }
+
+ if(paccRelation)
+ {
+ xTargets = paccRelation->TargetSet;
+ pRAcc = xTargets[0];
+ if (m_xAccessible.get() != static_cast<XAccessible*>(pRAcc.get()))
+ return S_FALSE;
+ }
+
+ Reference<XAccessibleExtendedComponent> pRXIE(pRLebelContext,UNO_QUERY);
+ if(!pRXIE.is())
+ return S_FALSE;
+
+ OUString ouStr = pRXIE->getTitledBorderText();
+ sal_Unicode key;
+ if(GetMnemonicChar(ouStr, &key))
+ {
+ wString = "Alt+" + OUStringChar(key);
+ }
+ else
+ return S_FALSE;
+ }
+
+ SysFreeString(*pszKeyboardShortcut);
+ *pszKeyboardShortcut = SysAllocString(o3tl::toW(wString.getStr()));
+
+ return S_OK;
+ }
+ else
+ {
+ return S_FALSE;
+ }
+ }
+
+ long lVal = varChild.lVal;
+ varChild.lVal = CHILDID_SELF;
+ IMAccessible *pChild = this->GetChildInterface(lVal);
+ if(!pChild)
+ return E_FAIL;
+
+ return pChild->get_accKeyboardShortcut(varChild,pszKeyboardShortcut);
+ }
+ return S_FALSE;
+
+ } catch(...) { return E_FAIL; }
+}
+
+/**
+* Returns the current focused child to AT.
+* @param pvarChild, [in,out] vt member of pvarChild must be VT_I4,and lVal member stores the child ID,
+* the child ID specify child index from 0 to children count, 0 stands for object self.
+* @return S_OK if successful and E_FAIL if failure.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::get_accFocus(VARIANT *pvarChild)
+{
+ SolarMutexGuard g;
+
+ try {
+ if (m_isDestroy) return S_FALSE;
+ // #CHECK#
+ if(pvarChild == nullptr)
+ {
+ return E_INVALIDARG;
+ }
+ if( m_dFocusChildID==UACC_NO_FOCUS )
+ {
+ pvarChild->vt = VT_EMPTY;//no focus on the object and its children
+ return S_OK;
+ }
+ //if the descendant of current object has focus indicated by m_dFocusChildID, return the IDispatch of this focused object
+ else
+ {
+ IMAccessible* pIMAcc = nullptr;
+ g_pAgent->GetIAccessibleFromResID(m_dFocusChildID,&pIMAcc);
+ if (pIMAcc == nullptr)
+ {
+ return E_FAIL;
+ }
+ pIMAcc->AddRef();
+ pvarChild->vt = VT_DISPATCH;
+ pvarChild->pdispVal = pIMAcc;
+
+ }
+ return S_OK;
+
+ } catch(...) { return E_FAIL; }
+}
+
+/**
+* Returns the selection of the current COM object to AT.
+* @param pvarChildren,[in,out]
+* if selection num is 0,return VT_EMPTY for vt,
+* if selection num is 1,return VT_I4 for vt,and child index for lVal
+* if selection num >1,return VT_UNKNOWN for vt, and IEnumVariant* for punkVal
+* @return S_OK if successful and S_FALSE if failure.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::get_accSelection(VARIANT *pvarChildren)
+{
+ SolarMutexGuard g;
+
+ try {
+ if (m_isDestroy) return S_FALSE;
+ // #CHECK#
+ if(pvarChildren == nullptr)
+ {
+ return E_INVALIDARG;
+ }
+ switch(m_pEnumVar->GetCountOfElements())
+ {
+ case 0:
+ pvarChildren->vt = VT_EMPTY;
+ break;
+ case 1:
+ VARIANT varTmp[1];
+ ULONG count;
+ VariantInit(&varTmp[0]);
+ m_pEnumVar->Next(1,varTmp,&count);
+ if(count!=1)
+ return S_FALSE;
+ pvarChildren->vt = VT_DISPATCH;
+ pvarChildren->pdispVal = varTmp[0].pdispVal;
+ pvarChildren->pdispVal->AddRef();
+ VariantClear(&varTmp[0]);
+ m_pEnumVar->Reset();
+ break;
+ default:
+ pvarChildren->vt = VT_UNKNOWN;
+ IEnumVARIANT* pClone;
+ m_pEnumVar->Clone(&pClone);
+ pClone->Reset();
+ pvarChildren->punkVal = pClone;
+ break;
+ }
+ return S_OK;
+
+ } catch(...) { return E_FAIL; }
+}
+
+/**
+* Returns the location of the current COM object self or its one child to AT.
+* @param varChild, vt member of varChild must be VT_I4,and lVal member stores the child ID,
+* the child ID specify child index from 0 to children count, 0 stands for object self.
+* @param pxLeft, [in,out] use to return the x-coordination of the proper object.
+* @param pyTop, [in,out] use to return the y-coordination of the proper object.
+* @param pcxWidth, [in,out] use to return the x-coordination width of the proper object.
+* @param pcyHeight, [in,out] use to return the y-coordination height of the proper object.
+* @return S_OK if successful and S_FALSE if failure.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::accLocation(long *pxLeft, long *pyTop, long *pcxWidth, long *pcyHeight, VARIANT varChild)
+{
+ SolarMutexGuard g;
+
+ try {
+ if (m_isDestroy) return S_FALSE;
+ // #CHECK#
+ if(pxLeft == nullptr || pyTop == nullptr || pcxWidth == nullptr || pcyHeight == nullptr)
+ {
+ return E_INVALIDARG;
+ }
+
+ if(varChild.vt==VT_I4)
+ {
+ if(varChild.lVal==CHILDID_SELF)
+ {
+
+ if (m_xAccessible.is())
+ {
+ Reference<XAccessibleContext> const pRContext =
+ m_xAccessible->getAccessibleContext();
+ if( !pRContext.is() )
+ return S_FALSE;
+ Reference< XAccessibleComponent > pRComponent(pRContext,UNO_QUERY);
+ if( !pRComponent.is() )
+ return S_FALSE;
+
+ css::awt::Point pCPoint = pRComponent->getLocationOnScreen();
+ css::awt::Size pCSize = pRComponent->getSize();
+ *pxLeft = pCPoint.X;
+ *pyTop = pCPoint.Y;
+ *pcxWidth = pCSize.Width;
+ *pcyHeight = pCSize.Height;
+ return S_OK;
+ }
+ else
+ {
+ *pxLeft = m_sLocation.m_dLeft;
+ *pyTop = m_sLocation.m_dTop;
+ *pcxWidth = m_sLocation.m_dWidth;
+ *pcyHeight = m_sLocation.m_dHeight;
+ return S_OK;
+ }
+ }
+
+ }
+ return S_FALSE;
+
+ } catch(...) { return E_FAIL; }
+}
+
+/**
+* Returns the current focused child to AT.
+* @param navDir, the direction flag of the navigation.
+* @param varStart, the start child id of this navigation action.
+* @param pvarEndUpAt, [in,out] the end up child of this navigation action.
+* @return S_OK if successful and E_FAIL if failure.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::accNavigate(long navDir, VARIANT varStart, VARIANT *pvarEndUpAt)
+{
+ SolarMutexGuard g;
+
+ try {
+ if (m_isDestroy) return S_FALSE;
+ // #CHECK#
+ if(pvarEndUpAt == nullptr)
+ {
+ return E_INVALIDARG;
+ }
+ HRESULT ret = E_FAIL;
+ switch (navDir)
+ {
+ case NAVDIR_FIRSTCHILD:
+ ret = GetFirstChild(varStart,pvarEndUpAt);
+ break;
+ case NAVDIR_LASTCHILD:
+ ret = GetLastChild(varStart,pvarEndUpAt);
+ break;
+ case NAVDIR_NEXT:
+ ret = GetNextSibling(varStart,pvarEndUpAt);
+ break;
+ case NAVDIR_PREVIOUS:
+ ret = GetPreSibling(varStart,pvarEndUpAt);
+ break;
+ case NAVDIR_DOWN://do not implement temporarily
+ break;
+ case NAVDIR_UP://do not implement temporarily
+ break;
+ case NAVDIR_LEFT://do not implement temporarily
+ break;
+ case NAVDIR_RIGHT://do not implement temporarily
+ break;
+ default:
+ break;
+ }
+ return ret;
+
+ } catch(...) { return E_FAIL; }
+}
+
+COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::accHitTest(long xLeft, long yTop, VARIANT *pvarChild)
+{
+ SolarMutexGuard g;
+
+ try {
+ if (m_isDestroy) return S_FALSE;
+ // #CHECK#
+ if(pvarChild == nullptr)
+ {
+ return E_INVALIDARG;
+ }
+ long x, y, w, h;
+ VARIANT varSelf;
+ VariantInit(&varSelf);
+ varSelf.vt = VT_I4;
+ varSelf.lVal = CHILDID_SELF;
+ accLocation(&x,&y,&w,&h,varSelf);
+ if( (x < xLeft && (x + w) >xLeft) && (y < yTop && (y + h) >yTop) )
+ {
+ int i, nCount;
+ pvarChild->vt = VT_EMPTY;
+ Reference< XAccessibleContext > pRContext = GetContextByXAcc(m_xAccessible.get());
+ nCount = pRContext->getAccessibleChildCount();
+ if(nCount > 256)
+ return E_FAIL;
+ IMAccessible* child = nullptr;
+ for( i = 0; i<nCount; i++)
+ {
+
+ child = GetChildInterface(i + 1);
+ if(child && child->accHitTest(xLeft,yTop,pvarChild) == S_OK)
+ break;
+ }
+
+ if(pvarChild->vt == VT_DISPATCH)
+ return S_OK;
+
+ if( i < nCount)
+ {
+ pvarChild->vt = VT_DISPATCH;
+ pvarChild->pdispVal = child;
+ child->AddRef();
+ }
+ else
+ {
+ pvarChild->vt = VT_I4;
+ pvarChild->lVal = CHILDID_SELF;
+ }
+ return S_OK;
+ }
+ return S_FALSE;
+
+ } catch(...) { return E_FAIL; }
+}
+
+/**
+* Get The other Interface from CMAccessible.
+* @param guidService, must be IID_IAccessible here.
+* @param riid, the IID interface .
+* @return S_OK if successful and S_FALSE if failure.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::QueryService(REFGUID guidService, REFIID riid, void** ppvObject)
+{
+ if( InlineIsEqualGUID(guidService, IID_IAccessible) )
+ return QueryInterface(riid, ppvObject);
+ return S_FALSE;
+}
+
+/**
+* Set the accessible name of the current COM object self or its one child from UNO.
+* @param varChild, vt member of varChild must be VT_I4,and lVal member stores the child ID,
+* the child ID specify child index from 0 to children count, 0 stands for object self.
+* @param szName, the name used to set the name of the proper object.
+* @return S_OK if successful and E_FAIL if failure.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::put_accName(VARIANT varChild, BSTR szName)
+{
+ SolarMutexGuard g;
+
+ try {
+ if (m_isDestroy) return S_FALSE;
+ if(varChild.vt==VT_I4)
+ {
+ if(varChild.lVal==CHILDID_SELF)
+ {
+ SysFreeString(m_pszName);
+ m_pszName=SysAllocString(szName);
+ return S_OK;
+ }
+
+ long lVal = varChild.lVal;
+ varChild.lVal = CHILDID_SELF;
+ IMAccessible *pChild = this->GetChildInterface(lVal);
+ if(!pChild)
+ return E_FAIL;
+ return pChild->put_accName(varChild,szName);
+ }
+ return E_FAIL;
+
+ } catch(...) { return E_FAIL; }
+}
+
+/**
+* Set the accessible value of the current COM object self or its one child from UNO.
+* @param varChild, vt member of varChild must be VT_I4,and lVal member stores the child ID,
+* the child ID specify child index from 0 to children count, 0 stands for object self.
+* @param szValue, the value used to set the value of the proper object.
+* @return S_OK if successful and E_FAIL if failure.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::put_accValue(VARIANT varChild, BSTR szValue)
+{
+ SolarMutexGuard g;
+
+ try {
+ if (m_isDestroy) return S_FALSE;
+ if(varChild.vt==VT_I4)
+ {
+ if(varChild.lVal==CHILDID_SELF)
+ {
+ SysFreeString(m_pszValue);
+ m_pszValue=SysAllocString(szValue);
+ return S_OK;
+ }
+
+ long lVal = varChild.lVal;
+ varChild.lVal = CHILDID_SELF;
+ IMAccessible *pChild = this->GetChildInterface(lVal);
+ if(!pChild)
+ return E_FAIL;
+ return pChild->put_accValue(varChild,szValue);
+ }
+ return E_FAIL;
+
+ } catch(...) { return E_FAIL; }
+}
+
+/**
+* Set the accessible name of the current COM object self from UNO.
+* @param pszName, the name value used to set the name of the current object.
+* @return S_OK if successful and E_FAIL if failure.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::Put_XAccName(const OLECHAR __RPC_FAR *pszName)
+{
+ // internal IMAccessible - no mutex meeded
+
+ try {
+ if (m_isDestroy) return S_FALSE;
+ // #CHECK#
+ if(pszName == nullptr)
+ {
+ return E_INVALIDARG;
+ }
+
+ SysFreeString(m_pszName);
+ m_pszName = SysAllocString(pszName);
+ if(m_pszName==nullptr)
+ return E_FAIL;
+ return S_OK;
+
+ } catch(...) { return E_FAIL; }
+}
+
+/**
+* Set the accessible role of the current COM object self from UNO.
+* @param pRole, the role value used to set the role of the current object.
+* @return S_OK if successful and E_FAIL if failure.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::Put_XAccRole(unsigned short pRole)
+{
+ // internal IMAccessible - no mutex meeded
+
+ m_iRole = pRole;
+ return S_OK;
+}
+
+/**
+* Add one state into the current state set for the current COM object from UNO.
+* @param pXSate, the state used to set the name of the current object.
+* @return S_OK if successful and E_FAIL if failure.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::DecreaseState(DWORD pXSate)
+{
+ // internal IMAccessible - no mutex meeded
+
+ m_dState &= (~pXSate);
+ return S_OK;
+}
+
+/**
+* Delete one state into the current state set for the current COM object from UNO.
+* @param pXSate, the state used to set the name of the current object.
+* @return S_OK if successful and E_FAIL if failure.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::IncreaseState(DWORD pXSate)
+{
+ // internal IMAccessible - no mutex meeded
+
+ m_dState |= pXSate;
+ return S_OK;
+}
+
+/**
+* Set state into the current state set for the current COM object from UNO.
+* @param pXSate, the state used to set the name of the current object.
+* @return S_OK if successful and E_FAIL if failure.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::SetState(DWORD pXSate)
+{
+ // internal IMAccessible - no mutex meeded
+
+ m_dState = pXSate;
+ return S_OK;
+}
+
+/**
+* Set the accessible value of the current COM object self from UNO.
+* @param pszAccValue, the name used to set the value of the current object.
+* @return S_OK if successful and E_FAIL if failure.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::Put_XAccValue(const OLECHAR __RPC_FAR *pszAccValue)
+{
+ // internal IMAccessible - no mutex meeded
+
+ try {
+ if (m_isDestroy) return S_FALSE;
+ // #CHECK#
+ if(pszAccValue == nullptr)
+ {
+ return E_INVALIDARG;
+ }
+ SysFreeString(m_pszValue);
+ m_pszValue = SysAllocString(pszAccValue);
+ if(m_pszValue==nullptr)
+ return E_FAIL;
+ return S_OK;
+
+ } catch(...) { return E_FAIL; }
+}
+
+/**
+* Set the HWND value of the current COM object self from UNO. It should set the parent IAccessible
+* Object through the method AccessibleObjectFromWindow(...).
+* @param hwnd, the HWND used to set the value of the current object.
+* @return S_OK if successful and E_FAIL if failure.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::Put_XAccWindowHandle(HWND hwnd)
+{
+ // internal IMAccessible - no mutex meeded
+
+ try {
+ if (m_isDestroy) return S_FALSE;
+ m_hwnd = hwnd;
+ return S_OK;
+
+ } catch(...) { return E_FAIL; }
+}
+
+/**
+* Set accessible focus by specifying child ID
+* @param dChildID, the child id identifies the focus child.
+* @return S_OK if successful and E_FAIL if failure.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::Put_XAccFocus(long dChildID)
+{
+ // internal IMAccessible - no mutex meeded
+
+ try {
+ if (m_isDestroy) return S_FALSE;
+
+ if(dChildID==CHILDID_SELF)
+ {
+ if(m_pIParent)
+ {
+ m_pIParent->Put_XAccFocus(m_dChildID);
+ }
+ }
+ else
+ {
+ m_dFocusChildID = dChildID;
+ //traverse all ancestors to set the focused child ID so that when the get_accFocus is called on
+ //any of the ancestors, this id can be used to get the IAccessible of focused object.
+ if(m_pIParent)
+ {
+ m_pIParent->Put_XAccFocus(dChildID);
+ }
+ }
+ return S_OK;
+
+ } catch(...) { return E_FAIL; }
+}
+
+/**
+*Set accessible object location for the current COM object
+* @param sLocation, the location of the current object.
+* @return S_OK if successful and E_FAIL if failure.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::Put_XAccLocation(const Location sLocation)
+{
+ // internal IMAccessible - no mutex meeded
+
+ this->m_sLocation = sLocation;
+ return S_OK;
+}
+
+/**
+* Set accessible parent object for the current COM object if
+* the current object is a child of some COM object
+* @param pIParent, the parent of the current object.
+* @return S_OK if successful and E_FAIL if failure.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::Put_XAccParent(IMAccessible __RPC_FAR *pIParent)
+{
+ // internal IMAccessible - no mutex meeded
+
+ this->m_pIParent = pIParent;
+
+ if(pIParent)
+ m_pIParent->AddRef();
+
+ return S_OK;
+}
+
+/**
+* Set unique child id to COM
+* @param dChildID, the id of the current object.
+* @return S_OK if successful and E_FAIL if failure.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::Put_XAccChildID(long dChildID)
+{
+ // internal IMAccessible - no mutex meeded
+
+ this->m_dChildID = dChildID;
+ return S_OK;
+}
+
+/**
+* Set AccObjectManagerAgent object pointer to COM
+* @param pAgent, the AccObjectManagerAgent point.
+* @return S_OK if successful and E_FAIL if failure.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::Put_XAccAgent(hyper pAgent)
+{
+ // internal IMAccessible - no mutex meeded
+
+ g_pAgent = reinterpret_cast<AccObjectManagerAgent*>(pAgent);
+ return S_OK;
+}
+
+/**
+* When a UNO control disposing, it disposes its listeners,
+* then notify AccObject in bridge management, then notify
+* COM that the XAccessible is invalid, so set m_xAccessible as NULL
+* @return S_OK if successful and E_FAIL if failure.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::NotifyDestroy()
+{
+ // internal IMAccessible - no mutex meeded
+
+ m_isDestroy = true;
+ m_xAccessible.clear();
+ return S_OK;
+}
+
+/**
+*private methods that help implement public functions
+*/
+
+/**
+* Return child interface pointer by child ID,note: need to call AddRef()
+* @param lChildID, specify child index,which AT(such as Inspect32) gives.
+* @return IMAccessible*, pointer to the corresponding child object.
+*/
+IMAccessible* CMAccessible::GetChildInterface(long dChildID)//for test
+{
+ if(dChildID<0)
+ {
+ if(g_pAgent)
+ {
+ IMAccessible* pIMAcc = nullptr;
+ g_pAgent->GetIAccessibleFromResID(dChildID,&pIMAcc);
+ return pIMAcc;
+ }
+ return nullptr;
+ }
+ else
+ {
+ if (!m_xAccessible.is())
+ return nullptr;
+
+ Reference<XAccessibleContext> const pRContext =
+ m_xAccessible->getAccessibleContext();
+ if( !pRContext.is() )
+ return nullptr;
+
+ if(dChildID<1 || dChildID>pRContext->getAccessibleChildCount())
+ return nullptr;
+
+ IAccessible* pChild = nullptr;
+ Reference< XAccessible > pXChild = pRContext->getAccessibleChild(dChildID-1);
+ bool isGet = get_IAccessibleFromXAccessible(pXChild.get(), &pChild);
+
+ if(!isGet)
+ {
+ g_pAgent->InsertAccObj(pXChild.get(), m_xAccessible.get(), m_hwnd);
+ isGet = get_IAccessibleFromXAccessible(pXChild.get(), &pChild);
+ }
+
+ if(isGet)
+ {
+ IMAccessible* pIMAcc = static_cast<IMAccessible*>(pChild);
+ return pIMAcc;
+ }
+ }
+
+ return nullptr;
+}
+
+/**
+* for descendantmanager circumstance,provide child interface when navigate
+* @param varCur, the current child.
+* @param flags, the navigation direction.
+* @return IMAccessible*, the child of the end up node.
+*/
+IMAccessible* CMAccessible::GetNavigateChildForDM(VARIANT varCur, short flags)
+{
+
+ XAccessibleContext* pXContext = GetContextByXAcc(m_xAccessible.get());
+ if(pXContext==nullptr)
+ {
+ return nullptr;
+ }
+
+ int count = pXContext->getAccessibleChildCount();
+ if(count<1)
+ {
+ return nullptr;
+ }
+
+ IMAccessible* pCurChild = nullptr;
+ union {
+ XAccessible* pChildXAcc;
+ hyper nHyper = 0;
+ };
+ Reference<XAccessible> pRChildXAcc;
+ XAccessibleContext* pChildContext = nullptr;
+ int index = 0,delta=0;
+ switch(flags)
+ {
+ case DM_FIRSTCHILD:
+ pRChildXAcc = pXContext->getAccessibleChild(0);
+ break;
+ case DM_LASTCHILD:
+ pRChildXAcc = pXContext->getAccessibleChild(count-1);
+ break;
+ case DM_NEXTCHILD:
+ case DM_PREVCHILD:
+ pCurChild = GetChildInterface(varCur.lVal);
+ if(pCurChild==nullptr)
+ {
+ return nullptr;
+ }
+ pCurChild->GetUNOInterface(&nHyper);
+ if(pChildXAcc==nullptr)
+ {
+ return nullptr;
+ }
+ pChildContext = GetContextByXAcc(pChildXAcc);
+ if(pChildContext == nullptr)
+ {
+ return nullptr;
+ }
+ delta = (flags==DM_NEXTCHILD)?1:-1;
+ //currently, getAccessibleIndexInParent is error in UNO for
+ //some kind of List,such as ValueSet, the index will be less 1 than
+ //what should be, need to fix UNO code
+ index = pChildContext->getAccessibleIndexInParent()+delta;
+ if((index>=0)&&(index<=count-1))
+ {
+ pRChildXAcc = pXContext->getAccessibleChild(index);
+ }
+ break;
+ default:
+ break;
+ }
+
+ if(!pRChildXAcc.is())
+ {
+ return nullptr;
+ }
+ pChildXAcc = pRChildXAcc.get();
+ g_pAgent->InsertAccObj(pChildXAcc, m_xAccessible.get());
+ return g_pAgent->GetIMAccByXAcc(pChildXAcc);
+}
+
+/**
+*the following 4 private methods are for accNavigate implementation
+*/
+
+/**
+* Return first child for parent container, process differently according
+* to whether it is descendant manage
+* @param varStart, the start child id of this navigation action.
+* @param pvarEndUpAt, [in,out] the end up child of this navigation action.
+* @return S_OK if successful and E_FAIL if failure.
+*/
+HRESULT CMAccessible::GetFirstChild(VARIANT varStart,VARIANT* pvarEndUpAt)
+{
+
+ try {
+ if (m_isDestroy) return S_FALSE;
+ // #CHECK#
+ if(pvarEndUpAt == nullptr)
+ {
+ return E_INVALIDARG;
+ }
+ if(varStart.vt != VT_I4)
+ {
+ pvarEndUpAt->vt = VT_EMPTY;
+ return E_INVALIDARG;
+ }
+
+ pvarEndUpAt->pdispVal = GetNavigateChildForDM(varStart, DM_FIRSTCHILD);
+ if(pvarEndUpAt->pdispVal)
+ {
+ pvarEndUpAt->pdispVal->AddRef();
+ pvarEndUpAt->vt = VT_DISPATCH;
+ return S_OK;
+ }
+
+ pvarEndUpAt->vt = VT_EMPTY;
+ return E_FAIL;
+
+ } catch(...) { return E_FAIL; }
+}
+
+/**
+* Return last child for parent container, process differently according
+* to whether it is descendant manage
+* @param varStart, the start child id of this navigation action.
+* @param pvarEndUpAt, [in,out] the end up child of this navigation action.
+* @return S_OK if successful and E_FAIL if failure.
+*/
+HRESULT CMAccessible::GetLastChild(VARIANT varStart,VARIANT* pvarEndUpAt)
+{
+
+ try {
+ if (m_isDestroy) return S_FALSE;
+ // #CHECK#
+ if(pvarEndUpAt == nullptr)
+ {
+ return E_INVALIDARG;
+ }
+ if(varStart.vt != VT_I4)
+ {
+ pvarEndUpAt->vt = VT_EMPTY;
+ return E_INVALIDARG;
+ }
+
+ pvarEndUpAt->pdispVal = GetNavigateChildForDM(varStart, DM_LASTCHILD);
+ if(pvarEndUpAt->pdispVal)
+ {
+ pvarEndUpAt->pdispVal->AddRef();
+ pvarEndUpAt->vt = VT_DISPATCH;
+ return S_OK;
+ }
+ pvarEndUpAt->vt = VT_EMPTY;
+ return E_FAIL;
+
+ } catch(...) { return E_FAIL; }
+}
+
+/**
+* The method GetNextSibling is general, whatever it is descendant manage or not
+* Get the next sibling object.
+* @param varStart, the start child id of this navigation action.
+* @param pvarEndUpAt, [in,out] the end up child of this navigation action.
+* @return S_OK if successful and E_FAIL if failure.
+*/
+HRESULT CMAccessible::GetNextSibling(VARIANT varStart,VARIANT* pvarEndUpAt)
+{
+
+ try {
+ if (m_isDestroy) return S_FALSE;
+ if(varStart.vt != VT_I4)
+ {
+ pvarEndUpAt->vt = VT_EMPTY;
+ return E_INVALIDARG;
+ }
+
+ Reference<XAccessibleContext> const pRContext =
+ GetContextByXAcc(m_xAccessible.get());
+ if(pRContext.is())
+ {
+ varStart.iVal = sal_Int16(pRContext->getAccessibleIndexInParent() + 2);
+ if(m_pIParent)
+ if( m_pIParent->get_accChild(varStart,&pvarEndUpAt->pdispVal) == S_OK)
+ {
+ pvarEndUpAt->vt = VT_DISPATCH;
+ return S_OK;
+ }
+ }
+ pvarEndUpAt->vt = VT_EMPTY;
+ return E_FAIL;
+
+ } catch(...) { return E_FAIL; }
+}
+
+/**
+*the method GetPreSibling is general, whatever it is descendant manage or not
+* @param varStart, the start child id of this navigation action.
+* @param pvarEndUpAt, [in,out] the end up child of this navigation action.
+* @return S_OK if successful and E_FAIL if failure.
+*/
+HRESULT CMAccessible::GetPreSibling(VARIANT varStart,VARIANT* pvarEndUpAt)
+{
+
+ try {
+ if (m_isDestroy) return S_FALSE;
+ // #CHECK#
+ if(pvarEndUpAt == nullptr)
+ {
+ return E_INVALIDARG;
+ }
+ if(varStart.vt != VT_I4)
+ {
+ pvarEndUpAt->vt = VT_EMPTY;
+ return E_INVALIDARG;
+ }
+
+ Reference<XAccessibleContext> const pRContext =
+ GetContextByXAcc(m_xAccessible.get());
+ if(pRContext.is())
+ {
+ varStart.iVal = sal_Int16(pRContext->getAccessibleIndexInParent());
+ if(m_pIParent && varStart.iVal > 0)
+ if( m_pIParent->get_accChild(varStart,&pvarEndUpAt->pdispVal) == S_OK)
+ {
+ pvarEndUpAt->vt = VT_DISPATCH;
+ return S_OK;
+ }
+ }
+ pvarEndUpAt->vt = VT_EMPTY;
+ return E_FAIL;
+
+ } catch(...) { return E_FAIL; }
+}
+
+/**
+* For IAccessible2 implementation methods
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::get_nRelations( long __RPC_FAR *nRelations)
+{
+ SolarMutexGuard g;
+
+ try {
+ if (m_isDestroy) return S_FALSE;
+
+ // #CHECK#
+ if(nRelations == nullptr)
+ {
+ return E_INVALIDARG;
+ }
+
+ *nRelations = 0;
+
+ if (!m_xContext.is())
+ return E_FAIL;
+ Reference<XAccessibleRelationSet> pRrelationSet =
+ m_xContext->getAccessibleRelationSet();
+ if(!pRrelationSet.is())
+ {
+ *nRelations = 0;
+ return S_OK;
+ }
+
+ *nRelations = pRrelationSet->getRelationCount();
+ return S_OK;
+
+ } catch(...) { return E_FAIL; }
+}
+
+COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::get_relation( long relationIndex, IAccessibleRelation __RPC_FAR *__RPC_FAR *relation)
+{
+ SolarMutexGuard g;
+
+ try {
+ if (m_isDestroy) return S_FALSE;
+ // #CHECK#
+ if(relation == nullptr)
+ {
+ return E_INVALIDARG;
+ }
+
+ if (!m_xContext.is())
+ return E_FAIL;
+
+
+ long nMax = 0;
+ get_nRelations(&nMax);
+
+ *relation = static_cast<IAccessibleRelation*>(::CoTaskMemAlloc(sizeof(IAccessibleRelation)));
+
+ // #CHECK Memory Allocation#
+ if(*relation == nullptr)
+ {
+ return E_FAIL;
+ }
+
+ if( relationIndex < nMax )
+ {
+ Reference<XAccessibleRelationSet> const pRrelationSet =
+ m_xContext->getAccessibleRelationSet();
+ if(!pRrelationSet.is())
+ {
+
+ return E_FAIL;
+ }
+
+ IAccessibleRelation* pRelation = nullptr;
+ HRESULT hr = createInstance<CAccRelation>(IID_IAccessibleRelation,
+ &pRelation);
+ if(SUCCEEDED(hr))
+ {
+ IUNOXWrapper* wrapper = nullptr;
+ hr = pRelation->QueryInterface(IID_IUNOXWrapper, reinterpret_cast<void**>(&wrapper));
+ if(SUCCEEDED(hr))
+ {
+ AccessibleRelation accRelation = pRrelationSet->getRelation(relationIndex);
+ wrapper->put_XSubInterface(
+ reinterpret_cast<hyper>(&accRelation));
+ wrapper->Release();
+ *relation = pRelation;
+ return S_OK;
+ }
+
+ }
+ }
+
+ return E_FAIL;
+
+ } catch(...) { return E_FAIL; }
+}
+
+COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::get_relations( long, IAccessibleRelation __RPC_FAR *__RPC_FAR *relation, long __RPC_FAR *nRelations)
+{
+ SolarMutexGuard g;
+
+ try {
+ if (m_isDestroy) return S_FALSE;
+
+ // #CHECK#
+ if(relation == nullptr || nRelations == nullptr)
+ {
+ return E_INVALIDARG;
+ }
+ // #CHECK XInterface#
+
+ if (!m_xContext.is())
+ return E_FAIL;
+
+ Reference<XAccessibleRelationSet> const pRrelationSet =
+ m_xContext->getAccessibleRelationSet();
+ if(!pRrelationSet.is())
+ {
+ *nRelations = 0;
+ return S_OK;
+ }
+
+ long nCount = pRrelationSet->getRelationCount();
+
+ *relation = static_cast<IAccessibleRelation*>(::CoTaskMemAlloc(nCount*sizeof(IAccessibleRelation)));
+
+ // #CHECK Memory Allocation#
+ if(*relation == nullptr)
+ {
+ return E_FAIL;
+ }
+
+ for(int i=0; i<nCount ; i++)
+ {
+ IAccessibleRelation* pRelation = nullptr;
+ HRESULT hr = createInstance<CAccRelation>(IID_IAccessibleRelation,
+ &pRelation);
+ if(SUCCEEDED(hr))
+ {
+ IUNOXWrapper* wrapper = nullptr;
+ hr = pRelation->QueryInterface(IID_IUNOXWrapper, reinterpret_cast<void**>(&wrapper));
+ if(SUCCEEDED(hr))
+ {
+ AccessibleRelation accRelation = pRrelationSet->getRelation(i);
+ wrapper->put_XSubInterface(
+ reinterpret_cast<hyper>(&accRelation));
+ wrapper->Release();
+ }
+ relation[i] = pRelation;
+ }
+ }
+
+ *nRelations = nCount;
+ return S_OK;
+
+ } catch(...) { return E_FAIL; }
+}
+
+COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::role(long __RPC_FAR *role)
+{
+ SolarMutexGuard g;
+
+ try {
+
+ (*role) = m_iRole;
+
+ return S_OK;
+
+ } catch(...) { return E_FAIL; }
+}
+
+
+COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::get_nActions(long __RPC_FAR *nActions)
+{
+ SolarMutexGuard g;
+
+ try
+ {
+ if (m_isDestroy) return S_FALSE;
+ // #CHECK#
+ if(nActions == nullptr)
+ {
+ return E_INVALIDARG;
+ }
+ *nActions = 0;
+ IAccessibleAction* pAcc = nullptr;
+ HRESULT hr = QueryInterface(IID_IAccessibleAction, reinterpret_cast<void**>(&pAcc));
+ if( hr == S_OK )
+ {
+ pAcc->nActions(nActions);
+ pAcc->Release();
+ }
+
+ return S_OK;
+ }
+ catch(...)
+ {
+ *nActions = 0;
+ return S_OK;
+ }
+}
+
+
+COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::scrollToPoint(enum IA2CoordinateType, long, long)
+{
+ return E_NOTIMPL;
+}
+
+COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::scrollTo(enum IA2ScrollType)
+{
+ return E_NOTIMPL;
+}
+
+static XAccessible* getTheParentOfMember(XAccessible* pXAcc)
+{
+ // #CHECK#
+ if(pXAcc == nullptr)
+ {
+ return nullptr;
+ }
+ Reference<XAccessibleContext> pRContext = pXAcc->getAccessibleContext();
+ Reference<XAccessibleRelationSet> pRrelationSet = pRContext->getAccessibleRelationSet();
+ sal_Int32 nRelations = pRrelationSet->getRelationCount();
+ for(sal_Int32 i=0 ; i<nRelations ; i++)
+ {
+ AccessibleRelation accRelation = pRrelationSet->getRelation(i);
+ if(accRelation.RelationType == 7)
+ {
+ Sequence< Reference< XInterface > > xTargets = accRelation.TargetSet;
+ return static_cast<XAccessible*>(xTargets[0].get());
+ }
+ }
+ return nullptr;
+}
+
+COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::get_groupPosition(long __RPC_FAR *groupLevel,long __RPC_FAR *similarItemsInGroup,long __RPC_FAR *positionInGroup)
+{
+ SolarMutexGuard g;
+
+ try {
+ if (m_isDestroy) return S_FALSE;
+ // #CHECK#
+ if(groupLevel == nullptr || similarItemsInGroup == nullptr || positionInGroup == nullptr)
+ {
+ return E_INVALIDARG;
+ }
+
+ if (!m_xAccessible.is())
+ return E_FAIL;
+
+ Reference<XAccessibleContext> const pRContext =
+ m_xAccessible->getAccessibleContext();
+ if(!pRContext.is())
+ return E_FAIL;
+ long Role = pRContext->getAccessibleRole();
+
+ *groupLevel = 0;
+ *similarItemsInGroup = 0;
+ *positionInGroup = 0;
+
+ if (Role != AccessibleRole::DOCUMENT && Role != AccessibleRole::DOCUMENT_PRESENTATION &&
+ Role != AccessibleRole::DOCUMENT_SPREADSHEET && Role != AccessibleRole::DOCUMENT_TEXT)
+ {
+ Reference< XAccessibleGroupPosition > xGroupPosition( pRContext, UNO_QUERY );
+ if ( xGroupPosition.is() )
+ {
+ Sequence< sal_Int32 > rSeq = xGroupPosition->getGroupPosition( Any( pRContext ) );
+ if (rSeq.getLength() >= 3)
+ {
+ *groupLevel = rSeq[0];
+ *similarItemsInGroup = rSeq[1];
+ *positionInGroup = rSeq[2];
+ return S_OK;
+ }
+ return S_OK;
+ }
+ }
+
+ Reference< XAccessible> pParentAcc = pRContext->getAccessibleParent();
+ if( !pParentAcc.is() )
+ {
+ return S_OK;
+ }
+
+ Reference<XAccessibleContext> pRParentContext = pParentAcc->getAccessibleContext();
+
+ if( Role == RADIO_BUTTON )
+ {
+ int index = 0;
+ int number = 0;
+ Reference<XAccessibleRelationSet> pRrelationSet = pRContext->getAccessibleRelationSet();
+ long nRel = pRrelationSet->getRelationCount();
+ for(int i=0 ; i<nRel ; i++)
+ {
+ AccessibleRelation accRelation = pRrelationSet->getRelation(i);
+ if(accRelation.RelationType == 7)
+ {
+ Sequence< Reference< XInterface > > xTargets = accRelation.TargetSet;
+
+ Reference<XInterface> pRAcc = xTargets[0];
+ for(int j=0; j<pRParentContext->getAccessibleChildCount(); j++)
+ {
+ if( getTheParentOfMember(pRParentContext->getAccessibleChild(j).get())
+ == static_cast<XAccessible*>(pRAcc.get()) &&
+ pRParentContext->getAccessibleChild(j)->getAccessibleContext()->getAccessibleRole() == RADIO_BUTTON)
+ number++;
+ if (pRParentContext->getAccessibleChild(j).get() == m_xAccessible.get())
+ index = number;
+ }
+ }
+ }
+ *groupLevel = 1;
+ *similarItemsInGroup = number;
+ *positionInGroup = index;
+ return S_OK;
+ }
+
+ else if ( COMBO_BOX == Role )
+ {
+ *groupLevel = 1;
+ *similarItemsInGroup = 0;
+ *positionInGroup = -1;
+
+ long nCount = pRContext->getAccessibleChildCount();
+ if( 2 != nCount)
+ {
+ return S_OK;
+ }
+ Reference<XAccessible> xList=pRContext->getAccessibleChild(1);
+ if (!xList.is())
+ {
+ return S_OK;
+ }
+ Reference<XAccessibleContext> xListContext(xList,UNO_QUERY);
+ if (!xListContext.is())
+ {
+ return S_OK;
+ }
+ Reference<XAccessibleSelection> xListSel(xList,UNO_QUERY);
+ if (!xListSel.is())
+ {
+ return S_OK;
+ }
+ *similarItemsInGroup = xListContext->getAccessibleChildCount();
+ if (*similarItemsInGroup > 0 )
+ {
+ try
+ {
+ Reference<XAccessible> xChild = xListSel->getSelectedAccessibleChild(0);
+ if (xChild.is())
+ {
+ Reference<XAccessibleContext> xChildContext(xChild,UNO_QUERY);
+ if (xChildContext.is())
+ {
+ *positionInGroup=xChildContext->getAccessibleIndexInParent() + 1 ;
+ return S_OK;
+ }
+ }
+ }
+ catch(...)
+ {}
+ }
+ return S_OK;
+ }
+ else if ( PAGE_TAB == Role )
+ {
+ *groupLevel = 1;
+ *similarItemsInGroup = pRParentContext->getAccessibleChildCount();
+
+ if (*similarItemsInGroup > 0 )
+ {
+ *positionInGroup=pRContext->getAccessibleIndexInParent() + 1 ;
+ }
+ else
+ {
+ *positionInGroup = -1;
+ }
+ return S_OK;
+ }
+
+ int level = 0;
+ bool isFound = false;
+ while( pParentAcc.is() && !isFound)
+ {
+ level++;
+ pRParentContext = pParentAcc->getAccessibleContext();
+ Role = pRParentContext->getAccessibleRole();
+ if( (Role == TREE) || (Role == LIST) )
+ isFound = true;
+ pParentAcc = pRParentContext->getAccessibleParent();
+ }
+
+ if( isFound )
+ {
+ Reference< XAccessible> pTempAcc = pRContext->getAccessibleParent();
+ pRParentContext = pTempAcc->getAccessibleContext();
+ *groupLevel = level;
+ *similarItemsInGroup = pRParentContext->getAccessibleChildCount();
+ *positionInGroup = pRContext->getAccessibleIndexInParent() + 1;
+ }
+ else
+ {
+ *groupLevel = 0;
+ *similarItemsInGroup = 0;
+ *positionInGroup = 0;
+ }
+ return S_OK;
+
+ } catch(...) { return E_FAIL; }
+}
+
+COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::get_extendedStates(long, BSTR __RPC_FAR *__RPC_FAR *, long __RPC_FAR *)
+{
+ return E_NOTIMPL;
+}
+
+
+COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::get_uniqueID(long __RPC_FAR *uniqueID)
+{
+ SolarMutexGuard g;
+
+ try {
+ if (m_isDestroy) return S_FALSE;
+ // #CHECK#
+ if(uniqueID == nullptr)
+ {
+ return E_INVALIDARG;
+ }
+ *uniqueID = m_dChildID;
+ return S_OK;
+
+ } catch(...) { return E_FAIL; }
+}
+
+COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::get_windowHandle(HWND __RPC_FAR *windowHandle)
+{
+ SolarMutexGuard g;
+
+ try {
+ if (m_isDestroy) return S_FALSE;
+ // #CHECK#
+ if(windowHandle == nullptr)
+ {
+ return E_INVALIDARG;
+ }
+
+ HWND nHwnd = m_hwnd;
+ IAccessible* pParent = m_pIParent;
+ while((nHwnd==nullptr) && pParent)
+ {
+ if (CMAccessible* pChild = dynamic_cast<CMAccessible*>(pParent))
+ {
+ pParent = pChild->m_pIParent;
+ nHwnd = pChild->m_hwnd;
+ }
+ else
+ pParent = nullptr;
+ }
+
+ *windowHandle = nHwnd;
+ return S_OK;
+
+ } catch(...) { return E_FAIL; }
+}
+
+/**
+* Get XAccessibleContext directly from UNO by the stored XAccessible pointer
+* @param pXAcc, UNO XAccessible object point.
+* @return XAccessibleContext*, the context of the pXAcc.
+*/
+XAccessibleContext* CMAccessible::GetContextByXAcc( XAccessible* pXAcc )
+{
+ Reference< XAccessibleContext > pRContext;
+ if( pXAcc == nullptr)
+ return nullptr;
+
+ pRContext = pXAcc->getAccessibleContext();
+ if( !pRContext.is() )
+ return nullptr;
+ return pRContext.get();
+}
+
+/**
+* Return the member variable m_pXAccessibleSelection, instead of
+* get XAccessibleSelection according to XAccessibleContext because if so,it will
+* depend on the UNO implementation code,so when COM is created, put XAccessibleSelection
+* by bridge management system
+* @return XAccessibleSelection*, the selection of the current object.
+*/
+Reference< XAccessibleSelection > CMAccessible::GetSelection()
+{
+ if (!m_xAccessible.is())
+ return nullptr;
+ Reference<XAccessibleContext> const pRContext =
+ m_xAccessible->getAccessibleContext();
+ if(pRContext.is())
+ {
+ Reference< XAccessibleSelection > pRSelection(pRContext,UNO_QUERY);
+ return pRSelection;
+ }
+ return nullptr;
+}
+
+/**
+* Select one XAccessible item, for accSelect implementation
+* @param pItem, the item should be selected.
+* @return S_OK if successful.
+*/
+HRESULT CMAccessible::SelectChild(XAccessible* pItem)
+{
+
+ try {
+ if (m_isDestroy) return S_FALSE;
+ XAccessibleContext* pParentContext = GetContextByXAcc(m_xAccessible.get());
+ XAccessibleContext* pContext = GetContextByXAcc( pItem );
+ if( pParentContext == nullptr || pContext == nullptr )
+ return E_FAIL;
+
+ Reference< XAccessibleSelection > pRSelection = GetSelection();
+ if( !pRSelection.is() )
+ return E_FAIL;
+ long Index = pContext->getAccessibleIndexInParent();
+ pRSelection->selectAccessibleChild( Index );
+ return S_OK;
+
+ } catch(...) { return E_FAIL; }
+}
+
+/**
+* Deselect one XAccessible item, for accSelect implementation
+* @param pItem, the item should be deselected.
+* @return S_OK if successful.
+*/
+HRESULT CMAccessible::DeSelectChild(XAccessible* pItem)
+{
+
+ try {
+ if (m_isDestroy) return S_FALSE;
+ XAccessibleContext* pParentContext = GetContextByXAcc(m_xAccessible.get());
+ ;
+ XAccessibleContext* pContext = GetContextByXAcc( pItem );
+ if( pParentContext == nullptr || pContext == nullptr )
+ return E_INVALIDARG;
+
+ Reference< XAccessibleSelection > pRSelection = GetSelection();
+ if( !pRSelection.is() )
+ return E_FAIL;
+ long Index = pContext->getAccessibleIndexInParent();
+ pRSelection->deselectAccessibleChild( Index );
+
+ return S_OK;
+
+ } catch(...) { return E_FAIL; }
+}
+
+/**
+* Select multiple XAccessible items,for implementation of accSelect
+* @param pItem, the items should be selected.
+* @param size, the size of the items.
+* @return S_OK if successful.
+*/
+HRESULT CMAccessible::SelectMultipleChidren( XAccessible** pItem,int size )
+{
+
+ try {
+ if (m_isDestroy) return S_FALSE;
+ // #CHECK#
+ if(pItem == nullptr)
+ {
+ return E_INVALIDARG;
+ }
+ for(int index = 0;index < size;index++)
+ {
+ SelectChild( pItem[index] );
+ }
+ return S_OK;
+
+ } catch(...) { return E_FAIL; }
+}
+
+/**
+* Deselect multiple XAccessible items,for implementation of accSelect
+* @param pItem, the items should be selected.
+* @param size, the size of the items.
+* @return S_OK if successful.
+*/
+HRESULT CMAccessible::DeSelectMultipleChildren( XAccessible** pItem,int size )
+{
+
+ try {
+ if (m_isDestroy) return S_FALSE;
+ // #CHECK#
+ if(pItem == nullptr)
+ {
+ return E_INVALIDARG;
+ }
+ for(int index = 0;index < size;index++)
+ {
+ DeSelectChild( pItem[index] );
+ }
+ return S_OK;
+
+ } catch(...) { return E_FAIL; }
+}
+
+/**
+* When COM is created, UNO set XAccessible pointer to it
+* in order to COM can operate UNO information
+* @param pXAcc, the XAccessible object of current object.
+* @return S_OK if successful.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::SetXAccessible(hyper pXAcc)
+{
+ // internal IMAccessible - no mutex meeded
+
+ m_xAccessible = reinterpret_cast<XAccessible*>(pXAcc);
+ m_pEnumVar->PutSelection(/*XAccessibleSelection*/
+ reinterpret_cast<hyper>(m_xAccessible.get()));
+
+ m_xContext = m_xAccessible->getAccessibleContext();
+
+ return S_OK;
+}
+
+/**
+* accSelect method has many optional flags, needs to process comprehensively
+* Mozilla and Microsoft do not implement SELFLAG_EXTENDSELECTION flag.
+* The implementation of this flag is a little trouble-shooting,so we also
+* do not implement it now
+* @param flagsSelect, the selection flag of the select action.
+* @param varChild, the child object pointer of current action.
+* @return S_OK if successful.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::accSelect(long flagsSelect, VARIANT varChild)
+{
+ SolarMutexGuard g;
+
+ try {
+ if (m_isDestroy) return S_FALSE;
+ if( (flagsSelect&SELFLAG_ADDSELECTION) &&
+ (SELFLAG_REMOVESELECTION&flagsSelect) )
+ return E_INVALIDARG;
+
+ if ( (flagsSelect&SELFLAG_TAKESELECTION) &&
+ (
+ (flagsSelect&SELFLAG_ADDSELECTION) ||
+ (flagsSelect&SELFLAG_REMOVESELECTION) ||
+ (flagsSelect&SELFLAG_EXTENDSELECTION )
+ )
+ )
+ return E_INVALIDARG;
+
+ if ( varChild.vt != VT_I4 )
+ return E_INVALIDARG;
+
+ IMAccessible* pSelectAcc;
+ if( varChild.lVal == CHILDID_SELF )
+ {
+ pSelectAcc = this;
+ pSelectAcc->AddRef();
+ }
+ else
+ {
+ pSelectAcc = GetChildInterface(varChild.lVal);
+ }
+
+ if( pSelectAcc == nullptr )
+ return E_INVALIDARG;
+
+ if( flagsSelect&SELFLAG_TAKEFOCUS )
+ {
+ union {
+ XAccessible* pTempUNO;
+ hyper nHyper = 0;
+ };
+ pSelectAcc->GetUNOInterface(&nHyper);
+
+ if( pTempUNO == nullptr )
+ return 0;
+
+ Reference<XAccessibleContext> pRContext = pTempUNO->getAccessibleContext();
+ Reference< XAccessibleComponent > pRComponent(pRContext,UNO_QUERY);
+ Reference< XAccessible > pRParentXAcc = pRContext->getAccessibleParent();
+ Reference< XAccessibleContext > pRParentContext = pRParentXAcc->getAccessibleContext();
+ Reference< XAccessibleComponent > pRParentComponent(pRParentContext,UNO_QUERY);
+ Reference< XAccessibleSelection > pRParentSelection(pRParentContext,UNO_QUERY);
+
+
+ pRComponent->grabFocus();
+
+ if( flagsSelect & SELFLAG_TAKESELECTION )
+ {
+ pRParentSelection->clearAccessibleSelection();
+ pRParentSelection->selectAccessibleChild( pRContext->getAccessibleIndexInParent() );
+ }
+
+ if( flagsSelect & SELFLAG_ADDSELECTION )
+ {
+ pRParentSelection->selectAccessibleChild( pRContext->getAccessibleIndexInParent() );
+ }
+
+ if( flagsSelect & SELFLAG_REMOVESELECTION )
+ {
+ pRParentSelection->deselectAccessibleChild( pRContext->getAccessibleIndexInParent() );
+ }
+
+ if( flagsSelect & SELFLAG_EXTENDSELECTION )
+ {
+ long indexInParrent = pRContext->getAccessibleIndexInParent();
+
+ if( pRParentSelection->isAccessibleChildSelected( indexInParrent + 1 ) ||
+ pRParentSelection->isAccessibleChildSelected( indexInParrent - 1 ) )
+ {
+ pRParentSelection->selectAccessibleChild( indexInParrent );
+ }
+ }
+
+ }
+
+ pSelectAcc->Release();
+ return S_OK;
+
+ } catch(...) { return E_FAIL; }
+}
+
+/**
+* Return XAccessible interface pointer when needed
+* @param pXAcc, [in, out] the Uno interface of the current object.
+* @return S_OK if successful.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::GetUNOInterface(hyper * pXAcc)
+{
+ // internal IMAccessible - no mutex meeded
+
+ if(pXAcc == nullptr)
+ return E_INVALIDARG;
+
+ *pXAcc = reinterpret_cast<hyper>(m_xAccessible.get());
+ return S_OK;
+}
+
+/**
+* Helper method for Implementation of get_accDefaultAction
+* @param pAction, the default action point of the current object.
+* @return S_OK if successful.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::SetDefaultAction(hyper pAction)
+{
+ // internal IMAccessible - no mutex meeded
+
+ m_xAction = reinterpret_cast<XAccessibleAction*>(pAction);
+ return S_OK;
+}
+
+/**
+* This method is called when AT open some UI elements initially
+* the UI element takes the default action defined here
+* @param varChild, the child id of the defaultaction.
+* @param pszDefaultAction,[in/out] the description of the current action.
+* @return S_OK if successful.
+*/
+COM_DECLSPEC_NOTHROW HRESULT STDMETHODCALLTYPE CMAccessible::get_accDefaultAction(VARIANT varChild, BSTR *pszDefaultAction)
+{
+ SolarMutexGuard g;
+
+ try {
+ if (m_isDestroy) return S_FALSE;
+ // #CHECK#
+ if(pszDefaultAction == nullptr)
+ {
+ return E_INVALIDARG;
+ }
+ if(varChild.vt==VT_I4)
+ {
+ if(varChild.lVal==CHILDID_SELF)
+ {
+ if (!m_xAction.is())
+ return DISP_E_MEMBERNOTFOUND;
+ SysFreeString(*pszDefaultAction);
+ *pszDefaultAction = SysAllocString(m_pszActionDescription);
+ return S_OK;
+ }
+
+ long lVal = varChild.lVal;
+ varChild.lVal = CHILDID_SELF;
+ IMAccessible *pChild = this->GetChildInterface(lVal);
+ if(!pChild)
+ return E_FAIL;
+ return pChild->get_accDefaultAction(varChild,pszDefaultAction);
+ }
+ return S_FALSE;
+
+ } catch(...) { return E_FAIL; }
+}
+
+/**
+* AT call this method to operate application
+* @param varChild, the child id of the action object.
+* @return S_OK if successful.
+*/
+COM_DECLSPEC_NOTHROW HRESULT STDMETHODCALLTYPE CMAccessible::accDoDefaultAction(VARIANT varChild)
+{
+ SolarMutexGuard g;
+
+ try {
+ if (m_isDestroy) return S_FALSE;
+ if( varChild.vt != VT_I4 )
+ return E_INVALIDARG;
+ if (!m_xAction.is())
+ return E_FAIL;
+ if (m_xAction->getAccessibleActionCount() == 0)
+ return E_FAIL;
+
+ if(varChild.lVal==CHILDID_SELF)
+ {
+ if (m_xAction->getAccessibleActionCount() > 0)
+ m_xAction->doAccessibleAction(0);
+ return S_OK;
+ }
+
+ long lVal = varChild.lVal;
+ varChild.lVal = CHILDID_SELF;
+ IMAccessible *pChild = this->GetChildInterface(lVal);
+ if(!pChild)
+ return E_FAIL;
+ return pChild->accDoDefaultAction( varChild );
+
+ } catch(...) { return E_FAIL; }
+}
+
+/**
+* UNO set description information for action to COM.
+* @param szAction, the action description of the current object.
+* @return S_OK if successful.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::Put_ActionDescription( const OLECHAR* szAction)
+{
+ // internal IMAccessible - no mutex meeded
+
+ try {
+ if (m_isDestroy) return S_FALSE;
+ // #CHECK#
+ if(szAction == nullptr)
+ {
+ return E_INVALIDARG;
+ }
+ SysFreeString(m_pszActionDescription );
+ m_pszActionDescription = SysAllocString( szAction );
+ return S_OK;
+
+ } catch(...) { return E_FAIL; }
+}
+
+bool CMAccessible::GetXInterfaceFromXAccessible(XAccessible* pXAcc, XInterface** ppXI, XInterfaceType eType)
+{
+ switch(eType)
+ {
+ case XInterfaceType::XI_COMPONENT:
+ return queryXInterface<XAccessibleComponent>(pXAcc, ppXI);
+ case XInterfaceType::XI_TEXT:
+ return queryXInterface<XAccessibleText>(pXAcc, ppXI);
+ case XInterfaceType::XI_EDITABLETEXT:
+ return queryXInterface<XAccessibleEditableText>(pXAcc, ppXI);
+ case XInterfaceType::XI_TABLE:
+ return queryXInterface<XAccessibleTable>(pXAcc, ppXI);
+ case XInterfaceType::XI_TABLECELL:
+ // needs specific handling, since there's no XInterface for table cells
+ return queryTableCell(pXAcc, ppXI);
+ case XInterfaceType::XI_SELECTION:
+ return queryXInterface<XAccessibleSelection>(pXAcc, ppXI);
+ case XInterfaceType::XI_EXTENDEDCOMP:
+ return queryXInterface<XAccessibleExtendedComponent>(pXAcc, ppXI);
+ case XInterfaceType::XI_KEYBINDING:
+ return queryXInterface<XAccessibleKeyBinding>(pXAcc, ppXI);
+ case XInterfaceType::XI_ACTION:
+ return queryXInterface<XAccessibleAction>(pXAcc, ppXI);
+ case XInterfaceType::XI_VALUE:
+ return queryXInterface<XAccessibleValue>(pXAcc, ppXI);
+ case XInterfaceType::XI_HYPERTEXT:
+ return queryXInterface<XAccessibleHypertext>(pXAcc, ppXI);
+ case XInterfaceType::XI_HYPERLINK:
+ return queryXInterface<XAccessibleHyperlink>(pXAcc, ppXI);
+ case XInterfaceType::XI_IMAGE:
+ return queryXInterface<XAccessibleImage>(pXAcc, ppXI);
+ default:
+ return false;
+ }
+}
+
+template<typename T> static HRESULT
+createAggInstance(CMAccessible &rOuter, void ** ppvObject)
+{
+ // Note: CComAggObject has special handling for IUnknown - must
+ // query for that when creating it! Otherwise we get a T member of it
+ // which will redirect QueryInterface back to CMAccessible infinitely.
+ // (CComAggObject has its own ref-count too which is not a problem
+ // since it is inserted in m_containedObjects.)
+ return CComCreator< CComAggObject<T> >::CreateInstance(
+ rOuter.GetControllingUnknown(), IID_IUnknown, ppvObject);
+}
+
+typedef HRESULT (AggCreatorFunc)(CMAccessible &, void **);
+
+namespace {
+
+struct AggMapEntry
+{
+ const IID* piid;
+ AggCreatorFunc* pfnCreateInstance;
+ const XInterfaceType eXInterfaceType;
+};
+
+}
+
+static AggMapEntry g_CMAccessible_AggMap[] = {
+ { &IID_IAccessibleComponent, &createAggInstance<CAccComponent>, XInterfaceType::XI_COMPONENT },
+ { &IID_IAccessibleText, &createAggInstance<CAccText>, XInterfaceType::XI_TEXT },
+ { &IID_IAccessibleEditableText, &createAggInstance<CAccEditableText>, XInterfaceType::XI_EDITABLETEXT },
+ { &IID_IAccessibleImage, &createAggInstance<CAccImage>, XInterfaceType::XI_IMAGE },
+ { &IID_IAccessibleTable, &createAggInstance<CAccTable>, XInterfaceType::XI_TABLE },
+ { &IID_IAccessibleTable2, &createAggInstance<CAccTable>, XInterfaceType::XI_TABLE },
+ { &IID_IAccessibleTableCell, &createAggInstance<CAccTableCell>, XInterfaceType::XI_TABLECELL },
+ { &IID_IAccessibleAction, &createAggInstance<CAccAction>, XInterfaceType::XI_ACTION },
+ { &IID_IAccessibleValue, &createAggInstance<CAccValue>, XInterfaceType::XI_VALUE },
+ { &IID_IAccessibleHypertext, &createAggInstance<CAccHypertext>, XInterfaceType::XI_HYPERTEXT },
+ { &IID_IAccessibleHyperlink, &createAggInstance<CAccHyperLink>, XInterfaceType::XI_HYPERLINK }
+};
+
+
+HRESULT WINAPI CMAccessible::SmartQI(void* /*pv*/, REFIID iid, void** ppvObject)
+{
+ try {
+
+ if (m_isDestroy) return S_FALSE;
+ if (InlineIsEqualGUID(iid,IID_IAccIdentity) ||
+ InlineIsEqualGUID(iid,IID_IStdMarshalInfo) ||
+ InlineIsEqualGUID(iid,IID_IMarshal) ||
+ InlineIsEqualGUID(iid,IID_IExternalConnection)||
+ InlineIsEqualGUID(iid,IID_IOleWindow))
+ {
+ return E_FAIL;
+ }
+
+ for (const AggMapEntry& rEntry : g_CMAccessible_AggMap)
+ {
+ if (InlineIsEqualGUID(iid, *rEntry.piid))
+ {
+ SolarMutexGuard g;
+
+ XInterface* pXI = nullptr;
+ bool bFound = GetXInterfaceFromXAccessible(m_xAccessible.get(),
+ &pXI, rEntry.eXInterfaceType);
+ if(!bFound)
+ {
+ return E_FAIL;
+ }
+
+ XGUIDToComObjHash::iterator pIndTemp = m_containedObjects.find( iid );
+ if ( pIndTemp != m_containedObjects.end() )
+ {
+ return pIndTemp->second.p->QueryInterface( iid, ppvObject );
+ }
+ else
+ {
+ HRESULT hr = rEntry.pfnCreateInstance(*this, ppvObject);
+ assert(hr == S_OK);
+ if(hr == S_OK)
+ {
+ m_containedObjects.emplace(*rEntry.piid, static_cast<IUnknown*>(*ppvObject));
+ IUNOXWrapper* wrapper = nullptr;
+ static_cast<IUnknown*>(*ppvObject)->QueryInterface(IID_IUNOXWrapper, reinterpret_cast<void**>(&wrapper));
+ if(wrapper)
+ {
+ wrapper->put_XInterface(
+ reinterpret_cast<hyper>(m_xAccessible.get()));
+ wrapper->Release();
+ }
+ return S_OK;
+ }
+ }
+ return E_FAIL;
+ }
+ }
+ return E_FAIL;
+
+ } catch(...) { return E_FAIL; }
+}
+
+bool CMAccessible::get_IAccessibleFromXAccessible(XAccessible* pXAcc, IAccessible** ppIA)
+{
+ try
+ {
+ // #CHECK#
+ if(ppIA == nullptr)
+ {
+ return false;
+ }
+ bool isGet = false;
+ if(g_pAgent)
+ isGet = g_pAgent->GetIAccessibleFromXAccessible(pXAcc, ppIA);
+
+ return isGet;
+ }
+ catch(...)
+ {
+ return false;
+ }
+}
+
+OUString CMAccessible::get_StringFromAny(Any const & pAny)
+{
+ switch(pAny.getValueTypeClass())
+ {
+ case TypeClass_CHAR:
+ {
+ sal_Int8 val;
+ pAny >>= val;
+ return OUString::number(val);
+ }
+ case TypeClass_BOOLEAN:
+ {
+ bool val;
+ pAny >>= val;
+ return OUString::number(int(val));
+ }
+ case TypeClass_BYTE:
+ {
+ sal_Int8 val;
+ pAny >>= val;
+ return OUString::number(val);
+ }
+ case TypeClass_SHORT:
+ {
+ sal_Int16 val;
+ pAny >>= val;
+ return OUString::number(val);
+ }
+ case TypeClass_UNSIGNED_SHORT:
+ {
+ sal_uInt16 val;
+ pAny >>= val;
+ return OUString::number(val);
+ }
+ case TypeClass_LONG:
+ {
+ sal_Int32 val;
+ pAny >>= val;
+ return OUString::number(val);
+ }
+ case TypeClass_UNSIGNED_LONG:
+ {
+ sal_uInt32 val;
+ pAny >>= val;
+ return OUString::number(val);
+ }
+ case TypeClass_FLOAT:
+ {
+ float val;
+ pAny >>= val;
+ return OUString::number(val);
+ }
+ case TypeClass_DOUBLE:
+ {
+ double val;
+ pAny >>= val;
+ return OUString::number(val);
+ }
+ case TypeClass_STRING:
+ {
+ OUString val;
+ pAny >>= val;
+ return val;
+ }
+ case TypeClass_SEQUENCE:
+ {
+ if(pAny.getValueType() == cppu::UnoType<Sequence< OUString >>::get())
+ {
+ Sequence < OUString > val;
+ pAny >>= val;
+
+ OUStringBuffer pString;
+
+ for (const OUString& rElem : val)
+ pString.append(rElem);
+
+ return pString.makeStringAndClear();
+ }
+ else if (pAny.getValueType() == cppu::UnoType<Sequence< css::style::TabStop >>::get())
+ {
+ Sequence < css::style::TabStop > val;
+ pAny >>= val;
+
+ OUStringBuffer buf;
+ for (const css::style::TabStop& rSingleVal : val)
+ {
+ buf.append("Position=");
+ buf.append(rSingleVal.Position);
+ buf.append(",TabAlign=");
+ buf.append(sal_Int32(rSingleVal.Alignment));
+ buf.append(",");
+
+ buf.append("DecimalChar=");
+ if (rSingleVal.DecimalChar==';' || rSingleVal.DecimalChar == ':' || rSingleVal.DecimalChar == ',' ||
+ rSingleVal.DecimalChar == '=' || rSingleVal.DecimalChar == '\\')
+ buf.append('\\');
+ buf.append(rSingleVal.DecimalChar);
+ buf.append(",");
+
+ buf.append("FillChar=");
+ if (rSingleVal.FillChar==';' || rSingleVal.FillChar == ':' || rSingleVal.FillChar == ',' ||
+ rSingleVal.FillChar == '=' || rSingleVal.FillChar == '\\')
+ buf.append('\\');
+ buf.append(rSingleVal.FillChar);
+ buf.append(",");
+ }
+ return buf.makeStringAndClear();
+ }
+ break;
+ }
+ case TypeClass_ENUM:
+ {
+ if (pAny.getValueType() == cppu::UnoType<css::awt::FontSlant>::get())
+ {
+ css::awt::FontSlant val;
+ pAny >>= val;
+ return OUString::number(sal_Int32(val));
+ }
+ break;
+ }
+ case TypeClass_STRUCT:
+ {
+ if (pAny.getValueType() == cppu::UnoType<css::style::LineSpacing>::get())
+ {
+ css::style::LineSpacing val;
+ pAny >>= val;
+ return "Mode=" + OUString::number(val.Mode) + ",Height="
+ + OUString::number(val.Height) + ",";
+ }
+ else if (pAny.getValueType() == cppu::UnoType<css::accessibility::TextSegment>::get())
+ {
+ css::accessibility::TextSegment val;
+ pAny >>= val;
+ return val.SegmentText;
+ }
+ break;
+ }
+ case TypeClass_VOID:
+ case TypeClass_HYPER:
+ case TypeClass_UNSIGNED_HYPER:
+ case TypeClass_TYPE:
+ case TypeClass_ANY:
+ case TypeClass_TYPEDEF:
+ case TypeClass_EXCEPTION:
+ case TypeClass_INTERFACE:
+ case TypeClass_SERVICE:
+ case TypeClass_MODULE:
+ case TypeClass_INTERFACE_METHOD:
+ case TypeClass_INTERFACE_ATTRIBUTE:
+ case TypeClass_UNKNOWN:
+ case TypeClass_PROPERTY:
+ case TypeClass_CONSTANT:
+ case TypeClass_CONSTANTS:
+ case TypeClass_SINGLETON:
+ break;
+ default:
+ break;
+ }
+ return OUString();
+}
+
+OUString CMAccessible::get_String4Numbering(const Any& pAny, sal_Int16 numberingLevel,std::u16string_view numberingPrefix)
+{
+ Reference< css::container::XIndexReplace > pXIndex;
+ if((pAny>>=pXIndex) && (numberingLevel !=-1))//numbering level is -1,means invalid value
+ {
+ Any aAny = pXIndex->getByIndex(numberingLevel);
+ Sequence< css::beans::PropertyValue > aProps;
+ aAny >>= aProps;
+ OUStringBuffer buf("Numbering:NumberingLevel=");
+ buf.append(sal_Int32(numberingLevel));
+ buf.append(',');
+ for (const css::beans::PropertyValue& rProp : aProps)
+ {
+ if( (rProp.Name == "BulletChar" ) ||
+ (rProp.Name == "NumberingType" ))
+ {
+ buf.append(rProp.Name);
+ buf.append('=');
+ auto const pTemp = CMAccessible::get_StringFromAny(rProp.Value);
+ buf.append(pTemp);
+ buf.append(',');
+
+ if (rProp.Name == "NumberingType" && !numberingPrefix.empty())
+ {
+ buf.append("NumberingPrefix=");
+ buf.append(numberingPrefix);
+ }
+ }
+ }
+ return buf.makeStringAndClear();
+ }
+
+ //Because now have three types numbering level:
+ //1.real numbering list,numbering level>=0 and numbering Rule !=NULL;
+ //2.common paragraph, numbering level >=0, and numbering Rule == NULL;
+ //3.TOC paragraph, numbering level >0, and numbering Rule ==NULL;
+ // IAText:numberinglevel base on 0, but TOC's level base on 1,
+ // so NumberingLevel value will be decreased 1 in bridge code.
+ else if(numberingLevel >0)
+ {
+ return "Numbering:NumberingLevel=" + OUString::number(numberingLevel-1) + ",NumberingType=4,NumberingPrefix=,";
+ }
+ else
+ {
+ return "Numbering:";
+ }
+}
+
+void CMAccessible::ConvertAnyToVariant(const css::uno::Any &rAnyVal, VARIANT *pvData)
+{
+ if(rAnyVal.hasValue())
+ {
+ // Clear VARIANT variable.
+ VariantClear(pvData);
+
+ // Set value according to value type.
+ switch(rAnyVal.getValueTypeClass())
+ {
+ case TypeClass_CHAR:
+ pvData->vt = VT_UI1;
+ memcpy(&pvData->bVal, rAnyVal.getValue(), sizeof(char));
+ break;
+
+ case TypeClass_BOOLEAN:
+ {
+ bool bBoolean(false);
+ rAnyVal >>= bBoolean;
+ pvData->vt = VT_BOOL;
+ pvData->boolVal = VARIANT_BOOL(bBoolean); // boolVal is a VARIANT_BOOL, a 16bit field
+ break;
+ }
+ case TypeClass_BYTE:
+ pvData->vt = VT_UI1;
+ memcpy(&pvData->bVal, rAnyVal.getValue(), sizeof(sal_Int8));
+ break;
+
+ case TypeClass_SHORT:
+ pvData->vt = VT_I2;
+ memcpy(&pvData->iVal, rAnyVal.getValue(), sizeof(sal_Int16));
+ break;
+
+ case TypeClass_UNSIGNED_SHORT:
+ pvData->vt = VT_I2;
+ memcpy(&pvData->iVal, rAnyVal.getValue(), sizeof(sal_uInt16));
+ break;
+
+ case TypeClass_LONG:
+ pvData->vt = VT_I4;
+ memcpy(&pvData->lVal, rAnyVal.getValue(), sizeof(sal_Int32));
+ break;
+
+ case TypeClass_UNSIGNED_LONG:
+ pvData->vt = VT_I4;
+ memcpy(&pvData->lVal, rAnyVal.getValue(), sizeof(sal_uInt32));
+ break;
+
+ case TypeClass_FLOAT:
+ pvData->vt = VT_R4;
+ memcpy(&pvData->fltVal, rAnyVal.getValue(), sizeof(float));
+ break;
+
+ case TypeClass_DOUBLE:
+ pvData->vt = VT_R8;
+ memcpy(&pvData->dblVal, rAnyVal.getValue(), sizeof(double));
+ break;
+
+ case TypeClass_STRING:
+ {
+ pvData->vt = VT_BSTR;
+ OUString val;
+ rAnyVal >>= val;
+ pvData->bstrVal = SysAllocString(o3tl::toW(val.getStr()));
+ break;
+ }
+
+ case TypeClass_VOID:
+ case TypeClass_HYPER:
+ case TypeClass_UNSIGNED_HYPER:
+ case TypeClass_TYPE:
+ case TypeClass_ANY:
+ case TypeClass_ENUM:
+ case TypeClass_TYPEDEF:
+ case TypeClass_STRUCT:
+ case TypeClass_EXCEPTION:
+ case TypeClass_SEQUENCE:
+ case TypeClass_INTERFACE:
+ {
+ Reference< XAccessible > pXAcc;
+ if(rAnyVal >>= pXAcc)
+ {
+ if(pXAcc.is())
+ {
+ IAccessible* pIAcc = nullptr;
+ get_IAccessibleFromXAccessible(pXAcc.get(), &pIAcc);
+ if(pIAcc == nullptr)
+ {
+ Reference< XAccessibleContext > pXAccContext = pXAcc->getAccessibleContext();
+ g_pAgent->InsertAccObj(pXAcc.get(),pXAccContext->getAccessibleParent().get());
+ get_IAccessibleFromXAccessible(pXAcc.get(), &pIAcc);
+ }
+ if(pIAcc)
+ {
+ pIAcc->AddRef();
+
+ pvData->vt = VT_UNKNOWN;
+ pvData->pdispVal = pIAcc;
+ break;
+ }
+ }
+ }
+ [[fallthrough]];
+ }
+ case TypeClass_SERVICE:
+ case TypeClass_MODULE:
+ case TypeClass_INTERFACE_METHOD:
+ case TypeClass_INTERFACE_ATTRIBUTE:
+ case TypeClass_UNKNOWN:
+ case TypeClass_PROPERTY:
+ case TypeClass_CONSTANT:
+ case TypeClass_CONSTANTS:
+ case TypeClass_SINGLETON:
+ case TypeClass::TypeClass_MAKE_FIXED_SIZE:
+ // Output the type string, if there is other uno value type.
+ pvData->vt = VT_BSTR;
+ pvData->bstrVal = SysAllocString(o3tl::toW(rAnyVal.getValueTypeName().getStr()));
+ break;
+
+ default:
+ break;
+ }
+ }
+ else
+ {
+ VariantClear(pvData);
+ }
+}
+
+COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::get_states(AccessibleStates __RPC_FAR *states)
+{
+ SolarMutexGuard g;
+
+ try {
+ if (m_isDestroy) return S_FALSE;
+
+ if (!m_xContext.is())
+ return E_FAIL;
+
+ Reference<XAccessibleStateSet> const pRStateSet =
+ m_xContext->getAccessibleStateSet();
+ if(!pRStateSet.is())
+ {
+ return S_OK;
+ }
+ Sequence<short> pStates = pRStateSet->getStates();
+
+
+ long count = pStates.getLength() ;
+ *states = 0x0;
+ for( int i = 0; i < count; i++ )
+ {
+ for( std::size_t j = 0; j < SAL_N_ELEMENTS(UNO_STATES); j++ )
+ {
+ if( pStates[i] == UNO_STATES[j] )
+ {
+ *states |= IA2_STATES[j];
+ break;
+ }
+ }
+ }
+ return S_OK;
+
+
+ } catch(...) { return E_FAIL; }
+}
+
+// return the UNO roles
+COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::get_extendedRole(BSTR __RPC_FAR *)
+{
+ return E_NOTIMPL;
+}
+
+COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::get_localizedExtendedRole(BSTR __RPC_FAR *)
+{
+ return E_NOTIMPL;
+}
+
+COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::get_nExtendedStates(long __RPC_FAR *)
+{
+ return E_NOTIMPL;
+}
+
+
+COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::get_localizedExtendedStates(long, BSTR __RPC_FAR *__RPC_FAR *, long __RPC_FAR *)
+{
+ return E_NOTIMPL;
+}
+
+
+COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::get_indexInParent(long __RPC_FAR *accParentIndex)
+{
+ try {
+ if (m_isDestroy) return S_FALSE;
+ // #CHECK#
+ if(accParentIndex == nullptr)
+ return E_INVALIDARG;
+
+ if (!m_xContext.is())
+ return E_FAIL;
+
+ *accParentIndex = m_xContext->getAccessibleIndexInParent();
+ return S_OK;
+
+
+ } catch(...) { return E_FAIL; }
+}
+COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::get_locale( IA2Locale __RPC_FAR *locale )
+{
+ try {
+ if (m_isDestroy) return S_FALSE;
+ if(locale == nullptr)
+ return E_INVALIDARG;
+
+ if (!m_xContext.is())
+ return E_FAIL;
+
+ css::lang::Locale unoLoc = m_xContext->getLocale();
+ locale->language = SysAllocString(o3tl::toW(unoLoc.Language.getStr()));
+ locale->country = SysAllocString(o3tl::toW(unoLoc.Country.getStr()));
+ locale->variant = SysAllocString(o3tl::toW(unoLoc.Variant.getStr()));
+
+ return S_OK;
+
+ } catch(...) { return E_FAIL; }
+}
+
+COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::get_appName(BSTR __RPC_FAR *name)
+{
+ SolarMutexGuard g;
+
+ try {
+ if (m_isDestroy) return S_FALSE;
+ if(name == nullptr)
+ return E_INVALIDARG;
+
+ *name = SysAllocString(OLESTR("Hannover"));
+ return S_OK;
+ } catch(...) { return E_FAIL; }
+}
+COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::get_appVersion(BSTR __RPC_FAR *version)
+{
+ SolarMutexGuard g;
+
+ try {
+ if (m_isDestroy) return S_FALSE;
+ if(version == nullptr)
+ return E_INVALIDARG;
+ *version=SysAllocString(OLESTR("3.0"));
+ return S_OK;
+ } catch(...) { return E_FAIL; }
+}
+COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::get_toolkitName(BSTR __RPC_FAR *name)
+{
+ SolarMutexGuard g;
+
+ try {
+ if (m_isDestroy) return S_FALSE;
+ if(name == nullptr)
+ return E_INVALIDARG;
+ *name = SysAllocString(OLESTR(" "));
+ return S_OK;
+ } catch(...) { return E_FAIL; }
+}
+COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::get_toolkitVersion(BSTR __RPC_FAR *version)
+{
+ SolarMutexGuard g;
+
+ try {
+ if (m_isDestroy) return S_FALSE;
+ if(version == nullptr)
+ return E_INVALIDARG;
+ *version = SysAllocString(OLESTR(" "));
+ return S_OK;
+ } catch(...) { return E_FAIL; }
+}
+
+
+COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::get_attributes(/*[out]*/ BSTR *pAttr)
+{
+ SolarMutexGuard g;
+
+ try {
+ if (m_isDestroy) return S_FALSE;
+
+ if (!m_xAccessible.is())
+ return E_FAIL;
+
+ Reference<XAccessibleContext> pRContext = m_xAccessible->getAccessibleContext();
+ if( !pRContext.is() )
+ {
+ return E_FAIL;
+ }
+ Reference<XAccessibleExtendedAttributes> pRXI(pRContext,UNO_QUERY);
+ if( !pRXI.is() )
+ return E_FAIL;
+ else
+ {
+ css::uno::Reference<css::accessibility::XAccessibleExtendedAttributes> pRXAttr;
+ pRXAttr = pRXI.get();
+ css::uno::Any anyVal = pRXAttr->getExtendedAttributes();
+
+ OUString val;
+ anyVal >>= val;
+
+ if(*pAttr)
+ SysFreeString(*pAttr);
+ *pAttr = SysAllocString(o3tl::toW(val.getStr()));
+
+ return S_OK;
+ }
+ } catch(...) { return E_FAIL; }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/winaccessibility/source/UAccCOM/MAccessible.h b/winaccessibility/source/UAccCOM/MAccessible.h
new file mode 100644
index 000000000..5d18d74ab
--- /dev/null
+++ b/winaccessibility/source/UAccCOM/MAccessible.h
@@ -0,0 +1,242 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include "stdafx.h"
+#include "Resource.h" // main symbols
+#include <map>
+#include <string_view>
+#include <com/sun/star/accessibility/XAccessible.hpp>
+#include <com/sun/star/accessibility/XAccessibleSelection.hpp>
+#include <com/sun/star/accessibility/XAccessibleAction.hpp>
+#include <AccObjectManagerAgent.hxx>
+#include "EnumVariant.h"
+#include "acccommon.h"
+#include <rtl/ustring.hxx>
+
+namespace {
+enum class XInterfaceType;
+}
+
+/**
+ *This class implements IMAccessible interface, which inherits from IAccessible2, and
+ *in turn inherits from IAccessible. So its methods include the methods defined only in
+ *IAccessible, plus the methods defined only in IAccessible2, plus the methods defined
+ *only in IMAccessible.
+ */
+class ATL_NO_VTABLE CMAccessible :
+ public CComObjectRoot,
+ public CComCoClass<CMAccessible, &CLSID_MAccessible>,
+ public IDispatchImpl<IMAccessible, &IID_IMAccessible, &LIBID_UACCCOMLib>,
+ public IServiceProvider,
+ public IAccessibleApplication
+{
+ typedef ::std::map<const GUID, CComPtr<IUnknown>, ltComp> XGUIDToComObjHash;
+
+public:
+ CMAccessible();
+ virtual ~CMAccessible();
+
+ DECLARE_NO_REGISTRY()
+
+ DECLARE_GET_CONTROLLING_UNKNOWN()
+
+ DECLARE_PROTECT_FINAL_CONSTRUCT()
+
+ BEGIN_COM_MAP(CMAccessible)
+ COM_INTERFACE_ENTRY(IMAccessible)
+ COM_INTERFACE_ENTRY(IAccessible)
+ COM_INTERFACE_ENTRY(IAccessible2)
+ COM_INTERFACE_ENTRY(IDispatch)
+ COM_INTERFACE_ENTRY(IAccessibleApplication)
+ COM_INTERFACE_ENTRY(IServiceProvider)
+ COM_INTERFACE_ENTRY_FUNC_BLIND(0,SmartQI_)
+#if defined __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Winconsistent-missing-override"
+#endif
+ END_COM_MAP()
+#if defined __clang__
+#pragma clang diagnostic pop
+#endif
+
+ // IMAccessible
+ STDMETHOD(put_accValue)(VARIANT varChild,BSTR szValue) override;
+ STDMETHOD(put_accName)(VARIANT varChild,BSTR szName) override;
+ STDMETHOD(accDoDefaultAction)(VARIANT varChild) override;
+ STDMETHOD(accHitTest)(long xLeft,long yTop,VARIANT *pvarChild) override;
+ STDMETHOD(accNavigate)(long navDir,VARIANT varStart,VARIANT *pvarEndUpAt) override;
+ STDMETHOD(accLocation)(long *pxLeft,long *pyTop,long *pcxWidth,long *pcyHeight,VARIANT varChild) override;
+ STDMETHOD(accSelect)(long flagsSelect,VARIANT varChild) override;
+ STDMETHOD(get_accDefaultAction)( VARIANT varChild,BSTR *pszDefaultAction) override;
+ STDMETHOD(get_accSelection)(VARIANT *pvarChildren) override;
+ STDMETHOD(get_accFocus)(VARIANT *pvarChild) override;
+ STDMETHOD(get_accKeyboardShortcut)( VARIANT varChild,BSTR *pszKeyboardShortcut) override;
+ STDMETHOD(get_accHelpTopic)(BSTR *pszHelpFile,VARIANT varChild,long *pidTopic) override;
+ STDMETHOD(get_accHelp)(VARIANT varChild,BSTR *pszHelp) override;
+ STDMETHOD(get_accState)(VARIANT varChild,VARIANT *pvarState) override;
+ STDMETHOD(get_accRole)(VARIANT varChild,VARIANT *pvarRole) override;
+ STDMETHOD(get_accDescription)(VARIANT varChild,BSTR *pszDescription) override;
+ STDMETHOD(get_accValue)( VARIANT varChild,BSTR *pszValue) override;
+ STDMETHOD(get_accName)(VARIANT varChild,BSTR *pszName) override;
+ STDMETHOD(get_accChild)(VARIANT varChild,IDispatch **ppdispChild) override;
+ STDMETHOD(get_accChildCount)(long *pcountChildren) override;
+ STDMETHOD(get_accParent)( IDispatch **ppdispParent) override;
+
+ // methods which are defined only in the IAccessible2
+ // These methods only declare here, and their implementation bodies are empty now.
+ STDMETHOD(get_nRelations)( long __RPC_FAR *nRelations) override;
+ STDMETHOD(get_relation)( long relationIndex, IAccessibleRelation __RPC_FAR *__RPC_FAR *relation) override;
+ STDMETHOD(get_relations)( long maxRelations, IAccessibleRelation __RPC_FAR *__RPC_FAR *relation, long __RPC_FAR *nRelations) override;
+ STDMETHOD(role)(long __RPC_FAR *role) override;
+ STDMETHOD(get_nActions)(long __RPC_FAR *nActions);
+ STDMETHOD(scrollTo)(enum IA2ScrollType scrollType) override;
+ STDMETHOD(scrollToPoint)(enum IA2CoordinateType coordinateType, long x, long y) override;
+ STDMETHOD(get_groupPosition)(long __RPC_FAR *groupLevel,long __RPC_FAR *similarItemsInGroup,long __RPC_FAR *positionInGroup) override;
+ STDMETHOD(get_states)( AccessibleStates __RPC_FAR *states ) override;
+ STDMETHOD(get_extendedRole)( BSTR __RPC_FAR *extendedRole ) override;
+ STDMETHOD(get_localizedExtendedRole)( BSTR __RPC_FAR *localizedExtendedRole ) override;
+ STDMETHOD(get_nExtendedStates)( long __RPC_FAR *nExtendedStates) override;
+ STDMETHOD(get_extendedStates)( long maxExtendedStates, BSTR __RPC_FAR *__RPC_FAR *extendedStates, long __RPC_FAR *nExtendedStates) override;
+ STDMETHOD(get_localizedExtendedStates)(long maxLocalizedExtendedStates,BSTR __RPC_FAR *__RPC_FAR *localizedExtendedStates,long __RPC_FAR *nLocalizedExtendedStates) override;
+ STDMETHOD(get_uniqueID)(long __RPC_FAR *uniqueID) override;
+ STDMETHOD(get_windowHandle)(HWND __RPC_FAR *windowHandle) override;
+ STDMETHOD(get_indexInParent)( long __RPC_FAR *accParentIndex ) override;
+ STDMETHOD(get_locale)( IA2Locale __RPC_FAR *locale ) override;
+ STDMETHOD(get_attributes)(/*[out]*/ BSTR *pAttr) override;
+
+ //IServiceProvider.
+ STDMETHOD(QueryService)(REFGUID guidService, REFIID riid, void** ppvObject) override;
+
+ //IAccessibleApplication
+ STDMETHOD(get_appName)(BSTR __RPC_FAR *name) override;
+ STDMETHOD(get_appVersion)(BSTR __RPC_FAR *version) override;
+ STDMETHOD(get_toolkitName)(BSTR __RPC_FAR *name) override;
+ STDMETHOD(get_toolkitVersion)(BSTR __RPC_FAR *version) override;
+
+ // methods which are defined only in IMAccessible
+ // These methods are provided for UNO management system.
+ // The UNO management system use these methods to put Accessibility
+ // information to COM.
+ STDMETHOD(Put_XAccName)(const OLECHAR __RPC_FAR *pszName) override;
+ STDMETHOD(Put_XAccRole)(unsigned short pRole) override;
+ STDMETHOD(DecreaseState)(DWORD pXSate) override;
+ STDMETHOD(IncreaseState)(DWORD pXSate) override;
+ STDMETHOD(SetState)(DWORD pXSate) override;
+ STDMETHOD(Put_XAccValue)(const OLECHAR __RPC_FAR *pszAccValue) override;
+ STDMETHOD(Put_XAccLocation)(const Location sLocation) override;
+ STDMETHOD(Put_XAccFocus)(long dChildID) override;
+ STDMETHOD(Put_XAccParent)(IMAccessible __RPC_FAR *pIParent) override;
+ STDMETHOD(Put_XAccWindowHandle)(HWND hwnd) override;
+ STDMETHOD(Put_XAccChildID)(long dChildID) override;
+ STDMETHOD(Put_XAccAgent)(hyper pAgent) override;
+ STDMETHOD(NotifyDestroy)() override;
+ STDMETHOD(Put_ActionDescription)( const OLECHAR* szAction) override;
+ STDMETHOD(SetDefaultAction)(hyper pAction) override;
+ STDMETHOD(GetUNOInterface)(hyper*) override;
+ STDMETHOD(SetXAccessible)(hyper) override;
+
+private:
+ BSTR m_pszName;
+ BSTR m_pszValue;
+ BSTR m_pszActionDescription;
+ unsigned short m_iRole;
+ DWORD m_dState;
+ IMAccessible* m_pIParent;
+ Location m_sLocation;
+
+ // identify a COM object/Acc object uniquely
+ long m_dChildID;
+ // specify the focus child ID in object self and its direct children
+
+ long m_dFocusChildID;
+ // parent window handle,will be used in the future application, its value comes from UNO
+
+ HWND m_hwnd;
+
+ // the COM class which implements IEnumVARIANT interface,currently only used in
+ // the implementation of get_accSelection
+ CEnumVariant* m_pEnumVar;
+
+ // specify if the XAccessible is invalid
+ bool m_isDestroy;
+
+ css::uno::Reference<css::accessibility::XAccessible> m_xAccessible;
+ // initially m_xAction and m_xContext are the same object
+ // but they may be different once AccObject::UpdateAction() is called?
+ css::uno::Reference<css::accessibility::XAccessibleAction> m_xAction;
+ css::uno::Reference<css::accessibility::XAccessibleContext> m_xContext;
+
+private:
+
+ // the helper methods in order to implement the above public methods
+ IMAccessible* GetChildInterface(long dChildIndex);//notice here the parameter is child index,not child id
+ IMAccessible* GetNavigateChildForDM(VARIANT varCur,short flags);//for descendant manage
+ HRESULT GetFirstChild(VARIANT varStart,VARIANT* pvarEndUpAt);//for accNavigate implementation
+ HRESULT GetLastChild(VARIANT varStart,VARIANT* pvarEndUpAt);//for accNavigate implementation
+ HRESULT GetNextSibling(VARIANT varStart,VARIANT* pvarEndUpAt);//for accNavigate implementation
+ HRESULT GetPreSibling(VARIANT varStart,VARIANT* pvarEndUpAt);//for accNavigate implementation
+
+ // the following private methods are used to implement accSelect method
+ HRESULT SelectChild(css::accessibility::XAccessible* pItem);
+ HRESULT DeSelectChild(css::accessibility::XAccessible* pItem);
+ HRESULT SelectMultipleChidren(css::accessibility::XAccessible** pItem,
+ int size);
+ HRESULT DeSelectMultipleChildren(css::accessibility::XAccessible** pItem,
+ int size);
+ static css::accessibility::XAccessibleContext* GetContextByXAcc(
+ css::accessibility::XAccessible* pXAcc);
+ css::uno::Reference<css::accessibility::XAccessibleSelection> GetSelection();
+ // end accSelect implementation methods
+ static bool GetXInterfaceFromXAccessible(css::accessibility::XAccessible*,
+ css::uno::XInterface**, XInterfaceType);
+ HRESULT WINAPI SmartQI(void* pv, REFIID iid, void** ppvObject);
+
+public:
+ // AccObjectManagerAgent is a management object in UNO, here keep its pointer for
+ // the implementation of accNavigate when descendant manage happens for List,Tree, or Table
+ // AccObjectManagerAgent and the following UNO objects XAccessible,XAccessibleSelection,
+ // XAccessibleAction are all used to operate UNO accessibility information directly when
+ // implement some specific MSAA methods,such as accSelection,accNavigate
+ static AccObjectManagerAgent* g_pAgent;
+
+ static bool get_IAccessibleFromXAccessible(
+ css::accessibility::XAccessible * pXAcc, IAccessible** ppIA);
+ XGUIDToComObjHash m_containedObjects;
+
+ static HRESULT WINAPI SmartQI_(void* pv,
+ REFIID iid, void** ppvObject, DWORD_PTR)
+ {
+ return static_cast<CMAccessible*>(pv)->SmartQI(pv,iid,ppvObject);
+ }
+
+ static OUString get_StringFromAny(css::uno::Any const & pAny);
+
+ static OUString get_String4Numbering(const css::uno::Any& pAny,
+ sal_Int16 numberingLevel, std::u16string_view numberingPrefix);
+
+ // Helper function for data conversion.
+ static void ConvertAnyToVariant(const css::uno::Any &rAnyVal,
+ VARIANT *pvData);
+};
+
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/winaccessibility/source/UAccCOM/Resource.h b/winaccessibility/source/UAccCOM/Resource.h
new file mode 100644
index 000000000..d8abe9bcc
--- /dev/null
+++ b/winaccessibility/source/UAccCOM/Resource.h
@@ -0,0 +1,38 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by UAccCOM.rc
+
+
+#define IDS_PROJNAME 100
+
+// Next default values for new objects
+
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 203
+#define _APS_NEXT_COMMAND_VALUE 32768
+#define _APS_NEXT_CONTROL_VALUE 201
+#define _APS_NEXT_SYMED_VALUE 137
+#endif
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/winaccessibility/source/UAccCOM/StdAfx.cxx b/winaccessibility/source/UAccCOM/StdAfx.cxx
new file mode 100644
index 000000000..71ebbdb6b
--- /dev/null
+++ b/winaccessibility/source/UAccCOM/StdAfx.cxx
@@ -0,0 +1,26 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "stdafx.h"
+
+#ifdef _ATL_STATIC_REGISTRY
+#include <statreg.h>
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/winaccessibility/source/UAccCOM/UAccCOM.cxx b/winaccessibility/source/UAccCOM/UAccCOM.cxx
new file mode 100644
index 000000000..944db5c94
--- /dev/null
+++ b/winaccessibility/source/UAccCOM/UAccCOM.cxx
@@ -0,0 +1,117 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "stdafx.h"
+#include "Resource.h"
+#include <initguid.h>
+#include <accHelper.hxx>
+
+#if defined __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wnon-virtual-dtor"
+#endif
+#include <UAccCOM.h>
+#if defined __clang__
+#pragma clang diagnostic pop
+#endif
+
+#if defined __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored \
+ "-Wextra-tokens" // "#endif !_MIDL_USE_GUIDDEF_" in midl-generated code
+#endif
+#include <UAccCOM_i.c>
+#include <ia2_api_all_i.c>
+#if defined __clang__
+#pragma clang diagnostic pop
+#endif
+
+#include "MAccessible.h"
+#include "EnumVariant.h"
+#include "UNOXWrapper.h"
+#include "AccComponent.h"
+#include "AccRelation.h"
+#include "AccAction.h"
+#include "AccText.h"
+#include "AccEditableText.h"
+#include "AccImage.h"
+#include "AccValue.h"
+#include "AccTable.h"
+#include "AccTableCell.h"
+#include "AccHyperLink.h"
+#include "AccHypertext.h"
+
+CComModule _Module;
+
+BEGIN_OBJECT_MAP(ObjectMap)
+OBJECT_ENTRY(CLSID_MAccessible, CMAccessible)
+OBJECT_ENTRY(CLSID_EnumVariant, CEnumVariant)
+OBJECT_ENTRY(CLSID_AccComponent, CAccComponent)
+OBJECT_ENTRY(CLSID_AccRelation, CAccRelation)
+OBJECT_ENTRY(CLSID_AccAction, CAccAction)
+OBJECT_ENTRY(CLSID_AccText, CAccText)
+OBJECT_ENTRY(CLSID_AccEditableText, CAccEditableText)
+OBJECT_ENTRY(CLSID_AccImage, CAccImage)
+OBJECT_ENTRY(CLSID_AccValue, CAccValue)
+OBJECT_ENTRY(CLSID_AccTable, CAccTable)
+OBJECT_ENTRY(CLSID_AccTableCell, CAccTableCell)
+OBJECT_ENTRY(CLSID_AccHyperLink, CAccHyperLink)
+OBJECT_ENTRY(CLSID_AccHypertext, CAccHypertext)
+#if defined __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wmissing-field-initializers"
+#endif
+END_OBJECT_MAP()
+#if defined __clang__
+#pragma clang diagnostic pop
+#endif
+
+// DLL Entry Point
+
+extern "C" BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
+{
+ if (dwReason == DLL_PROCESS_ATTACH)
+ {
+ _Module.Init(ObjectMap, hInstance, &LIBID_UACCCOMLib);
+ DisableThreadLibraryCalls(hInstance);
+ }
+ else if (dwReason == DLL_PROCESS_DETACH)
+ _Module.Term();
+ return TRUE; // ok
+}
+
+// Used to determine whether the DLL can be unloaded by OLE
+
+STDAPI DllCanUnloadNow() { return (_Module.GetLockCount() == 0) ? S_OK : E_FAIL; }
+
+// Returns a class factory to create an object of the requested type
+
+STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
+{
+ return _Module.GetClassObject(rclsid, riid, ppv);
+}
+
+IMAccessible* UAccCOMCreateInstance()
+{
+ IMAccessible* pIMA = nullptr;
+ HRESULT hr = createInstance<CMAccessible>(IID_IMAccessible, &pIMA);
+ return (S_OK == hr) ? pIMA : nullptr;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/winaccessibility/source/UAccCOM/UAccCOM.def b/winaccessibility/source/UAccCOM/UAccCOM.def
new file mode 100644
index 000000000..45baa527b
--- /dev/null
+++ b/winaccessibility/source/UAccCOM/UAccCOM.def
@@ -0,0 +1,5 @@
+LIBRARY "UAccCOM.DLL"
+
+EXPORTS
+ DllCanUnloadNow PRIVATE
+ DllGetClassObject PRIVATE
diff --git a/winaccessibility/source/UAccCOM/UAccCOM.rc b/winaccessibility/source/UAccCOM/UAccCOM.rc
new file mode 100644
index 000000000..d81746ed3
--- /dev/null
+++ b/winaccessibility/source/UAccCOM/UAccCOM.rc
@@ -0,0 +1,90 @@
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+//Microsoft Developer Studio generated resource script.
+
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+
+
+// Generated from the TEXTINCLUDE 2 resource.
+
+#include "winres.h"
+
+
+#undef APSTUDIO_READONLY_SYMBOLS
+
+
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+
+
+// TEXTINCLUDE
+
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include ""winres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "1 TYPELIB ""UAccCOM.tlb""\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+
+// String Table
+
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ IDS_PROJNAME "UAccCOM"
+END
+
+#endif // English (U.S.) resources
+
+
+
+
+#ifndef APSTUDIO_INVOKED
+
+
+// Generated from the TEXTINCLUDE 3 resource.
+
+1 TYPELIB "UAccCOM.tlb"
+
+
+#endif // not APSTUDIO_INVOKED
+
diff --git a/winaccessibility/source/UAccCOM/UNOXWrapper.cxx b/winaccessibility/source/UAccCOM/UNOXWrapper.cxx
new file mode 100644
index 000000000..c009a005e
--- /dev/null
+++ b/winaccessibility/source/UAccCOM/UNOXWrapper.cxx
@@ -0,0 +1,43 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "UNOXWrapper.h"
+
+#if defined __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wnon-virtual-dtor"
+#endif
+#include <UAccCOM.h>
+#if defined __clang__
+#pragma clang diagnostic pop
+#endif
+
+using namespace ::com::sun::star;
+
+// CUNOXWrapper
+
+COM_DECLSPEC_NOTHROW STDMETHODIMP CUNOXWrapper::put_XInterface(hyper nXInterface)
+{
+ pUNOInterface = reinterpret_cast<accessibility::XAccessible*>(nXInterface);
+ return S_OK;
+}
+
+COM_DECLSPEC_NOTHROW STDMETHODIMP CUNOXWrapper::put_XSubInterface(hyper) { return S_OK; }
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/winaccessibility/source/UAccCOM/UNOXWrapper.h b/winaccessibility/source/UAccCOM/UNOXWrapper.h
new file mode 100644
index 000000000..42983f88a
--- /dev/null
+++ b/winaccessibility/source/UAccCOM/UNOXWrapper.h
@@ -0,0 +1,58 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include "stdafx.h"
+#include "Resource.h" // main symbols
+
+#include <com/sun/star/accessibility/XAccessible.hpp>
+
+#if defined __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wnon-virtual-dtor"
+#endif
+#include <UAccCOM.h>
+#if defined __clang__
+#pragma clang diagnostic pop
+#endif
+
+/**
+ * CUNOXWrapper implements IUNOXWrapper interface.
+ */
+class ATL_NO_VTABLE CUNOXWrapper : public IUNOXWrapper
+{
+protected:
+ css::accessibility::XAccessible* pUNOInterface;
+
+public:
+ CUNOXWrapper()
+ : pUNOInterface(nullptr)
+ {
+ }
+
+ // IUNOXWrapper
+ STDMETHOD(put_XInterface)(hyper pXInterface) override;
+ STDMETHOD(put_XSubInterface)(hyper) override;
+
+protected:
+ ~CUNOXWrapper() {}
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/winaccessibility/source/UAccCOM/acccommon.h b/winaccessibility/source/UAccCOM/acccommon.h
new file mode 100644
index 000000000..d2dffc5e6
--- /dev/null
+++ b/winaccessibility/source/UAccCOM/acccommon.h
@@ -0,0 +1,68 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+//for MAccessible.cxx
+struct ltComp
+{
+ bool operator()(REFGUID rguid1, REFGUID rguid2) const
+ {
+ if(reinterpret_cast<LONG const *>(&rguid1)[0] < reinterpret_cast<LONG const *>(&rguid2)[0])
+ return true;
+ else if(reinterpret_cast<LONG const *>(&rguid1)[0] > reinterpret_cast<LONG const *>(&rguid2)[0])
+ return false;
+ if(reinterpret_cast<LONG const *>(&rguid1)[1] < reinterpret_cast<LONG const *>(&rguid2)[1])
+ return true;
+ else if(reinterpret_cast<LONG const *>(&rguid1)[1] > reinterpret_cast<LONG const *>(&rguid2)[1])
+ return false;
+ if(reinterpret_cast<LONG const *>(&rguid1)[2] < reinterpret_cast<LONG const *>(&rguid2)[2])
+ return true;
+ else if(reinterpret_cast<LONG const *>(&rguid1)[2] > reinterpret_cast<LONG const *>(&rguid2)[2])
+ return false;
+ if(reinterpret_cast<LONG const *>(&rguid1)[3] < reinterpret_cast<LONG const *>(&rguid2)[3])
+ return true;
+ else if(reinterpret_cast<LONG const *>(&rguid1)[3] > reinterpret_cast<LONG const *>(&rguid2)[3])
+ return false;
+ return false;
+ }
+};
+
+enum DM_NIR {
+ DM_FIRSTCHILD = 0x00,
+ DM_LASTCHILD = 0x01,
+ DM_NEXTCHILD = 0x02,
+ DM_PREVCHILD = 0x03
+};
+
+
+#define SELECT_STR L"Select"
+#define PRESS_STR L"Press"
+#define UNCHECK_STR L"UnCheck"
+#define CHECK_STR L"Check"
+//End
+
+template<typename T, typename Ifc> HRESULT
+createInstance(REFIID iid, Ifc ** ppIfc)
+{
+ return
+ CComCreator< CComObject<T> >::CreateInstance(nullptr, iid, reinterpret_cast<void**>(ppIfc));
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/winaccessibility/source/UAccCOM/stdafx.h b/winaccessibility/source/UAccCOM/stdafx.h
new file mode 100644
index 000000000..53044645f
--- /dev/null
+++ b/winaccessibility/source/UAccCOM/stdafx.h
@@ -0,0 +1,65 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+// stdafx.h : include file for standard system include files,
+// or project specific include files that are used frequently,
+// but are changed infrequently
+
+#pragma once
+
+#pragma once
+
+// this turns off ATL's locking in the COM component implementations
+// (we don't need it since we use SolarMutex instead)
+#define _ATL_APARTMENT_THREADED
+
+#include <prewin.h>
+#if !defined WIN32_LEAN_AND_MEAN
+# define WIN32_LEAN_AND_MEAN
+#endif
+#include <windows.h>
+
+#if defined __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wall"
+#pragma clang diagnostic ignored "-Wattributes"
+#pragma clang diagnostic ignored "-Wdelete-incomplete"
+#pragma clang diagnostic ignored "-Wextra"
+#pragma clang diagnostic ignored "-Wint-to-pointer-cast"
+#pragma clang diagnostic ignored "-Winvalid-noreturn"
+#pragma clang diagnostic ignored "-Wmicrosoft"
+#pragma clang diagnostic ignored "-Wnon-pod-varargs"
+#pragma clang diagnostic ignored "-Wnon-virtual-dtor"
+#endif
+#include <atlbase.h>
+// You may derive a class from CComModule and use it if you want to override
+// something, but do not change the name of _Module
+extern CComModule _Module;
+#include <atlcom.h>
+#if defined __clang__
+#pragma clang diagnostic pop
+#endif
+#include <postwin.h>
+#undef OPAQUE
+
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */