1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "views/accelerator.h"
9 #elif defined(TOOLKIT_USES_GTK)
13 #include "base/i18n/rtl.h"
14 #include "base/logging.h"
15 #include "base/string_util.h"
16 #include "base/utf_string_conversions.h"
17 #include "grit/ui_strings.h"
18 #include "ui/base/l10n/l10n_util.h"
22 string16
Accelerator::GetShortcutText() const {
26 string_id
= IDS_APP_TAB_KEY
;
29 string_id
= IDS_APP_ENTER_KEY
;
32 string_id
= IDS_APP_ESC_KEY
;
35 string_id
= IDS_APP_PAGEUP_KEY
;
38 string_id
= IDS_APP_PAGEDOWN_KEY
;
41 string_id
= IDS_APP_END_KEY
;
44 string_id
= IDS_APP_HOME_KEY
;
47 string_id
= IDS_APP_INSERT_KEY
;
50 string_id
= IDS_APP_DELETE_KEY
;
53 string_id
= IDS_APP_LEFT_ARROW_KEY
;
56 string_id
= IDS_APP_RIGHT_ARROW_KEY
;
59 string_id
= IDS_APP_BACKSPACE_KEY
;
62 string_id
= IDS_APP_F1_KEY
;
65 string_id
= IDS_APP_F11_KEY
;
74 // Our fallback is to try translate the key code to a regular character
75 // unless it is one of digits (VK_0 to VK_9). Some keyboard
76 // layouts have characters other than digits assigned in
77 // an unshifted mode (e.g. French AZERY layout has 'a with grave
78 // accent' for '0'). For display in the menu (e.g. Ctrl-0 for the
79 // default zoom level), we leave VK_[0-9] alone without translation.
81 if (key_code_
>= '0' && key_code_
<= '9')
84 key
= LOWORD(::MapVirtualKeyW(key_code_
, MAPVK_VK_TO_CHAR
));
86 #elif defined(TOOLKIT_USES_GTK)
87 const gchar
* name
= NULL
;
90 name
= static_cast<const gchar
*>("/");
93 name
= gdk_keyval_name(gdk_keyval_to_lower(key_code_
));
97 if (name
[0] != 0 && name
[1] == 0)
98 shortcut
+= static_cast<string16::value_type
>(g_ascii_toupper(name
[0]));
100 shortcut
+= UTF8ToUTF16(name
);
104 shortcut
= l10n_util::GetStringUTF16(string_id
);
107 // Checking whether the character used for the accelerator is alphanumeric.
108 // If it is not, then we need to adjust the string later on if the locale is
109 // right-to-left. See below for more information of why such adjustment is
111 string16 shortcut_rtl
;
112 bool adjust_shortcut_for_rtl
= false;
113 if (base::i18n::IsRTL() && shortcut
.length() == 1 &&
114 !IsAsciiAlpha(shortcut
[0]) && !IsAsciiDigit(shortcut
[0])) {
115 adjust_shortcut_for_rtl
= true;
116 shortcut_rtl
.assign(shortcut
);
120 shortcut
= l10n_util::GetStringFUTF16(IDS_APP_SHIFT_MODIFIER
, shortcut
);
122 // Note that we use 'else-if' in order to avoid using Ctrl+Alt as a shortcut.
123 // See http://blogs.msdn.com/oldnewthing/archive/2004/03/29/101121.aspx for
126 shortcut
= l10n_util::GetStringFUTF16(IDS_APP_CONTROL_MODIFIER
, shortcut
);
127 else if (IsAltDown())
128 shortcut
= l10n_util::GetStringFUTF16(IDS_APP_ALT_MODIFIER
, shortcut
);
130 // For some reason, menus in Windows ignore standard Unicode directionality
131 // marks (such as LRE, PDF, etc.). On RTL locales, we use RTL menus and
132 // therefore any text we draw for the menu items is drawn in an RTL context.
133 // Thus, the text "Ctrl++" (which we currently use for the Zoom In option)
134 // appears as "++Ctrl" in RTL because the Unicode BiDi algorithm puts
135 // punctuations on the left when the context is right-to-left. Shortcuts that
136 // do not end with a punctuation mark (such as "Ctrl+H" do not have this
139 // The only way to solve this problem is to adjust the string if the locale
140 // is RTL so that it is drawn correnctly in an RTL context. Instead of
141 // returning "Ctrl++" in the above example, we return "++Ctrl". This will
142 // cause the text to appear as "Ctrl++" when Windows draws the string in an
143 // RTL context because the punctunation no longer appears at the end of the
146 // TODO(idana) bug# 1232732: this hack can be avoided if instead of using
147 // views::Menu we use views::MenuItemView because the latter is a View
148 // subclass and therefore it supports marking text as RTL or LTR using
149 // standard Unicode directionality marks.
150 if (adjust_shortcut_for_rtl
) {
151 int key_length
= static_cast<int>(shortcut_rtl
.length());
152 DCHECK_GT(key_length
, 0);
153 shortcut_rtl
.append(ASCIIToUTF16("+"));
155 // Subtracting the size of the shortcut key and 1 for the '+' sign.
156 shortcut_rtl
.append(shortcut
, 0, shortcut
.length() - key_length
- 1);
157 shortcut
.swap(shortcut_rtl
);