accelerator.cc revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/accelerators/accelerator.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <windows.h> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(TOOLKIT_GTK) 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <gdk/gdk.h> 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/i18n/rtl.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 155e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/string_util.h" 16868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/ui_strings.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(OS_WIN) && (defined(USE_AURA) || defined(OS_MACOSX)) 21d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ui/events/keycodes/keyboard_code_conversion.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace ui { 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Accelerator::Accelerator() 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : key_code_(ui::VKEY_UNKNOWN), 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type_(ui::ET_KEY_PRESSED), 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) modifiers_(0) { 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Accelerator::Accelerator(KeyboardCode keycode, int modifiers) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : key_code_(keycode), 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type_(ui::ET_KEY_PRESSED), 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) modifiers_(modifiers) { 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Accelerator::Accelerator(const Accelerator& accelerator) { 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) key_code_ = accelerator.key_code_; 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type_ = accelerator.type_; 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) modifiers_ = accelerator.modifiers_; 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (accelerator.platform_accelerator_.get()) 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) platform_accelerator_ = accelerator.platform_accelerator_->CreateCopy(); 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Accelerator::~Accelerator() { 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Accelerator& Accelerator::operator=(const Accelerator& accelerator) { 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (this != &accelerator) { 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) key_code_ = accelerator.key_code_; 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type_ = accelerator.type_; 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) modifiers_ = accelerator.modifiers_; 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (accelerator.platform_accelerator_.get()) 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) platform_accelerator_ = accelerator.platform_accelerator_->CreateCopy(); 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) platform_accelerator_.reset(); 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return *this; 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Accelerator::operator <(const Accelerator& rhs) const { 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (key_code_ != rhs.key_code_) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return key_code_ < rhs.key_code_; 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (type_ != rhs.type_) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return type_ < rhs.type_; 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return modifiers_ < rhs.modifiers_; 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Accelerator::operator ==(const Accelerator& rhs) const { 715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if ((key_code_ == rhs.key_code_) && (type_ == rhs.type_) && 725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) (modifiers_ == rhs.modifiers_)) 735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return true; 745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool platform_equal = 765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) platform_accelerator_.get() && rhs.platform_accelerator_.get() && 775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) platform_accelerator_.get() == rhs.platform_accelerator_.get(); 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return platform_equal; 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Accelerator::operator !=(const Accelerator& rhs) const { 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return !(*this == rhs); 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Accelerator::IsShiftDown() const { 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (modifiers_ & EF_SHIFT_DOWN) != 0; 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Accelerator::IsCtrlDown() const { 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (modifiers_ & EF_CONTROL_DOWN) != 0; 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Accelerator::IsAltDown() const { 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (modifiers_ & EF_ALT_DOWN) != 0; 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Accelerator::IsCmdDown() const { 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (modifiers_ & EF_COMMAND_DOWN) != 0; 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 102a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)base::string16 Accelerator::GetShortcutText() const { 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int string_id = 0; 104a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) switch (key_code_) { 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ui::VKEY_TAB: 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string_id = IDS_APP_TAB_KEY; 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ui::VKEY_RETURN: 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string_id = IDS_APP_ENTER_KEY; 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ui::VKEY_ESCAPE: 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string_id = IDS_APP_ESC_KEY; 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ui::VKEY_PRIOR: 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string_id = IDS_APP_PAGEUP_KEY; 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ui::VKEY_NEXT: 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string_id = IDS_APP_PAGEDOWN_KEY; 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ui::VKEY_END: 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string_id = IDS_APP_END_KEY; 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ui::VKEY_HOME: 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string_id = IDS_APP_HOME_KEY; 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ui::VKEY_INSERT: 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string_id = IDS_APP_INSERT_KEY; 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ui::VKEY_DELETE: 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string_id = IDS_APP_DELETE_KEY; 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ui::VKEY_LEFT: 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string_id = IDS_APP_LEFT_ARROW_KEY; 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ui::VKEY_RIGHT: 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string_id = IDS_APP_RIGHT_ARROW_KEY; 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 138a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) case ui::VKEY_UP: 139a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) string_id = IDS_APP_UP_ARROW_KEY; 140a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) break; 141a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) case ui::VKEY_DOWN: 142a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) string_id = IDS_APP_DOWN_ARROW_KEY; 143a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) break; 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ui::VKEY_BACK: 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string_id = IDS_APP_BACKSPACE_KEY; 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ui::VKEY_F1: 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string_id = IDS_APP_F1_KEY; 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ui::VKEY_F11: 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string_id = IDS_APP_F11_KEY; 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 153a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) case ui::VKEY_OEM_COMMA: 154a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) string_id = IDS_APP_COMMA_KEY; 155a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) break; 156a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) case ui::VKEY_OEM_PERIOD: 157a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) string_id = IDS_APP_PERIOD_KEY; 158a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) break; 15958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) case ui::VKEY_MEDIA_NEXT_TRACK: 16058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) string_id = IDS_APP_MEDIA_NEXT_TRACK_KEY; 16158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) break; 16258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) case ui::VKEY_MEDIA_PLAY_PAUSE: 16358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) string_id = IDS_APP_MEDIA_PLAY_PAUSE_KEY; 16458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) break; 16558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) case ui::VKEY_MEDIA_PREV_TRACK: 16658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) string_id = IDS_APP_MEDIA_PREV_TRACK_KEY; 16758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) break; 16858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) case ui::VKEY_MEDIA_STOP: 16958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) string_id = IDS_APP_MEDIA_STOP_KEY; 17058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) break; 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 175a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) base::string16 shortcut; 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!string_id) { 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Our fallback is to try translate the key code to a regular character 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // unless it is one of digits (VK_0 to VK_9). Some keyboard 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // layouts have characters other than digits assigned in 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // an unshifted mode (e.g. French AZERY layout has 'a with grave 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // accent' for '0'). For display in the menu (e.g. Ctrl-0 for the 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // default zoom level), we leave VK_[0-9] alone without translation. 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wchar_t key; 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (key_code_ >= '0' && key_code_ <= '9') 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) key = key_code_; 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) key = LOWORD(::MapVirtualKeyW(key_code_, MAPVK_VK_TO_CHAR)); 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shortcut += key; 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(USE_AURA) || defined(OS_MACOSX) 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const uint16 c = GetCharacterFromKeyCode(key_code_, false); 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (c != 0) 193a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) shortcut += 194a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) static_cast<base::string16::value_type>(base::ToUpperASCII(c)); 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(TOOLKIT_GTK) 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gchar* name = NULL; 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (key_code_) { 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ui::VKEY_OEM_2: 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) name = static_cast<const gchar*>("/"); 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) name = gdk_keyval_name(gdk_keyval_to_lower(key_code_)); 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (name) { 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (name[0] != 0 && name[1] == 0) 207a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) shortcut += 208a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) static_cast<base::string16::value_type>(g_ascii_toupper(name[0])); 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 2105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) shortcut += base::UTF8ToUTF16(name); 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shortcut = l10n_util::GetStringUTF16(string_id); 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Checking whether the character used for the accelerator is alphanumeric. 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If it is not, then we need to adjust the string later on if the locale is 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // right-to-left. See below for more information of why such adjustment is 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // required. 221a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) base::string16 shortcut_rtl; 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool adjust_shortcut_for_rtl = false; 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (base::i18n::IsRTL() && shortcut.length() == 1 && 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !IsAsciiAlpha(shortcut[0]) && !IsAsciiDigit(shortcut[0])) { 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) adjust_shortcut_for_rtl = true; 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shortcut_rtl.assign(shortcut); 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IsShiftDown()) 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shortcut = l10n_util::GetStringFUTF16(IDS_APP_SHIFT_MODIFIER, shortcut); 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note that we use 'else-if' in order to avoid using Ctrl+Alt as a shortcut. 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // See http://blogs.msdn.com/oldnewthing/archive/2004/03/29/101121.aspx for 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // more information. 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IsCtrlDown()) 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shortcut = l10n_util::GetStringFUTF16(IDS_APP_CONTROL_MODIFIER, shortcut); 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (IsAltDown()) 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shortcut = l10n_util::GetStringFUTF16(IDS_APP_ALT_MODIFIER, shortcut); 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IsCmdDown()) 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shortcut = l10n_util::GetStringFUTF16(IDS_APP_COMMAND_MODIFIER, shortcut); 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For some reason, menus in Windows ignore standard Unicode directionality 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // marks (such as LRE, PDF, etc.). On RTL locales, we use RTL menus and 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // therefore any text we draw for the menu items is drawn in an RTL context. 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Thus, the text "Ctrl++" (which we currently use for the Zoom In option) 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // appears as "++Ctrl" in RTL because the Unicode BiDi algorithm puts 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // punctuations on the left when the context is right-to-left. Shortcuts that 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // do not end with a punctuation mark (such as "Ctrl+H" do not have this 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // problem). 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The only way to solve this problem is to adjust the string if the locale 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // is RTL so that it is drawn correctly in an RTL context. Instead of 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // returning "Ctrl++" in the above example, we return "++Ctrl". This will 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // cause the text to appear as "Ctrl++" when Windows draws the string in an 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // RTL context because the punctuation no longer appears at the end of the 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // string. 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(idana) bug# 1232732: this hack can be avoided if instead of using 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // views::Menu we use views::MenuItemView because the latter is a View 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // subclass and therefore it supports marking text as RTL or LTR using 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // standard Unicode directionality marks. 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (adjust_shortcut_for_rtl) { 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int key_length = static_cast<int>(shortcut_rtl.length()); 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_GT(key_length, 0); 2665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) shortcut_rtl.append(base::ASCIIToUTF16("+")); 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Subtracting the size of the shortcut key and 1 for the '+' sign. 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shortcut_rtl.append(shortcut, 0, shortcut.length() - key_length - 1); 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shortcut.swap(shortcut_rtl); 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return shortcut; 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace ui 277