1dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file. 4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "chrome/browser/chromeos/status/input_method_menu.h" 6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <string> 821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include <vector> 9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/string_split.h" 11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/string_util.h" 12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/time.h" 13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/utf_string_conversions.h" 14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/browser_process.h" 15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/chromeos/cros/cros_library.h" 16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/chromeos/input_method/input_method_util.h" 173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/browser/chromeos/language_preferences.h" 18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/metrics/user_metrics.h" 193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/browser/prefs/pref_service.h" 203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/common/pref_names.h" 21dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/common/notification_service.h" 22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "grit/generated_resources.h" 23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "grit/theme_resources.h" 2472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/l10n/l10n_util.h" 2572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/resource/resource_bundle.h" 26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// The language menu consists of 3 parts (in this order): 28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// (1) input method names. The size of the list is always >= 1. 30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// (2) input method properties. This list might be empty. 31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// (3) "Customize language and input..." button. 32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Example of the menu (Japanese): 34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// ============================== (border of the popup window) 36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// [ ] English (|index| in the following functions is 0) 37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// [*] Japanese 38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// [ ] Chinese (Simplified) 39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// ------------------------------ (separator) 40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// [*] Hiragana (index = 5, The property has 2 radio groups) 41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// [ ] Katakana 42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// [ ] HalfWidthKatakana 43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// [*] Roman 44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// [ ] Kana 45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// ------------------------------ (separator) 46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Customize language and input...(index = 11) 47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// ============================== (border of the popup window) 48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Example of the menu (Simplified Chinese): 50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// ============================== (border of the popup window) 52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// [ ] English 53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// [ ] Japanese 54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// [*] Chinese (Simplified) 55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// ------------------------------ (separator) 56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Switch to full letter mode (The property has 2 command buttons) 57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Switch to half punctuation mode 58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// ------------------------------ (separator) 59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Customize language and input... 60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// ============================== (border of the popup window) 61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace { 64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Constants to specify the type of items in |model_|. 66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochenum { 67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch COMMAND_ID_INPUT_METHODS = 0, // English, Chinese, Japanese, Arabic, ... 68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch COMMAND_ID_IME_PROPERTIES, // Hiragana, Katakana, ... 69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch COMMAND_ID_CUSTOMIZE_LANGUAGE, // "Customize language and input..." button. 70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// A group ID for IME properties starts from 0. We use the huge value for the 73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// input method list to avoid conflict. 74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst int kRadioGroupLanguage = 1 << 16; 75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst int kRadioGroupNone = -1; 76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 77731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// A mapping from an input method id to a string for the language indicator. The 78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// mapping is necessary since some input methods belong to the same language. 79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// For example, both "xkb:us::eng" and "xkb:us:dvorak:eng" are for US English. 80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst struct { 81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const char* input_method_id; 82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const char* indicator_text; 83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} kMappingFromIdToIndicatorText[] = { 84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // To distinguish from "xkb:us::eng" 85201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch { "xkb:us:altgr-intl:eng", "EXTD" }, 86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { "xkb:us:dvorak:eng", "DV" }, 87201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch { "xkb:us:intl:eng", "INTL" }, 8821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen { "xkb:us:colemak:eng", "CO" }, 8972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen { "xkb:de:neo:ger", "NEO" }, 90ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // To distinguish from "xkb:gb::eng" 91ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen { "xkb:gb:dvorak:eng", "DV" }, 92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // To distinguish from "xkb:jp::jpn" 93731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick { "mozc", "\xe3\x81\x82" }, // U+3042, Japanese Hiragana letter A in UTF-8. 94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { "mozc-dv", "\xe3\x81\x82" }, 95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { "mozc-jp", "\xe3\x81\x82" }, 96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // For simplified Chinese input methods 97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { "pinyin", "\xe6\x8b\xbc" }, // U+62FC 98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // For traditional Chinese input methods 99ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen { "mozc-chewing", "\xe9\x85\xb7" }, // U+9177 100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { "m17n:zh:cangjie", "\xe5\x80\x89" }, // U+5009 1013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick { "m17n:zh:quick", "\xe9\x80\x9f" }, // U+901F 1023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // For Hangul input method. 1033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick { "hangul", "\xed\x95\x9c" }, // U+D55C 104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst size_t kMappingFromIdToIndicatorTextLen = 106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ARRAYSIZE_UNSAFE(kMappingFromIdToIndicatorText); 107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Returns the language name for the given |language_code|. 109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstd::wstring GetLanguageName(const std::string& language_code) { 110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const string16 language_name = l10n_util::GetDisplayNameForLocale( 111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch language_code, g_browser_process->GetApplicationLocale(), true); 112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return UTF16ToWide(language_name); 113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} // namespace 116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace chromeos { 118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//////////////////////////////////////////////////////////////////////////////// 120731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// InputMethodMenu 121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 122731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickInputMethodMenu::InputMethodMenu(PrefService* pref_service, 12372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen StatusAreaHost::ScreenMode screen_mode, 12472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen bool for_out_of_box_experience_dialog) 125731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick : input_method_descriptors_(CrosLibrary::Get()->GetInputMethodLibrary()-> 126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GetActiveInputMethods()), 127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch model_(NULL), 128513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // Be aware that the constructor of |input_method_menu_| calls 129513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // GetItemCount() in this class. Therefore, GetItemCount() have to return 130513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // 0 when |model_| is NULL. 131513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch ALLOW_THIS_IN_INITIALIZER_LIST(input_method_menu_(this)), 132513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch minimum_input_method_menu_width_(0), 133731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick pref_service_(pref_service), 13472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen screen_mode_(screen_mode), 13572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen for_out_of_box_experience_dialog_(for_out_of_box_experience_dialog) { 136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(input_method_descriptors_.get() && 137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch !input_method_descriptors_->empty()); 138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Sync current and previous input methods on Chrome prefs with ibus-daemon. 14072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (pref_service_ && (screen_mode_ == StatusAreaHost::kBrowserMode)) { 141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch previous_input_method_pref_.Init( 142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch prefs::kLanguagePreviousInputMethod, pref_service, this); 143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch current_input_method_pref_.Init( 144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch prefs::kLanguageCurrentInputMethod, pref_service, this); 145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 14772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen InputMethodLibrary* library = CrosLibrary::Get()->GetInputMethodLibrary(); 14872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen library->AddObserver(this); // FirstObserverIsAdded() might be called back. 14972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 15072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (screen_mode_ == StatusAreaHost::kLoginMode) { 15172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // This button is for the login screen. 152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch registrar_.Add(this, 153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NotificationType::LOGIN_USER_CHANGED, 154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NotificationService::AllSources()); 155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 158731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickInputMethodMenu::~InputMethodMenu() { 15972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // RemoveObserver() is no-op if |this| object is already removed from the 16072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // observer list. 161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CrosLibrary::Get()->GetInputMethodLibrary()->RemoveObserver(this); 162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//////////////////////////////////////////////////////////////////////////////// 16572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// ui::MenuModel implementation: 166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 167731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickint InputMethodMenu::GetCommandIdAt(int index) const { 16872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return index; 169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 17121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenbool InputMethodMenu::IsItemDynamicAt(int index) const { 172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Menu content for the language button could change time by time. 173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 176731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickbool InputMethodMenu::GetAcceleratorAt( 17772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen int index, ui::Accelerator* accelerator) const { 178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Views for Chromium OS does not support accelerators yet. 179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 182731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickbool InputMethodMenu::IsItemCheckedAt(int index) const { 183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK_GE(index, 0); 184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(input_method_descriptors_.get()); 185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (IndexIsInInputMethodList(index)) { 187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const InputMethodDescriptor& input_method 188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch = input_method_descriptors_->at(index); 189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return input_method == CrosLibrary::Get()->GetInputMethodLibrary()-> 190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch current_input_method(); 191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (GetPropertyIndex(index, &index)) { 194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const ImePropertyList& property_list 195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch = CrosLibrary::Get()->GetInputMethodLibrary()->current_ime_properties(); 196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return property_list.at(index).is_selection_item_checked; 197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Separator(s) or the "Customize language and input..." button. 200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 203731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickint InputMethodMenu::GetGroupIdAt(int index) const { 204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK_GE(index, 0); 205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (IndexIsInInputMethodList(index)) { 20772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return for_out_of_box_experience_dialog_ ? 208513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch kRadioGroupNone : kRadioGroupLanguage; 209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (GetPropertyIndex(index, &index)) { 212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const ImePropertyList& property_list 213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch = CrosLibrary::Get()->GetInputMethodLibrary()->current_ime_properties(); 214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return property_list.at(index).selection_item_id; 215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return kRadioGroupNone; 218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 220731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickbool InputMethodMenu::HasIcons() const { 221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We don't support icons on Chrome OS. 222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 225ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool InputMethodMenu::GetIconAt(int index, SkBitmap* icon) { 226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 22972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenui::ButtonMenuItemModel* InputMethodMenu::GetButtonMenuItemAt( 230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int index) const { 231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return NULL; 232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 234731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickbool InputMethodMenu::IsEnabledAt(int index) const { 235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Just return true so all input method names and input method propertie names 236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // could be clicked. 237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 24072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenui::MenuModel* InputMethodMenu::GetSubmenuModelAt(int index) const { 241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We don't use nested menus. 242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return NULL; 243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 245731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickvoid InputMethodMenu::HighlightChangedTo(int index) { 246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Views for Chromium OS does not support this interface yet. 247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 249731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickvoid InputMethodMenu::MenuWillShow() { 250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Views for Chromium OS does not support this interface yet. 251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 253ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid InputMethodMenu::SetMenuModelDelegate(ui::MenuModelDelegate* delegate) { 254ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Not needed for current usage. 255ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 256ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 257731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickint InputMethodMenu::GetItemCount() const { 258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!model_.get()) { 259731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Model is not constructed yet. This means that 260731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // InputMethodMenu is being constructed. Return zero. 261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return 0; 262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return model_->GetItemCount(); 264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 26672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenui::MenuModel::ItemType InputMethodMenu::GetTypeAt(int index) const { 267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK_GE(index, 0); 268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (IndexPointsToConfigureImeMenuItem(index)) { 27072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return ui::MenuModel::TYPE_COMMAND; // "Customize language and input" 271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (IndexIsInInputMethodList(index)) { 27472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return for_out_of_box_experience_dialog_ ? 27572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ui::MenuModel::TYPE_COMMAND : ui::MenuModel::TYPE_RADIO; 276c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 277c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (GetPropertyIndex(index, &index)) { 279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const ImePropertyList& property_list 280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch = CrosLibrary::Get()->GetInputMethodLibrary()->current_ime_properties(); 281c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (property_list.at(index).is_selection_item) { 28272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return ui::MenuModel::TYPE_RADIO; 283c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 28472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return ui::MenuModel::TYPE_COMMAND; 285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 286c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 28772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return ui::MenuModel::TYPE_SEPARATOR; 288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 290731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickstring16 InputMethodMenu::GetLabelAt(int index) const { 291c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK_GE(index, 0); 292c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(input_method_descriptors_.get()); 293c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 294c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We use IDS_OPTIONS_SETTINGS_LANGUAGES_CUSTOMIZE here as the button 295c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // opens the same dialog that is opened from the main options dialog. 296c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (IndexPointsToConfigureImeMenuItem(index)) { 297c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return l10n_util::GetStringUTF16(IDS_OPTIONS_SETTINGS_LANGUAGES_CUSTOMIZE); 298c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 299c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 300c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::wstring name; 301c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (IndexIsInInputMethodList(index)) { 3023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick name = GetTextForMenu(input_method_descriptors_->at(index)); 303c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else if (GetPropertyIndex(index, &index)) { 304ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen InputMethodLibrary* library = CrosLibrary::Get()->GetInputMethodLibrary(); 305ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const ImePropertyList& property_list = library->current_ime_properties(); 306ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const std::string& input_method_id = library->current_input_method().id; 307ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return input_method::GetStringUTF16( 308ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen property_list.at(index).label, input_method_id); 309c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 310c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 311c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return WideToUTF16(name); 312c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 313c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 314731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickvoid InputMethodMenu::ActivatedAt(int index) { 315c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK_GE(index, 0); 316c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(input_method_descriptors_.get()); 317c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 318c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (IndexPointsToConfigureImeMenuItem(index)) { 319731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick OpenConfigUI(); 320c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 321c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 322c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 323c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (IndexIsInInputMethodList(index)) { 324c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Inter-IME switching. 325c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const InputMethodDescriptor& input_method 326c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch = input_method_descriptors_->at(index); 327c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CrosLibrary::Get()->GetInputMethodLibrary()->ChangeInputMethod( 328c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch input_method.id); 32972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen UserMetrics::RecordAction( 33072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen UserMetricsAction("LanguageMenuButton_InputMethodChanged")); 331c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 332c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 333c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 334c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (GetPropertyIndex(index, &index)) { 335c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Intra-IME switching (e.g. Japanese-Hiragana to Japanese-Katakana). 336c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const ImePropertyList& property_list 337c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch = CrosLibrary::Get()->GetInputMethodLibrary()->current_ime_properties(); 338c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const std::string key = property_list.at(index).key; 339c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (property_list.at(index).is_selection_item) { 340c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Radio button is clicked. 341c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const int id = property_list.at(index).selection_item_id; 342c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // First, deactivate all other properties in the same radio group. 343c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (int i = 0; i < static_cast<int>(property_list.size()); ++i) { 344c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (i != index && id == property_list.at(i).selection_item_id) { 345c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CrosLibrary::Get()->GetInputMethodLibrary()->SetImePropertyActivated( 346c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch property_list.at(i).key, false); 347c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 348c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 349c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Then, activate the property clicked. 350c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CrosLibrary::Get()->GetInputMethodLibrary()->SetImePropertyActivated( 351c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch key, true); 352c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 353c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Command button like "Switch to half punctuation mode" is clicked. 354c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We can always use "Deactivate" for command buttons. 355c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CrosLibrary::Get()->GetInputMethodLibrary()->SetImePropertyActivated( 356c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch key, false); 357c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 358c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 359c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 360c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 361c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch LOG(ERROR) << "Unexpected index: " << index; 362c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 363c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 364c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//////////////////////////////////////////////////////////////////////////////// 365731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// views::ViewMenuDelegate implementation: 366c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 367731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickvoid InputMethodMenu::RunMenu( 368731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick views::View* unused_source, const gfx::Point& pt) { 369731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick PrepareForMenuOpen(); 370513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch input_method_menu_.RunMenuAt(pt, views::Menu2::ALIGN_TOPRIGHT); 371c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 372c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 373c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//////////////////////////////////////////////////////////////////////////////// 374c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// InputMethodLibrary::Observer implementation: 375c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 37621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid InputMethodMenu::InputMethodChanged( 37721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen InputMethodLibrary* obj, 37821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen const InputMethodDescriptor& current_input_method, 37921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen size_t num_active_input_methods) { 38021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen UpdateUIFromInputMethod(current_input_method, num_active_input_methods); 38121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 382c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 38321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid InputMethodMenu::PreferenceUpdateNeeded( 38421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen InputMethodLibrary* obj, 38521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen const InputMethodDescriptor& previous_input_method, 38621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen const InputMethodDescriptor& current_input_method) { 38772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (screen_mode_ == StatusAreaHost::kBrowserMode) { 388731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (pref_service_) { // make sure we're not in unit tests. 389c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Sometimes (e.g. initial boot) |previous_input_method.id| is empty. 390c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch previous_input_method_pref_.SetValue(previous_input_method.id); 391c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch current_input_method_pref_.SetValue(current_input_method.id); 392ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen pref_service_->ScheduleSavePersistentPrefs(); 393c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 39472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } else if (screen_mode_ == StatusAreaHost::kLoginMode) { 39572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (g_browser_process && g_browser_process->local_state()) { 39672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen g_browser_process->local_state()->SetString( 39772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen language_prefs::kPreferredKeyboardLayout, current_input_method.id); 39872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen g_browser_process->local_state()->SavePersistentPrefs(); 39972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 40072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 40172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 40272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 403ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid InputMethodMenu::PropertyListChanged( 404ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen InputMethodLibrary* obj, 405ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const ImePropertyList& current_ime_properties) { 406ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Usual order of notifications of input method change is: 407ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // 1. RegisterProperties(empty) 408ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // 2. RegisterProperties(list-of-new-properties) 409ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // 3. GlobalInputMethodChanged 410ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // However, due to the asynchronicity, we occasionally (but rarely) face to 411ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // 1. RegisterProperties(empty) 412ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // 2. GlobalInputMethodChanged 413ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // 3. RegisterProperties(list-of-new-properties) 414ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // this order. On this unusual case, we must rebuild the menu after the last 415ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // RegisterProperties. For the other cases, no rebuild is needed. Actually 416ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // it is better to be avoided. Otherwise users can sometimes observe the 417ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // awkward clear-then-register behavior. 418ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!current_ime_properties.empty()) { 419ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen InputMethodLibrary* library = CrosLibrary::Get()->GetInputMethodLibrary(); 420ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const InputMethodDescriptor& input_method = library->current_input_method(); 421ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen size_t num_active_input_methods = library->GetNumActiveInputMethods(); 422ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen UpdateUIFromInputMethod(input_method, num_active_input_methods); 423ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 424ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 425ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 42672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid InputMethodMenu::FirstObserverIsAdded(InputMethodLibrary* obj) { 42772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // NOTICE: Since this function might be called from the constructor of this 42872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // class, it's better to avoid calling virtual functions. 42972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 43072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (pref_service_ && (screen_mode_ == StatusAreaHost::kBrowserMode)) { 43172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Get the input method name in the Preferences file which was in use last 43272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // time, and switch to the method. We remember two input method names in the 43372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // preference so that the Control+space hot-key could work fine from the 43472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // beginning. InputMethodChanged() will be called soon and the indicator 43572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // will be updated. 43672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen InputMethodLibrary* library = CrosLibrary::Get()->GetInputMethodLibrary(); 43772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const std::string previous_input_method_id = 43872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen previous_input_method_pref_.GetValue(); 43972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (!previous_input_method_id.empty()) { 44072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen library->ChangeInputMethod(previous_input_method_id); 44172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 44272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const std::string current_input_method_id = 44372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen current_input_method_pref_.GetValue(); 44472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (!current_input_method_id.empty()) { 44572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen library->ChangeInputMethod(current_input_method_id); 446c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 447c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 448c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 449c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 450731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickvoid InputMethodMenu::PrepareForMenuOpen() { 451731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick UserMetrics::RecordAction(UserMetricsAction("LanguageMenuButton_Open")); 45272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen PrepareMenu(); 45372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 45472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 45572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid InputMethodMenu::PrepareMenu() { 456731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick input_method_descriptors_.reset(CrosLibrary::Get()->GetInputMethodLibrary()-> 457731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick GetActiveInputMethods()); 458731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick RebuildModel(); 459513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch input_method_menu_.Rebuild(); 460513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (minimum_input_method_menu_width_ > 0) { 461513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch input_method_menu_.SetMinimumWidth(minimum_input_method_menu_width_); 462731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 463c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 464c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 46521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid InputMethodMenu::ActiveInputMethodsChanged( 46621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen InputMethodLibrary* obj, 46721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen const InputMethodDescriptor& current_input_method, 46821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen size_t num_active_input_methods) { 469731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Update the icon if active input methods are changed. See also 47021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // comments in UpdateUI() in input_method_menu_button.cc. 47121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen UpdateUIFromInputMethod(current_input_method, num_active_input_methods); 472c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 473c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 474731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickvoid InputMethodMenu::UpdateUIFromInputMethod( 47521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen const InputMethodDescriptor& input_method, 47621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen size_t num_active_input_methods) { 477c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const std::wstring name = GetTextForIndicator(input_method); 4783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const std::wstring tooltip = GetTextForMenu(input_method); 47921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen UpdateUI(input_method.id, name, tooltip, num_active_input_methods); 480c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 481c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 482731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickvoid InputMethodMenu::RebuildModel() { 48372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen model_.reset(new ui::SimpleMenuModel(NULL)); 484c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch string16 dummy_label = UTF8ToUTF16(""); 485c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Indicates if separator's needed before each section. 486c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool need_separator = false; 487c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 488c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!input_method_descriptors_->empty()) { 489c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We "abuse" the command_id and group_id arguments of AddRadioItem method. 490c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // A COMMAND_ID_XXX enum value is passed as command_id, and array index of 491c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // |input_method_descriptors_| or |property_list| is passed as group_id. 492c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (size_t i = 0; i < input_method_descriptors_->size(); ++i) { 493c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch model_->AddRadioItem(COMMAND_ID_INPUT_METHODS, dummy_label, i); 494c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 4953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 496c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch need_separator = true; 497c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 498c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 499c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const ImePropertyList& property_list 500c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch = CrosLibrary::Get()->GetInputMethodLibrary()->current_ime_properties(); 501c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!property_list.empty()) { 502731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (need_separator) { 503c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch model_->AddSeparator(); 504731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 505c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (size_t i = 0; i < property_list.size(); ++i) { 506c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch model_->AddRadioItem(COMMAND_ID_IME_PROPERTIES, dummy_label, i); 507c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 508c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch need_separator = true; 509c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 510c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 511731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (ShouldSupportConfigUI()) { 512c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Note: We use AddSeparator() for separators, and AddRadioItem() for all 513c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // other items even if an item is not actually a radio item. 514731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (need_separator) { 515c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch model_->AddSeparator(); 516731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 517c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch model_->AddRadioItem(COMMAND_ID_CUSTOMIZE_LANGUAGE, dummy_label, 518c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 0 /* dummy */); 519c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 520c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 521c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 522731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickbool InputMethodMenu::IndexIsInInputMethodList(int index) const { 523c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK_GE(index, 0); 524c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(model_.get()); 525c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (index >= model_->GetItemCount()) { 526c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 527c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 528c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 52972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return ((model_->GetTypeAt(index) == ui::MenuModel::TYPE_RADIO) && 530c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch (model_->GetCommandIdAt(index) == COMMAND_ID_INPUT_METHODS) && 531c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch input_method_descriptors_.get() && 532c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch (index < static_cast<int>(input_method_descriptors_->size()))); 533c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 534c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 535731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickbool InputMethodMenu::GetPropertyIndex(int index, int* property_index) const { 536c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK_GE(index, 0); 537c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(property_index); 538c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(model_.get()); 539c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (index >= model_->GetItemCount()) { 540c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 541c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 542c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 54372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if ((model_->GetTypeAt(index) == ui::MenuModel::TYPE_RADIO) && 544c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch (model_->GetCommandIdAt(index) == COMMAND_ID_IME_PROPERTIES)) { 545c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const int tmp_property_index = model_->GetGroupIdAt(index); 546c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const ImePropertyList& property_list 547c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch = CrosLibrary::Get()->GetInputMethodLibrary()->current_ime_properties(); 548c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (tmp_property_index < static_cast<int>(property_list.size())) { 549c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *property_index = tmp_property_index; 550c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 551c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 552c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 553c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 554c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 555c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 556731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickbool InputMethodMenu::IndexPointsToConfigureImeMenuItem(int index) const { 557c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK_GE(index, 0); 558c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(model_.get()); 559c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (index >= model_->GetItemCount()) { 560c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 561c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 562c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 56372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return ((model_->GetTypeAt(index) == ui::MenuModel::TYPE_RADIO) && 564c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch (model_->GetCommandIdAt(index) == COMMAND_ID_CUSTOMIZE_LANGUAGE)); 565c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 566c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 567731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickstd::wstring InputMethodMenu::GetTextForIndicator( 568c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const InputMethodDescriptor& input_method) { 569c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // For the status area, we use two-letter, upper-case language code like 570c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // "US" and "JP". 571c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::wstring text; 572c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 573c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Check special cases first. 574c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (size_t i = 0; i < kMappingFromIdToIndicatorTextLen; ++i) { 575c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (kMappingFromIdToIndicatorText[i].input_method_id == input_method.id) { 576c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch text = UTF8ToWide(kMappingFromIdToIndicatorText[i].indicator_text); 577c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 578c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 579c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 580c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 58172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Display the keyboard layout name when using a keyboard layout. 58272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (text.empty() && input_method::IsKeyboardLayout(input_method.id)) { 583c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const size_t kMaxKeyboardLayoutNameLen = 2; 584c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const std::wstring keyboard_layout = UTF8ToWide( 585c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch input_method::GetKeyboardLayoutName(input_method.id)); 586c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch text = StringToUpperASCII(keyboard_layout).substr( 587c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 0, kMaxKeyboardLayoutNameLen); 588c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 589c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 590c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // TODO(yusukes): Some languages have two or more input methods. For example, 591c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Thai has 3, Vietnamese has 4. If these input methods could be activated at 592c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // the same time, we should do either of the following: 593c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // (1) Add mappings to |kMappingFromIdToIndicatorText| 594c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // (2) Add suffix (1, 2, ...) to |text| when ambiguous. 595c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 596c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (text.empty()) { 597c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const size_t kMaxLanguageNameLen = 2; 598c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string language_code = 599c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch input_method::GetLanguageCodeFromDescriptor(input_method); 600c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 601c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Use "CN" for simplified Chinese and "TW" for traditonal Chinese, 602c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // rather than "ZH". 603c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (StartsWithASCII(language_code, "zh-", false)) { 604c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<std::string> portions; 605731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick base::SplitString(language_code, '-', &portions); 606c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (portions.size() >= 2 && !portions[1].empty()) { 607c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch language_code = portions[1]; 608c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 609c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 610c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 611c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch text = StringToUpperASCII(UTF8ToWide(language_code)).substr( 612c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 0, kMaxLanguageNameLen); 613c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 614c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(!text.empty()); 615c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return text; 616c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 617c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 618731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickstd::wstring InputMethodMenu::GetTextForMenu( 6193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const InputMethodDescriptor& input_method) { 6203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // We don't show language here. Name of keyboard layout or input method 6213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // usually imply (or explicitly include) its language. 6223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 6233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Special case for Dutch, French and German: these languages have multiple 6243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // keyboard layouts and share the same laout of keyboard (Belgian). We need to 6253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // show explicitly the language for the layout. 6263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // For Arabic and Hindi: they share "Standard Input Method". 627c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const std::string language_code 628c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch = input_method::GetLanguageCodeFromDescriptor(input_method); 629c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::wstring text; 6303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (language_code == "ar" || 6313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick language_code == "hi" || 6323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick language_code == "nl" || 6333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick language_code == "fr" || 6343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick language_code == "de") { 6353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick text = GetLanguageName(language_code) + L" - "; 636c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 637ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen text += input_method::GetString(input_method.display_name, input_method.id); 638c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 639c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(!text.empty()); 640c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return text; 641c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 642c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 643731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickvoid InputMethodMenu::RegisterPrefs(PrefService* local_state) { 644731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick local_state->RegisterStringPref(language_prefs::kPreferredKeyboardLayout, ""); 645c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 646c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 647731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickvoid InputMethodMenu::Observe(NotificationType type, 648731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const NotificationSource& source, 649731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const NotificationDetails& details) { 650c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (type == NotificationType::LOGIN_USER_CHANGED) { 65172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // When a user logs in, we should remove |this| object from the observer 65272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // list so that PreferenceUpdateNeeded() does not update the local state 65372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // anymore. 65472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen CrosLibrary::Get()->GetInputMethodLibrary()->RemoveObserver(this); 655c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 656c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 657c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 658731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickvoid InputMethodMenu::SetMinimumWidth(int width) { 659731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // On the OOBE network selection screen, fixed width menu would be preferable. 660513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch minimum_input_method_menu_width_ = width; 661731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 662731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 663c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} // namespace chromeos 664