1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/accessible/src/atk/nsMaiInterfaceAction.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,128 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* vim: set ts=2 et sw=2 tw=80: */ 1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +#include "InterfaceInitFuncs.h" 1.11 + 1.12 +#include "Accessible-inl.h" 1.13 +#include "nsMai.h" 1.14 +#include "Role.h" 1.15 +#include "mozilla/Likely.h" 1.16 + 1.17 +#include "nsString.h" 1.18 + 1.19 +using namespace mozilla::a11y; 1.20 + 1.21 +extern "C" { 1.22 + 1.23 +static gboolean 1.24 +doActionCB(AtkAction *aAction, gint aActionIndex) 1.25 +{ 1.26 + AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aAction)); 1.27 + if (!accWrap) 1.28 + return FALSE; 1.29 + 1.30 + nsresult rv = accWrap->DoAction(aActionIndex); 1.31 + return (NS_FAILED(rv)) ? FALSE : TRUE; 1.32 +} 1.33 + 1.34 +static gint 1.35 +getActionCountCB(AtkAction *aAction) 1.36 +{ 1.37 + AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aAction)); 1.38 + return accWrap ? accWrap->ActionCount() : 0; 1.39 +} 1.40 + 1.41 +static const gchar* 1.42 +getActionDescriptionCB(AtkAction *aAction, gint aActionIndex) 1.43 +{ 1.44 + AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aAction)); 1.45 + if (!accWrap) 1.46 + return nullptr; 1.47 + 1.48 + nsAutoString description; 1.49 + nsresult rv = accWrap->GetActionDescription(aActionIndex, description); 1.50 + NS_ENSURE_SUCCESS(rv, nullptr); 1.51 + return AccessibleWrap::ReturnString(description); 1.52 +} 1.53 + 1.54 +static const gchar* 1.55 +getActionNameCB(AtkAction *aAction, gint aActionIndex) 1.56 +{ 1.57 + AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aAction)); 1.58 + if (!accWrap) 1.59 + return nullptr; 1.60 + 1.61 + nsAutoString autoStr; 1.62 + nsresult rv = accWrap->GetActionName(aActionIndex, autoStr); 1.63 + NS_ENSURE_SUCCESS(rv, nullptr); 1.64 + return AccessibleWrap::ReturnString(autoStr); 1.65 +} 1.66 + 1.67 +static const gchar* 1.68 +getKeyBindingCB(AtkAction *aAction, gint aActionIndex) 1.69 +{ 1.70 + AccessibleWrap* acc = GetAccessibleWrap(ATK_OBJECT(aAction)); 1.71 + if (!acc) 1.72 + return nullptr; 1.73 + 1.74 + // Return all key bindings including access key and keyboard shortcut. 1.75 + nsAutoString keyBindingsStr; 1.76 + 1.77 + // Get access key. 1.78 + KeyBinding keyBinding = acc->AccessKey(); 1.79 + if (!keyBinding.IsEmpty()) { 1.80 + keyBinding.AppendToString(keyBindingsStr, KeyBinding::eAtkFormat); 1.81 + 1.82 + Accessible* parent = acc->Parent(); 1.83 + roles::Role role = parent ? parent->Role() : roles::NOTHING; 1.84 + if (role == roles::PARENT_MENUITEM || role == roles::MENUITEM || 1.85 + role == roles::RADIO_MENU_ITEM || role == roles::CHECK_MENU_ITEM) { 1.86 + // It is submenu, expose keyboard shortcuts from menu hierarchy like 1.87 + // "s;<Alt>f:s" 1.88 + nsAutoString keysInHierarchyStr = keyBindingsStr; 1.89 + do { 1.90 + KeyBinding parentKeyBinding = parent->AccessKey(); 1.91 + if (!parentKeyBinding.IsEmpty()) { 1.92 + nsAutoString str; 1.93 + parentKeyBinding.ToString(str, KeyBinding::eAtkFormat); 1.94 + str.Append(':'); 1.95 + 1.96 + keysInHierarchyStr.Insert(str, 0); 1.97 + } 1.98 + } while ((parent = parent->Parent()) && parent->Role() != roles::MENUBAR); 1.99 + 1.100 + keyBindingsStr.Append(';'); 1.101 + keyBindingsStr.Append(keysInHierarchyStr); 1.102 + } 1.103 + } else { 1.104 + // No access key, add ';' to point this. 1.105 + keyBindingsStr.Append(';'); 1.106 + } 1.107 + 1.108 + // Get keyboard shortcut. 1.109 + keyBindingsStr.Append(';'); 1.110 + keyBinding = acc->KeyboardShortcut(); 1.111 + if (!keyBinding.IsEmpty()) { 1.112 + keyBinding.AppendToString(keyBindingsStr, KeyBinding::eAtkFormat); 1.113 + } 1.114 + 1.115 + return AccessibleWrap::ReturnString(keyBindingsStr); 1.116 +} 1.117 +} 1.118 + 1.119 +void 1.120 +actionInterfaceInitCB(AtkActionIface* aIface) 1.121 +{ 1.122 + NS_ASSERTION(aIface, "Invalid aIface"); 1.123 + if (MOZ_UNLIKELY(!aIface)) 1.124 + return; 1.125 + 1.126 + aIface->do_action = doActionCB; 1.127 + aIface->get_n_actions = getActionCountCB; 1.128 + aIface->get_description = getActionDescriptionCB; 1.129 + aIface->get_keybinding = getKeyBindingCB; 1.130 + aIface->get_name = getActionNameCB; 1.131 +}