~ubuntu-branches/ubuntu/precise/kompozer/precise

« back to all changes in this revision

Viewing changes to mozilla/accessible/src/atk/nsMaiInterfaceAction.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Anthony Yarusso
  • Date: 2007-08-27 01:11:03 UTC
  • Revision ID: james.westby@ubuntu.com-20070827011103-2jgf4s6532gqu2ka
Tags: upstream-0.7.10
ImportĀ upstreamĀ versionĀ 0.7.10

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 
2
/* vim:expandtab:shiftwidth=4:tabstop=4:
 
3
 */
 
4
/* ***** BEGIN LICENSE BLOCK *****
 
5
 * Version: NPL 1.1/GPL 2.0/LGPL 2.1
 
6
 *
 
7
 *
 
8
 * The contents of this file are subject to the Mozilla Public
 
9
 * License Version 1.1 (the "License"); you may not use this file
 
10
 * except in compliance with the License. You may obtain a copy of
 
11
 * the License at http://www.mozilla.org/MPL/
 
12
 *
 
13
 * Software distributed under the License is distributed on an "AS
 
14
 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
 
15
 * implied. See the License for the specific language governing
 
16
 * rights and limitations under the License.
 
17
 *
 
18
 * The Original Code is mozilla.org code.
 
19
 *
 
20
 * The Initial Developer of the Original Code is Sun Microsystems, Inc.
 
21
 * Portions created by Sun Microsystems are Copyright (C) 2002 Sun
 
22
 * Microsystems, Inc. All Rights Reserved.
 
23
 *
 
24
 * Original Author: Bolian Yin (bolian.yin@sun.com)
 
25
 *
 
26
 * Contributor(s):
 
27
 *
 
28
 * Alternatively, the contents of this file may be used under the terms of
 
29
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 
30
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 
31
 * in which case the provisions of the GPL or the LGPL are applicable instead
 
32
 * of those above. If you wish to allow use of your version of this file only
 
33
 * under the terms of either the GPL or the LGPL, and not to allow others to
 
34
 * use your version of this file under the terms of the NPL, indicate your
 
35
 * decision by deleting the provisions above and replace them with the notice
 
36
 * and other provisions required by the GPL or the LGPL. If you do not delete
 
37
 * the provisions above, a recipient may use your version of this file under
 
38
 * the terms of any one of the NPL, the GPL or the LGPL.
 
39
 *
 
40
 * ***** END LICENSE BLOCK ***** */
 
41
 
 
42
#include "nsMaiInterfaceAction.h"
 
43
#include "nsAccessibleWrap.h"
 
44
#include "nsString.h"
 
45
 
 
46
G_BEGIN_DECLS
 
47
 
 
48
static void interfaceInitCB(AtkActionIface *aIface);
 
49
/* action interface callbacks */
 
50
static gboolean doActionCB(AtkAction *aAction, gint aActionIndex);
 
51
static gint getActionCountCB(AtkAction *aAction);
 
52
static const gchar *getDescriptionCB(AtkAction *aAction, gint aActionIndex);
 
53
static const gchar *getNameCB(AtkAction *aAction, gint aActionIndex);
 
54
static const gchar *getKeyBindingCB(AtkAction *aAction, gint aActionIndex);
 
55
static gboolean     setDescriptionCB(AtkAction *aAction, gint aActionIndex,
 
56
                                     const gchar *aDesc);
 
57
G_END_DECLS
 
58
 
 
59
MaiInterfaceAction::MaiInterfaceAction(nsAccessibleWrap *aAccWrap):
 
60
    MaiInterface(aAccWrap)
 
61
{
 
62
}
 
63
 
 
64
MaiInterfaceAction::~MaiInterfaceAction()
 
65
{
 
66
}
 
67
 
 
68
MaiInterfaceType
 
69
MaiInterfaceAction::GetType()
 
70
{
 
71
    return MAI_INTERFACE_ACTION;
 
72
}
 
73
 
 
74
const GInterfaceInfo *
 
75
MaiInterfaceAction::GetInterfaceInfo()
 
76
{
 
77
    static const GInterfaceInfo atk_if_action_info = {
 
78
        (GInterfaceInitFunc)interfaceInitCB,
 
79
        (GInterfaceFinalizeFunc) NULL,
 
80
        NULL
 
81
    };
 
82
    return &atk_if_action_info;
 
83
}
 
84
 
 
85
/* static functions */
 
