cros_language_options_handler.cc revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
1// Copyright (c) 2012 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. 4 5#include "chrome/browser/ui/webui/options/chromeos/cros_language_options_handler.h" 6 7#include <map> 8#include <set> 9#include <vector> 10 11#include "base/bind.h" 12#include "base/bind_helpers.h" 13#include "base/i18n/rtl.h" 14#include "base/stringprintf.h" 15#include "base/utf_string_conversions.h" 16#include "base/values.h" 17#include "chrome/app/chrome_command_ids.h" 18#include "chrome/browser/browser_process.h" 19#include "chrome/browser/chromeos/input_method/input_method_configuration.h" 20#include "chrome/browser/chromeos/input_method/input_method_manager.h" 21#include "chrome/browser/chromeos/input_method/input_method_util.h" 22#include "chrome/browser/lifetime/application_lifetime.h" 23#include "chrome/browser/profiles/profile.h" 24#include "chrome/browser/ui/browser.h" 25#include "chrome/browser/ui/browser_finder.h" 26#include "content/public/browser/navigation_controller.h" 27#include "content/public/browser/user_metrics.h" 28#include "content/public/browser/web_contents.h" 29#include "grit/chromium_strings.h" 30#include "grit/generated_resources.h" 31#include "ui/base/l10n/l10n_util.h" 32 33using content::UserMetricsAction; 34 35namespace chromeos { 36namespace options { 37 38CrosLanguageOptionsHandler::CrosLanguageOptionsHandler() { 39} 40 41CrosLanguageOptionsHandler::~CrosLanguageOptionsHandler() { 42} 43 44void CrosLanguageOptionsHandler::GetLocalizedValues( 45 DictionaryValue* localized_strings) { 46 ::options::LanguageOptionsHandlerCommon::GetLocalizedValues( 47 localized_strings); 48 49 RegisterTitle(localized_strings, "languagePage", 50 IDS_OPTIONS_SETTINGS_LANGUAGES_AND_INPUT_DIALOG_TITLE); 51 localized_strings->SetString("ok_button", l10n_util::GetStringUTF16(IDS_OK)); 52 localized_strings->SetString("configure", 53 l10n_util::GetStringUTF16(IDS_OPTIONS_SETTINGS_LANGUAGES_CONFIGURE)); 54 localized_strings->SetString("input_method", 55 l10n_util::GetStringUTF16(IDS_OPTIONS_SETTINGS_LANGUAGES_INPUT_METHOD)); 56 localized_strings->SetString("please_add_another_input_method", 57 l10n_util::GetStringUTF16( 58 IDS_OPTIONS_SETTINGS_LANGUAGES_PLEASE_ADD_ANOTHER_INPUT_METHOD)); 59 localized_strings->SetString("input_method_instructions", 60 l10n_util::GetStringUTF16( 61 IDS_OPTIONS_SETTINGS_LANGUAGES_INPUT_METHOD_INSTRUCTIONS)); 62 localized_strings->SetString("switch_input_methods_hint", 63 l10n_util::GetStringUTF16( 64 IDS_OPTIONS_SETTINGS_LANGUAGES_SWITCH_INPUT_METHODS_HINT)); 65 localized_strings->SetString("select_previous_input_method_hint", 66 l10n_util::GetStringUTF16( 67 IDS_OPTIONS_SETTINGS_LANGUAGES_SELECT_PREVIOUS_INPUT_METHOD_HINT)); 68 localized_strings->SetString("restart_button", 69 l10n_util::GetStringUTF16( 70 IDS_OPTIONS_SETTINGS_LANGUAGES_SIGN_OUT_BUTTON)); 71 localized_strings->SetString("extension_ime_label", 72 l10n_util::GetStringUTF16( 73 IDS_OPTIONS_SETTINGS_LANGUAGES_INPUT_METHOD_EXTENSION_IME)); 74 localized_strings->SetString("extension_ime_description", 75 l10n_util::GetStringUTF16( 76 IDS_OPTIONS_SETTINGS_LANGUAGES_INPUT_METHOD_EXTENSION_DESCRIPTION)); 77 78 input_method::InputMethodManager* manager = 79 input_method::GetInputMethodManager(); 80 // GetSupportedInputMethods() never return NULL. 81 scoped_ptr<input_method::InputMethodDescriptors> descriptors( 82 manager->GetSupportedInputMethods()); 83 localized_strings->Set("languageList", GetLanguageList(*descriptors)); 84 localized_strings->Set("inputMethodList", GetInputMethodList(*descriptors)); 85 localized_strings->Set("extensionImeList", GetExtensionImeList()); 86} 87 88void CrosLanguageOptionsHandler::RegisterMessages() { 89 ::options::LanguageOptionsHandlerCommon::RegisterMessages(); 90 91 web_ui()->RegisterMessageCallback("inputMethodDisable", 92 base::Bind(&CrosLanguageOptionsHandler::InputMethodDisableCallback, 93 base::Unretained(this))); 94 web_ui()->RegisterMessageCallback("inputMethodEnable", 95 base::Bind(&CrosLanguageOptionsHandler::InputMethodEnableCallback, 96 base::Unretained(this))); 97 web_ui()->RegisterMessageCallback("inputMethodOptionsOpen", 98 base::Bind(&CrosLanguageOptionsHandler::InputMethodOptionsOpenCallback, 99 base::Unretained(this))); 100 web_ui()->RegisterMessageCallback("uiLanguageRestart", 101 base::Bind(&CrosLanguageOptionsHandler::RestartCallback, 102 base::Unretained(this))); 103} 104 105ListValue* CrosLanguageOptionsHandler::GetInputMethodList( 106 const input_method::InputMethodDescriptors& descriptors) { 107 input_method::InputMethodManager* manager = 108 input_method::GetInputMethodManager(); 109 110 ListValue* input_method_list = new ListValue(); 111 112 for (size_t i = 0; i < descriptors.size(); ++i) { 113 const input_method::InputMethodDescriptor& descriptor = 114 descriptors[i]; 115 const std::string language_code = descriptor.language_code(); 116 const std::string display_name = 117 manager->GetInputMethodUtil()->GetInputMethodDisplayNameFromId( 118 descriptor.id()); 119 DictionaryValue* dictionary = new DictionaryValue(); 120 dictionary->SetString("id", descriptor.id()); 121 dictionary->SetString("displayName", display_name); 122 123 // One input method can be associated with multiple languages, hence 124 // we use a dictionary here. 125 DictionaryValue* language_codes = new DictionaryValue(); 126 language_codes->SetBoolean(language_code, true); 127 // Check extra languages to see if there are languages associated with 128 // this input method. If these are present, add these. 129 const std::vector<std::string> extra_language_codes = 130 manager->GetInputMethodUtil()->GetExtraLanguageCodesFromId( 131 descriptor.id()); 132 for (size_t j = 0; j < extra_language_codes.size(); ++j) 133 language_codes->SetBoolean(extra_language_codes[j], true); 134 dictionary->Set("languageCodeSet", language_codes); 135 136 input_method_list->Append(dictionary); 137 } 138 139 return input_method_list; 140} 141 142ListValue* CrosLanguageOptionsHandler::GetLanguageList( 143 const input_method::InputMethodDescriptors& descriptors) { 144 std::set<std::string> language_codes; 145 // Collect the language codes from the supported input methods. 146 for (size_t i = 0; i < descriptors.size(); ++i) { 147 const input_method::InputMethodDescriptor& descriptor = descriptors[i]; 148 const std::string language_code = descriptor.language_code(); 149 language_codes.insert(language_code); 150 } 151 // Collect the language codes from extra languages. 152 const std::vector<std::string> extra_language_codes = 153 input_method::GetInputMethodManager()->GetInputMethodUtil() 154 ->GetExtraLanguageCodeList(); 155 for (size_t i = 0; i < extra_language_codes.size(); ++i) 156 language_codes.insert(extra_language_codes[i]); 157 158 // Map of display name -> {language code, native_display_name}. 159 // In theory, we should be able to create a map that is sorted by 160 // display names using ICU comparator, but doing it is hard, thus we'll 161 // use an auxiliary vector to achieve the same result. 162 typedef std::pair<std::string, string16> LanguagePair; 163 typedef std::map<string16, LanguagePair> LanguageMap; 164 LanguageMap language_map; 165 // The auxiliary vector mentioned above. 166 std::vector<string16> display_names; 167 168 // Build the list of display names, and build the language map. 169 for (std::set<std::string>::const_iterator iter = language_codes.begin(); 170 iter != language_codes.end(); ++iter) { 171 input_method::InputMethodUtil* input_method_util = 172 input_method::GetInputMethodManager()->GetInputMethodUtil(); 173 const string16 display_name = 174 input_method_util->GetLanguageDisplayNameFromCode(*iter); 175 const string16 native_display_name = 176 input_method::InputMethodUtil::GetLanguageNativeDisplayNameFromCode( 177 *iter); 178 display_names.push_back(display_name); 179 language_map[display_name] = 180 std::make_pair(*iter, native_display_name); 181 } 182 DCHECK_EQ(display_names.size(), language_map.size()); 183 184 // Sort display names using locale specific sorter. 185 l10n_util::SortStrings16(g_browser_process->GetApplicationLocale(), 186 &display_names); 187 188 // Build the language list from the language map. 189 ListValue* language_list = new ListValue(); 190 for (size_t i = 0; i < display_names.size(); ++i) { 191 // Sets the directionality of the display language name. 192 string16 display_name(display_names[i]); 193 bool markup_removal = 194 base::i18n::UnadjustStringForLocaleDirection(&display_name); 195 DCHECK(markup_removal); 196 bool has_rtl_chars = base::i18n::StringContainsStrongRTLChars(display_name); 197 std::string directionality = has_rtl_chars ? "rtl" : "ltr"; 198 199 const LanguagePair& pair = language_map[display_names[i]]; 200 DictionaryValue* dictionary = new DictionaryValue(); 201 dictionary->SetString("code", pair.first); 202 dictionary->SetString("displayName", display_names[i]); 203 dictionary->SetString("textDirection", directionality); 204 dictionary->SetString("nativeDisplayName", pair.second); 205 language_list->Append(dictionary); 206 } 207 208 return language_list; 209} 210 211base::ListValue* CrosLanguageOptionsHandler::GetExtensionImeList() { 212 input_method::InputMethodManager* manager = 213 input_method::GetInputMethodManager(); 214 215 input_method::InputMethodDescriptors descriptors; 216 manager->GetInputMethodExtensions(&descriptors); 217 218 ListValue* extension_ime_ids_list = new ListValue(); 219 220 for (size_t i = 0; i < descriptors.size(); ++i) { 221 const input_method::InputMethodDescriptor& descriptor = descriptors[i]; 222 DictionaryValue* dictionary = new DictionaryValue(); 223 dictionary->SetString("id", descriptor.id()); 224 dictionary->SetString("displayName", descriptor.name()); 225 extension_ime_ids_list->Append(dictionary); 226 } 227 228 return extension_ime_ids_list; 229} 230 231string16 CrosLanguageOptionsHandler::GetProductName() { 232 return l10n_util::GetStringUTF16(IDS_SHORT_PRODUCT_OS_NAME); 233} 234 235void CrosLanguageOptionsHandler::SetApplicationLocale( 236 const std::string& language_code) { 237 Profile::FromWebUI(web_ui())->ChangeAppLocale( 238 language_code, Profile::APP_LOCALE_CHANGED_VIA_SETTINGS); 239} 240 241void CrosLanguageOptionsHandler::RestartCallback(const ListValue* args) { 242 content::RecordAction(UserMetricsAction("LanguageOptions_SignOut")); 243 chrome::AttemptUserExit(); 244} 245 246void CrosLanguageOptionsHandler::InputMethodDisableCallback( 247 const ListValue* args) { 248 const std::string input_method_id = UTF16ToASCII(ExtractStringValue(args)); 249 const std::string action = base::StringPrintf( 250 "LanguageOptions_DisableInputMethod_%s", input_method_id.c_str()); 251 content::RecordComputedAction(action); 252} 253 254void CrosLanguageOptionsHandler::InputMethodEnableCallback( 255 const ListValue* args) { 256 const std::string input_method_id = UTF16ToASCII(ExtractStringValue(args)); 257 const std::string action = base::StringPrintf( 258 "LanguageOptions_EnableInputMethod_%s", input_method_id.c_str()); 259 content::RecordComputedAction(action); 260} 261 262void CrosLanguageOptionsHandler::InputMethodOptionsOpenCallback( 263 const ListValue* args) { 264 const std::string input_method_id = UTF16ToASCII(ExtractStringValue(args)); 265 const std::string action = base::StringPrintf( 266 "InputMethodOptions_Open_%s", input_method_id.c_str()); 267 content::RecordComputedAction(action); 268} 269 270} // namespace options 271} // namespace chromeos 272