// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/autocomplete/autocomplete_accessibility.h"
#include "chrome/browser/autocomplete/autocomplete_edit.h"
#include "chrome/browser/autocomplete/autocomplete_edit_view_win.h"
#include "grit/generated_resources.h"
#include "ui/base/l10n/l10n_util.h"
#include "views/accessibility/native_view_accessibility_win.h"
#include "views/view.h"
HRESULT AutocompleteAccessibility::Initialize(
const AutocompleteEditViewWin* edit_box) {
if (edit_box == NULL) {
return E_INVALIDARG;
}
edit_box_ = edit_box;
// Create a default accessible object for this instance.
return CreateStdAccessibleObject(edit_box_->m_hWnd, OBJID_CLIENT,
IID_IAccessible,
reinterpret_cast<void **>(default_accessibility_server_.Receive()));
}
STDMETHODIMP AutocompleteAccessibility::get_accChildCount(LONG* child_count) {
if (!child_count) {
return E_INVALIDARG;
}
DCHECK(default_accessibility_server_);
return default_accessibility_server_->get_accChildCount(child_count);
}
STDMETHODIMP AutocompleteAccessibility::get_accChild(VARIANT var_child,
IDispatch** disp_child) {
if (var_child.vt != VT_I4 || !disp_child) {
return E_INVALIDARG;
}
// If var_child is the parent, remain with the same IDispatch
if (var_child.lVal == CHILDID_SELF)
return S_OK;
*disp_child = NULL;
return S_FALSE;
}
STDMETHODIMP AutocompleteAccessibility::get_accParent(IDispatch** disp_parent) {
if (!disp_parent) {
return E_INVALIDARG;
}
if (edit_box_->parent_view() == NULL) {
*disp_parent = NULL;
return S_FALSE;
}
// Retrieve the IDispatch interface for the parent view.
*disp_parent = NativeViewAccessibilityWin::GetAccessibleForView(
edit_box_->parent_view());
// Increment the reference count for the retrieved interface.
(*disp_parent)->AddRef();
return S_OK;
}
STDMETHODIMP AutocompleteAccessibility::accNavigate(LONG nav_dir, VARIANT start,
VARIANT* end) {
if (start.vt != VT_I4 || !end) {
return E_INVALIDARG;
}
DCHECK(default_accessibility_server_);
return default_accessibility_server_->accNavigate(nav_dir, start, end);
}
STDMETHODIMP AutocompleteAccessibility::get_accFocus(VARIANT* focus_child) {
if (!focus_child) {
return E_INVALIDARG;
}
DCHECK(default_accessibility_server_);
return default_accessibility_server_->get_accFocus(focus_child);
}
STDMETHODIMP AutocompleteAccessibility::get_accName(VARIANT var_id,
BSTR* name) {
if (var_id.vt != VT_I4 || !name) {
return E_INVALIDARG;
}
string16 temp_name = l10n_util::GetStringUTF16(IDS_ACCNAME_LOCATION);
if (!temp_name.empty()) {
// Return name retrieved.
*name = SysAllocString(temp_name.c_str());
} else {
// If no name is found, return S_FALSE.
return S_FALSE;
}
DCHECK(*name);
return S_OK;
}
STDMETHODIMP AutocompleteAccessibility::get_accDescription(VARIANT var_id,
BSTR* desc) {
if (var_id.vt != VT_I4 || !desc) {
return E_INVALIDARG;
}
return S_FALSE;
}
STDMETHODIMP AutocompleteAccessibility::get_accValue(VARIANT var_id,
BSTR* value) {
if (var_id.vt != VT_I4 || !value) {
return E_INVALIDARG;
}
string16 temp_value;
if (var_id.lVal != CHILDID_SELF)
return E_INVALIDARG;
// Edit box has no children, only handle self.
temp_value = edit_box_->GetText();
if (temp_value.empty())
return S_FALSE;
// Return value retrieved.
*value = SysAllocString(temp_value.c_str());
DCHECK(*value);
return S_OK;
}
STDMETHODIMP AutocompleteAccessibility::get_accState(VARIANT var_id,
VARIANT* state) {
if (var_id.vt != VT_I4 || !state) {
return E_INVALIDARG;
}
DCHECK(default_accessibility_server_);
HRESULT hr = default_accessibility_server_->get_accState(var_id, state);
if (hr != S_OK)
return hr;
// Adding on state to convey the fact that there is a dropdown.
state->lVal |= STATE_SYSTEM_HASPOPUP;
return S_OK;
}
STDMETHODIMP AutocompleteAccessibility::get_accRole(VARIANT var_id,
VARIANT* role) {
if (var_id.vt != VT_I4 || !role) {
return E_INVALIDARG;
}
role->vt = VT_I4;
// Need to override the default role, which is ROLE_SYSTEM_CLIENT.
if (var_id.lVal == CHILDID_SELF) {
role->lVal = ROLE_SYSTEM_TEXT;
} else {
return S_FALSE;
}
return S_OK;
}
STDMETHODIMP AutocompleteAccessibility::get_accDefaultAction(VARIANT var_id,
BSTR* def_action) {
if (var_id.vt != VT_I4 || !def_action) {
return E_INVALIDARG;
}
return S_FALSE;
}
STDMETHODIMP AutocompleteAccessibility::accLocation(LONG* x_left, LONG* y_top,
LONG* width, LONG* height,
VARIANT var_id) {
if (var_id.vt != VT_I4 || !x_left || !y_top || !width || !height) {
return E_INVALIDARG;
}
DCHECK(default_accessibility_server_);
return default_accessibility_server_->accLocation(x_left, y_top, width,
height, var_id);
}
STDMETHODIMP AutocompleteAccessibility::accHitTest(LONG x_left, LONG y_top,
VARIANT* child) {
if (!child) {
return E_INVALIDARG;
}
DCHECK(default_accessibility_server_);
return default_accessibility_server_->accHitTest(x_left, y_top, child);
}
STDMETHODIMP AutocompleteAccessibility::get_accKeyboardShortcut(VARIANT var_id,
BSTR* acc_key) {
if (var_id.vt != VT_I4 || !acc_key) {
return E_INVALIDARG;
}
return S_FALSE;
}
// IAccessible functions not supported.
HRESULT AutocompleteAccessibility::accDoDefaultAction(VARIANT var_id) {
return DISP_E_MEMBERNOTFOUND;
}
STDMETHODIMP AutocompleteAccessibility::get_accSelection(VARIANT* selected) {
if (selected)
selected->vt = VT_EMPTY;
return DISP_E_MEMBERNOTFOUND;
}
STDMETHODIMP AutocompleteAccessibility::accSelect(LONG flagsSelect,
VARIANT var_id) {
return DISP_E_MEMBERNOTFOUND;
}
STDMETHODIMP AutocompleteAccessibility::get_accHelp(VARIANT var_id,
BSTR* help) {
if (help)
*help = NULL;
return DISP_E_MEMBERNOTFOUND;
}
STDMETHODIMP AutocompleteAccessibility::get_accHelpTopic(BSTR* help_file,
VARIANT var_id,
LONG* topic_id) {
if (help_file) {
*help_file = NULL;
}
if (topic_id) {
*topic_id = static_cast<LONG>(-1);
}
return DISP_E_MEMBERNOTFOUND;
}
STDMETHODIMP AutocompleteAccessibility::put_accName(VARIANT var_id,
BSTR put_name) {
// Deprecated.
return DISP_E_MEMBERNOTFOUND;
}
STDMETHODIMP AutocompleteAccessibility::put_accValue(VARIANT var_id,
BSTR put_val) {
// Deprecated.
return DISP_E_MEMBERNOTFOUND;
}