86
 
 
87
void
 
88
interfaceInitCB(AtkActionIface *aIface)
 
89
{
 
90
    NS_ASSERTION(aIface, "Invalid aIface");
 
91
    if (!aIface)
 
92
        return;
 
93
 
 
94
    aIface->do_action = doActionCB;
 
95
    aIface->get_n_actions = getActionCountCB;
 
96
    aIface->get_description = getDescriptionCB;
 
97
    aIface->get_keybinding = getKeyBindingCB;
 
98
    aIface->get_name = getNameCB;
 
99
    aIface->set_description = setDescriptionCB;
 
100
}
 
101
 
 
102
gboolean
 
103
doActionCB(AtkAction *aAction, gint aActionIndex)
 
104
{
 
105
    nsAccessibleWrap *accWrap = GetAccessibleWrap(ATK_OBJECT(aAction));
 
106
    NS_ENSURE_TRUE(accWrap, FALSE);
 
107
 
 
108
    nsresult rv = accWrap->DoAction(aActionIndex);
 
109
    return (NS_FAILED(rv)) ? FALSE : TRUE;
 
110
}
 
111
 
 
112
gint
 
113
getActionCountCB(AtkAction *aAction)
 
114
{
 
115
    nsAccessibleWrap *accWrap = GetAccessibleWrap(ATK_OBJECT(aAction));
 
116
    NS_ENSURE_TRUE(accWrap, 0);
 
117
 
 
118
    PRUint8 num = 0;
 
119
    nsresult rv = accWrap->GetNumActions(&num);
 
120
    return (NS_FAILED(rv)) ? 0 : NS_STATIC_CAST(gint, num);
 
121
}
 
122
 
 
123
const gchar *
 
124
getDescriptionCB(AtkAction *aAction, gint aActionIndex)
 
125
{
 
126
    // the interface in nsIAccessibleAction is empty
 
127
    // use getName as default description
 
128
    return getNameCB(aAction, aActionIndex);
 
129
}
 
130
 
 
131
const gchar *
 
132
getNameCB(AtkAction *aAction, gint aActionIndex)
 
133
{
 
134
    nsAccessibleWrap *accWrap = GetAccessibleWrap(ATK_OBJECT(aAction));
 
135
    NS_ENSURE_TRUE(accWrap, nsnull);
 
136
 
 
137
    MaiInterfaceAction *action =
 
138
        NS_STATIC_CAST(MaiInterfaceAction *,
 
139
                       accWrap->GetMaiInterface(MAI_INTERFACE_ACTION));
 
140
    NS_ENSURE_TRUE(action, nsnull);
 
141
 
 
142
    const char *name = action->GetName();
 
143
    if (!name || !*name) {
 
144
        nsAutoString autoStr;
 
145
        nsresult rv = accWrap->GetActionName(aActionIndex, autoStr);
 
146
        NS_ENSURE_SUCCESS(rv, nsnull);
 
147
 
 
148
        action->SetName(autoStr);
 
149
        name = action->GetName();
 
150
    }
 
151
    return name;
 
152
}
 
153
 
 
154
const gchar *
 
155
getKeyBindingCB(AtkAction *aAction, gint aActionIndex)
 
