diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:06:44 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:06:44 +0000 |
commit | ed5640d8b587fbcfed7dd7967f3de04b37a76f26 (patch) | |
tree | 7a5f7c6c9d02226d7471cb3cc8fbbf631b415303 /winaccessibility/source/UAccCOM | |
parent | Initial commit. (diff) | |
download | libreoffice-cb75148ebd0135178ff46f89a30139c44f8d2040.tar.xz libreoffice-cb75148ebd0135178ff46f89a30139c44f8d2040.zip |
Adding upstream version 4:7.4.7.upstream/4%7.4.7upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'winaccessibility/source/UAccCOM')
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: */ |