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 : /* ***** BEGIN LICENSE BLOCK *****
4 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 : *
6 : * The contents of this file are subject to the Mozilla Public License Version
7 : * 1.1 (the "License"); you may not use this file except in compliance with
8 : * the License. You may obtain a copy of the License at
9 : * http://www.mozilla.org/MPL/
10 : *
11 : * Software distributed under the License is distributed on an "AS IS" basis,
12 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 : * for the specific language governing rights and limitations under the
14 : * License.
15 : *
16 : * The Original Code is mozilla.org code.
17 : *
18 : * The Initial Developer of the Original Code is
19 : * Sun Microsystems, Inc.
20 : * Portions created by the Initial Developer are Copyright (C) 2002
21 : * the Initial Developer. All Rights Reserved.
22 : *
23 : * Contributor(s):
24 : * Bolian Yin (bolian.yin@sun.com)
25 : *
26 : * Alternatively, the contents of this file may be used under the terms of
27 : * either the GNU General Public License Version 2 or later (the "GPL"), or
28 : * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 : * in which case the provisions of the GPL or the LGPL are applicable instead
30 : * of those above. If you wish to allow use of your version of this file only
31 : * under the terms of either the GPL or the LGPL, and not to allow others to
32 : * use your version of this file under the terms of the MPL, indicate your
33 : * decision by deleting the provisions above and replace them with the notice
34 : * and other provisions required by the GPL or the LGPL. If you do not delete
35 : * the provisions above, a recipient may use your version of this file under
36 : * the terms of any one of the MPL, the GPL or the LGPL.
37 : *
38 : * ***** END LICENSE BLOCK ***** */
39 :
40 : #include "nsMaiInterfaceAction.h"
41 :
42 : #include "nsAccUtils.h"
43 : #include "nsRoleMap.h"
44 : #include "nsString.h"
45 : #include "Role.h"
46 :
47 : #include "nsIDOMDOMStringList.h"
48 :
49 : using namespace mozilla::a11y;
50 :
51 : void
52 0 : actionInterfaceInitCB(AtkActionIface *aIface)
53 : {
54 0 : NS_ASSERTION(aIface, "Invalid aIface");
55 0 : if (!aIface)
56 0 : return;
57 :
58 0 : aIface->do_action = doActionCB;
59 0 : aIface->get_n_actions = getActionCountCB;
60 0 : aIface->get_description = getActionDescriptionCB;
61 0 : aIface->get_keybinding = getKeyBindingCB;
62 0 : aIface->get_name = getActionNameCB;
63 : }
64 :
65 : gboolean
66 0 : doActionCB(AtkAction *aAction, gint aActionIndex)
67 : {
68 0 : nsAccessibleWrap *accWrap = GetAccessibleWrap(ATK_OBJECT(aAction));
69 0 : if (!accWrap)
70 0 : return FALSE;
71 :
72 0 : nsresult rv = accWrap->DoAction(aActionIndex);
73 0 : return (NS_FAILED(rv)) ? FALSE : TRUE;
74 : }
75 :
76 : gint
77 0 : getActionCountCB(AtkAction *aAction)
78 : {
79 0 : nsAccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aAction));
80 0 : return accWrap ? accWrap->ActionCount() : 0;
81 : }
82 :
83 : const gchar *
84 0 : getActionDescriptionCB(AtkAction *aAction, gint aActionIndex)
85 : {
86 0 : nsAccessibleWrap *accWrap = GetAccessibleWrap(ATK_OBJECT(aAction));
87 0 : if (!accWrap)
88 0 : return nsnull;
89 :
90 0 : nsAutoString description;
91 0 : nsresult rv = accWrap->GetActionDescription(aActionIndex, description);
92 0 : NS_ENSURE_SUCCESS(rv, nsnull);
93 0 : return nsAccessibleWrap::ReturnString(description);
94 : }
95 :
96 : const gchar *
97 0 : getActionNameCB(AtkAction *aAction, gint aActionIndex)
98 : {
99 0 : nsAccessibleWrap *accWrap = GetAccessibleWrap(ATK_OBJECT(aAction));
100 0 : if (!accWrap)
101 0 : return nsnull;
102 :
103 0 : nsAutoString autoStr;
104 0 : nsresult rv = accWrap->GetActionName(aActionIndex, autoStr);
105 0 : NS_ENSURE_SUCCESS(rv, nsnull);
106 0 : return nsAccessibleWrap::ReturnString(autoStr);
107 : }
108 :
109 : const gchar *
110 0 : getKeyBindingCB(AtkAction *aAction, gint aActionIndex)
111 : {
112 0 : nsAccessibleWrap* acc = GetAccessibleWrap(ATK_OBJECT(aAction));
113 0 : if (!acc)
114 0 : return nsnull;
115 :
116 : // Return all key bindings including access key and keyboard shortcut.
117 0 : nsAutoString keyBindingsStr;
118 :
119 : // Get access key.
120 0 : KeyBinding keyBinding = acc->AccessKey();
121 0 : if (!keyBinding.IsEmpty()) {
122 0 : keyBinding.AppendToString(keyBindingsStr, KeyBinding::eAtkFormat);
123 :
124 0 : nsAccessible* parent = acc->Parent();
125 0 : roles::Role role = parent ? parent->Role() : roles::NOTHING;
126 0 : if (role == roles::PARENT_MENUITEM || role == roles::MENUITEM ||
127 : role == roles::RADIO_MENU_ITEM || role == roles::CHECK_MENU_ITEM) {
128 : // It is submenu, expose keyboard shortcuts from menu hierarchy like
129 : // "s;<Alt>f:s"
130 0 : nsAutoString keysInHierarchyStr = keyBindingsStr;
131 0 : do {
132 0 : KeyBinding parentKeyBinding = parent->AccessKey();
133 0 : if (!parentKeyBinding.IsEmpty()) {
134 0 : nsAutoString str;
135 0 : parentKeyBinding.ToString(str, KeyBinding::eAtkFormat);
136 0 : str.Append(':');
137 :
138 0 : keysInHierarchyStr.Insert(str, 0);
139 : }
140 0 : } while ((parent = parent->Parent()) && parent->Role() != roles::MENUBAR);
141 :
142 0 : keyBindingsStr.Append(';');
143 0 : keyBindingsStr.Append(keysInHierarchyStr);
144 : }
145 : } else {
146 : // No access key, add ';' to point this.
147 0 : keyBindingsStr.Append(';');
148 : }
149 :
150 : // Get keyboard shortcut.
151 0 : keyBindingsStr.Append(';');
152 0 : keyBinding = acc->KeyboardShortcut();
153 0 : if (!keyBinding.IsEmpty()) {
154 0 : keyBinding.AppendToString(keyBindingsStr, KeyBinding::eAtkFormat);
155 : }
156 :
157 0 : return nsAccessibleWrap::ReturnString(keyBindingsStr);
158 : }
|