156
{
 
157
    nsAccessibleWrap *accWrap = GetAccessibleWrap(ATK_OBJECT(aAction));
 
158
    NS_ENSURE_TRUE(accWrap, nsnull);
 
159
 
 
160
    MaiInterfaceAction *action =
 
161
        NS_STATIC_CAST(MaiInterfaceAction *,
 
162
                       accWrap->GetMaiInterface(MAI_INTERFACE_ACTION));
 
163
    NS_ENSURE_TRUE(action, nsnull);
 
164
 
 
165
    if (action->GetKeyBinding())
 
166
        return action->GetKeyBinding();
 
167
 
 
168
    //return all KeyBindings including accesskey and shortcut
 
169
    
 
170
    nsAutoString allKeyBinding;
 
171
 
 
172
    //get accesskey
 
173
    nsAutoString accessKey;
 
174
    nsresult rv = accWrap->GetKeyboardShortcut(accessKey);
 
175
 
 
176
    if (NS_SUCCEEDED(rv) && !accessKey.IsEmpty()) {
 
177
        nsCOMPtr<nsIAccessible> parentAccessible;
 
178
        accWrap->GetParent(getter_AddRefs(parentAccessible));
 
179
        if (parentAccessible) {
 
180
            PRUint32 role;
 
181
            parentAccessible->GetRole(&role);
 
182
 
 
183
            if (role == ATK_ROLE_MENU_BAR) {
 
184
                //it is topmenu, change from "Alt+f" to "f;<Alt>f"
 
185
                nsAutoString rightChar;
 
186
                accessKey.Right(rightChar, 1);
 
187
                allKeyBinding = rightChar + NS_LITERAL_STRING(";<Alt>") +
 
188
                                rightChar;
 
189
            }
 
190
            else if ((role == ATK_ROLE_MENU) || (role == ATK_ROLE_MENU_ITEM)) {
 
191
                //it is submenu, change from "s" to "s;<Alt>fs"
 
192
                nsAutoString allKey = accessKey;
 
193
                nsCOMPtr<nsIAccessible> grandParentAcc = parentAccessible;
 
194
 
 
195
                while ((grandParentAcc) && (role != ATK_ROLE_MENU_BAR)) {
 
196
                    nsAutoString grandParentKey;
 
197
                    grandParentAcc->GetKeyboardShortcut(grandParentKey);
 
198
 
 
199
                    if (!grandParentKey.IsEmpty()) {
 
200
                        nsAutoString rightChar;
 
201
                        grandParentKey.Right(rightChar, 1);
 
202
                        allKey = rightChar + allKey;
 
203
                    }
 
204
 
 
205
                    nsCOMPtr<nsIAccessible> tempAcc = grandParentAcc;
 
206
                    tempAcc->GetParent(getter_AddRefs(grandParentAcc));
 
207
                    if (grandParentAcc)
 
208
                        grandParentAcc->GetRole(&role);
 
209
                }
 
210
                allKeyBinding = accessKey + NS_LITERAL_STRING(";<Alt>") +
 
211
                                allKey;
 
212
            }
 
213
        }
 
214
        else {
 
215
            //default process, rarely happens.
 
216
            nsAutoString rightChar;
 
217
            accessKey.Right(rightChar, 1);
 
218
            allKeyBinding = rightChar + NS_LITERAL_STRING(";<Alt>") + rightChar;
 
219
        }
 
220
    }
 
221
    else  //don't have accesskey
 
222
        allKeyBinding = NS_LITERAL_STRING(";");
 
223
 
 
224
    //get shortcut
 
225
    nsAutoString keyBinding, subShortcut;
 
226
    rv = accWrap->GetKeyBinding(keyBinding);
 
227
 
 
228
    if (NS_SUCCEEDED(rv) && !keyBinding.IsEmpty()) {
 
229
        //change the shortcut from "Ctrl+Shift+L" to "<Control><Shift>L"
 
230
        PRInt32 oldPos, curPos=0;
 
231
        while ((curPos != -1) && (curPos < (PRInt32)keyBinding.Length())) {
 
232
            oldPos = curPos;
 
233
            nsAutoString subString;
 
234
            curPos = keyBinding.FindChar('+', oldPos);
 
235
            if (curPos == -1) {
 
236
                keyBinding.Mid(subString, oldPos, keyBinding.Length() - oldPos);
 
237
                subShortcut += subString;
 
238
            }
 
239
            else {
 
240
                keyBinding.Mid(subString, oldPos, curPos - oldPos);
 
241
      
 
242
                //change "Ctrl" to "Control"
 
243
                if (subString.EqualsIgnoreCase("ctrl"))
 
244
                    subString = NS_LITERAL_STRING("Control");
 
245
      
 
246
                subShortcut += NS_LITERAL_STRING("<") + subString +
 
247
                               NS_LITERAL_STRING(">");
 
248
                curPos++;
 
249
            }
 
250
        }
 
251
    }
 
252
 
 
253
    allKeyBinding += NS_LITERAL_STRING(";") + subShortcut;
 
254
    action->SetKeyBinding(allKeyBinding);
 
255
    return action->GetKeyBinding();
 
256
}
 
257
 
 
258
gboolean
 
259
setDescriptionCB(AtkAction *aAction, gint aActionIndex,
 
260
                 const gchar *aDesc)
 
261
{
 
262
    nsAccessibleWrap *accWrap = GetAccessibleWrap(ATK_OBJECT(aAction));
 
263
    NS_ENSURE_TRUE(accWrap, nsnull);
 
264
 
 
265
    /* this is not supported in nsIAccessible yet */
 
266
    return FALSE;
 
267
}