michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* vim:expandtab:shiftwidth=2:tabstop=2: michael@0: */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include "ia2AccessibleAction.h" michael@0: michael@0: #include "AccessibleAction_i.c" michael@0: michael@0: #include "AccessibleWrap.h" michael@0: #include "IUnknownImpl.h" michael@0: michael@0: using namespace mozilla::a11y; michael@0: michael@0: // IUnknown michael@0: michael@0: STDMETHODIMP michael@0: ia2AccessibleAction::QueryInterface(REFIID iid, void** ppv) michael@0: { michael@0: if (!ppv) michael@0: return E_INVALIDARG; michael@0: michael@0: *ppv = nullptr; michael@0: michael@0: if (IID_IAccessibleAction == iid) { michael@0: *ppv = static_cast(this); michael@0: (reinterpret_cast(*ppv))->AddRef(); michael@0: return S_OK; michael@0: } michael@0: michael@0: return E_NOINTERFACE; michael@0: } michael@0: michael@0: // IAccessibleAction michael@0: michael@0: STDMETHODIMP michael@0: ia2AccessibleAction::nActions(long* aActionCount) michael@0: { michael@0: A11Y_TRYBLOCK_BEGIN michael@0: michael@0: if (!aActionCount) michael@0: return E_INVALIDARG; michael@0: michael@0: *aActionCount = 0; michael@0: michael@0: AccessibleWrap* acc = static_cast(this); michael@0: if (acc->IsDefunct()) michael@0: return CO_E_OBJNOTCONNECTED; michael@0: michael@0: *aActionCount = acc->ActionCount(); michael@0: return S_OK; michael@0: michael@0: A11Y_TRYBLOCK_END michael@0: } michael@0: michael@0: STDMETHODIMP michael@0: ia2AccessibleAction::doAction(long aActionIndex) michael@0: { michael@0: A11Y_TRYBLOCK_BEGIN michael@0: michael@0: AccessibleWrap* acc = static_cast(this); michael@0: if (acc->IsDefunct()) michael@0: return CO_E_OBJNOTCONNECTED; michael@0: michael@0: uint8_t index = static_cast(aActionIndex); michael@0: nsresult rv = acc->DoAction(index); michael@0: return GetHRESULT(rv); michael@0: michael@0: A11Y_TRYBLOCK_END michael@0: } michael@0: michael@0: STDMETHODIMP michael@0: ia2AccessibleAction::get_description(long aActionIndex, BSTR *aDescription) michael@0: { michael@0: A11Y_TRYBLOCK_BEGIN michael@0: michael@0: if (!aDescription) michael@0: return E_INVALIDARG; michael@0: michael@0: *aDescription = nullptr; michael@0: michael@0: AccessibleWrap* acc = static_cast(this); michael@0: if (acc->IsDefunct()) michael@0: return CO_E_OBJNOTCONNECTED; michael@0: michael@0: nsAutoString description; michael@0: uint8_t index = static_cast(aActionIndex); michael@0: nsresult rv = acc->GetActionDescription(index, description); michael@0: if (NS_FAILED(rv)) michael@0: return GetHRESULT(rv); michael@0: michael@0: if (description.IsEmpty()) michael@0: return S_FALSE; michael@0: michael@0: *aDescription = ::SysAllocStringLen(description.get(), michael@0: description.Length()); michael@0: return *aDescription ? S_OK : E_OUTOFMEMORY; michael@0: michael@0: A11Y_TRYBLOCK_END michael@0: } michael@0: michael@0: STDMETHODIMP michael@0: ia2AccessibleAction::get_keyBinding(long aActionIndex, long aNumMaxBinding, michael@0: BSTR **aKeyBinding, michael@0: long *aNumBinding) michael@0: { michael@0: A11Y_TRYBLOCK_BEGIN michael@0: michael@0: if (!aKeyBinding) michael@0: return E_INVALIDARG; michael@0: *aKeyBinding = nullptr; michael@0: michael@0: if (!aNumBinding) michael@0: return E_INVALIDARG; michael@0: *aNumBinding = 0; michael@0: michael@0: if (aActionIndex != 0 || aNumMaxBinding < 1) michael@0: return E_INVALIDARG; michael@0: michael@0: AccessibleWrap* acc = static_cast(this); michael@0: if (acc->IsDefunct()) michael@0: return CO_E_OBJNOTCONNECTED; michael@0: michael@0: // Expose keyboard shortcut if it's not exposed via MSAA keyboard shortcut. michael@0: KeyBinding keyBinding = acc->AccessKey(); michael@0: if (keyBinding.IsEmpty()) michael@0: return S_FALSE; michael@0: michael@0: keyBinding = acc->KeyboardShortcut(); michael@0: if (keyBinding.IsEmpty()) michael@0: return S_FALSE; michael@0: michael@0: nsAutoString keyStr; michael@0: keyBinding.ToString(keyStr); michael@0: michael@0: *aKeyBinding = static_cast(::CoTaskMemAlloc(sizeof(BSTR*))); michael@0: if (!*aKeyBinding) michael@0: return E_OUTOFMEMORY; michael@0: michael@0: *(aKeyBinding[0]) = ::SysAllocStringLen(keyStr.get(), keyStr.Length()); michael@0: if (!*(aKeyBinding[0])) { michael@0: ::CoTaskMemFree(*aKeyBinding); michael@0: return E_OUTOFMEMORY; michael@0: } michael@0: michael@0: *aNumBinding = 1; michael@0: return S_OK; michael@0: michael@0: A11Y_TRYBLOCK_END michael@0: } michael@0: michael@0: STDMETHODIMP michael@0: ia2AccessibleAction::get_name(long aActionIndex, BSTR *aName) michael@0: { michael@0: A11Y_TRYBLOCK_BEGIN michael@0: michael@0: if (!aName) michael@0: return E_INVALIDARG; michael@0: michael@0: *aName = nullptr; michael@0: michael@0: AccessibleWrap* acc = static_cast(this); michael@0: if (acc->IsDefunct()) michael@0: return CO_E_OBJNOTCONNECTED; michael@0: michael@0: nsAutoString name; michael@0: uint8_t index = static_cast(aActionIndex); michael@0: nsresult rv = acc->GetActionName(index, name); michael@0: if (NS_FAILED(rv)) michael@0: return GetHRESULT(rv); michael@0: michael@0: if (name.IsEmpty()) michael@0: return S_FALSE; michael@0: michael@0: *aName = ::SysAllocStringLen(name.get(), name.Length()); michael@0: return *aName ? S_OK : E_OUTOFMEMORY; michael@0: michael@0: A11Y_TRYBLOCK_END michael@0: } michael@0: michael@0: STDMETHODIMP michael@0: ia2AccessibleAction::get_localizedName(long aActionIndex, BSTR *aLocalizedName) michael@0: { michael@0: A11Y_TRYBLOCK_BEGIN michael@0: michael@0: if (!aLocalizedName) michael@0: return E_INVALIDARG; michael@0: michael@0: *aLocalizedName = nullptr; michael@0: return E_NOTIMPL; michael@0: michael@0: A11Y_TRYBLOCK_END michael@0: }