|
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
|
2 /* vim: set ts=2 et sw=2 tw=80: */ |
|
3 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
4 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
6 |
|
7 #include "InterfaceInitFuncs.h" |
|
8 |
|
9 #include "Accessible-inl.h" |
|
10 #include "nsMai.h" |
|
11 #include "Role.h" |
|
12 #include "mozilla/Likely.h" |
|
13 |
|
14 #include "nsString.h" |
|
15 |
|
16 using namespace mozilla::a11y; |
|
17 |
|
18 extern "C" { |
|
19 |
|
20 static gboolean |
|
21 doActionCB(AtkAction *aAction, gint aActionIndex) |
|
22 { |
|
23 AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aAction)); |
|
24 if (!accWrap) |
|
25 return FALSE; |
|
26 |
|
27 nsresult rv = accWrap->DoAction(aActionIndex); |
|
28 return (NS_FAILED(rv)) ? FALSE : TRUE; |
|
29 } |
|
30 |
|
31 static gint |
|
32 getActionCountCB(AtkAction *aAction) |
|
33 { |
|
34 AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aAction)); |
|
35 return accWrap ? accWrap->ActionCount() : 0; |
|
36 } |
|
37 |
|
38 static const gchar* |
|
39 getActionDescriptionCB(AtkAction *aAction, gint aActionIndex) |
|
40 { |
|
41 AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aAction)); |
|
42 if (!accWrap) |
|
43 return nullptr; |
|
44 |
|
45 nsAutoString description; |
|
46 nsresult rv = accWrap->GetActionDescription(aActionIndex, description); |
|
47 NS_ENSURE_SUCCESS(rv, nullptr); |
|
48 return AccessibleWrap::ReturnString(description); |
|
49 } |
|
50 |
|
51 static const gchar* |
|
52 getActionNameCB(AtkAction *aAction, gint aActionIndex) |
|
53 { |
|
54 AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aAction)); |
|
55 if (!accWrap) |
|
56 return nullptr; |
|
57 |
|
58 nsAutoString autoStr; |
|
59 nsresult rv = accWrap->GetActionName(aActionIndex, autoStr); |
|
60 NS_ENSURE_SUCCESS(rv, nullptr); |
|
61 return AccessibleWrap::ReturnString(autoStr); |
|
62 } |
|
63 |
|
64 static const gchar* |
|
65 getKeyBindingCB(AtkAction *aAction, gint aActionIndex) |
|
66 { |
|
67 AccessibleWrap* acc = GetAccessibleWrap(ATK_OBJECT(aAction)); |
|
68 if (!acc) |
|
69 return nullptr; |
|
70 |
|
71 // Return all key bindings including access key and keyboard shortcut. |
|
72 nsAutoString keyBindingsStr; |
|
73 |
|
74 // Get access key. |
|
75 KeyBinding keyBinding = acc->AccessKey(); |
|
76 if (!keyBinding.IsEmpty()) { |
|
77 keyBinding.AppendToString(keyBindingsStr, KeyBinding::eAtkFormat); |
|
78 |
|
79 Accessible* parent = acc->Parent(); |
|
80 roles::Role role = parent ? parent->Role() : roles::NOTHING; |
|
81 if (role == roles::PARENT_MENUITEM || role == roles::MENUITEM || |
|
82 role == roles::RADIO_MENU_ITEM || role == roles::CHECK_MENU_ITEM) { |
|
83 // It is submenu, expose keyboard shortcuts from menu hierarchy like |
|
84 // "s;<Alt>f:s" |
|
85 nsAutoString keysInHierarchyStr = keyBindingsStr; |
|
86 do { |
|
87 KeyBinding parentKeyBinding = parent->AccessKey(); |
|
88 if (!parentKeyBinding.IsEmpty()) { |
|
89 nsAutoString str; |
|
90 parentKeyBinding.ToString(str, KeyBinding::eAtkFormat); |
|
91 str.Append(':'); |
|
92 |
|
93 keysInHierarchyStr.Insert(str, 0); |
|
94 } |
|
95 } while ((parent = parent->Parent()) && parent->Role() != roles::MENUBAR); |
|
96 |
|
97 keyBindingsStr.Append(';'); |
|
98 keyBindingsStr.Append(keysInHierarchyStr); |
|
99 } |
|
100 } else { |
|
101 // No access key, add ';' to point this. |
|
102 keyBindingsStr.Append(';'); |
|
103 } |
|
104 |
|
105 // Get keyboard shortcut. |
|
106 keyBindingsStr.Append(';'); |
|
107 keyBinding = acc->KeyboardShortcut(); |
|
108 if (!keyBinding.IsEmpty()) { |
|
109 keyBinding.AppendToString(keyBindingsStr, KeyBinding::eAtkFormat); |
|
110 } |
|
111 |
|
112 return AccessibleWrap::ReturnString(keyBindingsStr); |
|
113 } |
|
114 } |
|
115 |
|
116 void |
|
117 actionInterfaceInitCB(AtkActionIface* aIface) |
|
118 { |
|
119 NS_ASSERTION(aIface, "Invalid aIface"); |
|
120 if (MOZ_UNLIKELY(!aIface)) |
|
121 return; |
|
122 |
|
123 aIface->do_action = doActionCB; |
|
124 aIface->get_n_actions = getActionCountCB; |
|
125 aIface->get_description = getActionDescriptionCB; |
|
126 aIface->get_keybinding = getKeyBindingCB; |
|
127 aIface->get_name = getActionNameCB; |
|
128 } |