1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 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/utf_string_conversions.h" 12 #include "base/values.h" 13 #include "chrome/app/chrome_command_ids.h" 14 #include "chrome/browser/browser_process.h" 15 #include "chrome/browser/metrics/user_metrics.h" 16 #include "chrome/browser/profiles/profile.h" 17 #include "chrome/browser/ui/browser.h" 18 #include "content/browser/tab_contents/tab_contents.h" 19 #include "grit/chromium_strings.h" 20 #include "grit/generated_resources.h" 21 #include "ui/base/l10n/l10n_util.h" 22 23 #include "chrome/browser/chromeos/cros/cros_library.h" 24 #include "chrome/browser/chromeos/cros/input_method_library.h" 25 26 namespace chromeos { 27 28 CrosLanguageOptionsHandler::CrosLanguageOptionsHandler() { 29 } 30 31 CrosLanguageOptionsHandler::~CrosLanguageOptionsHandler() { 32 } 33 34 void CrosLanguageOptionsHandler::GetLocalizedValues( 35 DictionaryValue* localized_strings) { 36 LanguageOptionsHandlerCommon::GetLocalizedValues(localized_strings); 37 38 localized_strings->SetString("ok_button", l10n_util::GetStringUTF16(IDS_OK)); 39 localized_strings->SetString("configure", 40 l10n_util::GetStringUTF16(IDS_OPTIONS_SETTINGS_LANGUAGES_CONFIGURE)); 41 localized_strings->SetString("input_method", 42 l10n_util::GetStringUTF16(IDS_OPTIONS_SETTINGS_LANGUAGES_INPUT_METHOD)); 43 localized_strings->SetString("please_add_another_input_method", 44 l10n_util::GetStringUTF16( 45 IDS_OPTIONS_SETTINGS_LANGUAGES_PLEASE_ADD_ANOTHER_INPUT_METHOD)); 46 localized_strings->SetString("input_method_instructions", 47 l10n_util::GetStringUTF16( 48 IDS_OPTIONS_SETTINGS_LANGUAGES_INPUT_METHOD_INSTRUCTIONS)); 49 localized_strings->SetString("switch_input_methods_hint", 50 l10n_util::GetStringFUTF16( 51 IDS_OPTIONS_SETTINGS_LANGUAGES_SWITCH_INPUT_METHODS_HINT, 52 ASCIIToUTF16("alt+shift"))); 53 localized_strings->SetString("select_previous_input_method_hint", 54 l10n_util::GetStringFUTF16( 55 IDS_OPTIONS_SETTINGS_LANGUAGES_SELECT_PREVIOUS_INPUT_METHOD_HINT, 56 ASCIIToUTF16("ctrl+space"))); 57 localized_strings->SetString("restart_button", 58 l10n_util::GetStringUTF16( 59 IDS_OPTIONS_SETTINGS_LANGUAGES_SIGN_OUT_BUTTON)); 60 61 // GetSupportedInputMethods() never return NULL. 62 InputMethodLibrary *im_library = 63 CrosLibrary::Get()->GetInputMethodLibrary(); 64 scoped_ptr<chromeos::InputMethodDescriptors> descriptors( 65 im_library->GetSupportedInputMethods()); 66 localized_strings->Set("languageList", GetLanguageList(*descriptors)); 67 localized_strings->Set("inputMethodList", GetInputMethodList(*descriptors)); 68 } 69 70 void CrosLanguageOptionsHandler::RegisterMessages() { 71 LanguageOptionsHandlerCommon::RegisterMessages(); 72 73 web_ui_->RegisterMessageCallback("inputMethodDisable", 74 NewCallback(this, 75 &CrosLanguageOptionsHandler::InputMethodDisableCallback)); 76 web_ui_->RegisterMessageCallback("inputMethodEnable", 77 NewCallback(this, 78 &CrosLanguageOptionsHandler::InputMethodEnableCallback)); 79 web_ui_->RegisterMessageCallback("inputMethodOptionsOpen", 80 NewCallback(this, 81 &CrosLanguageOptionsHandler::InputMethodOptionsOpenCallback)); 82 web_ui_->RegisterMessageCallback("uiLanguageRestart", 83 NewCallback(this, &CrosLanguageOptionsHandler::RestartCallback)); 84 } 85 86 ListValue* CrosLanguageOptionsHandler::GetInputMethodList( 87 const chromeos::InputMethodDescriptors& descriptors) { 88 ListValue* input_method_list = new ListValue(); 89 90 for (size_t i = 0; i < descriptors.size(); ++i) { 91 const chromeos::InputMethodDescriptor& descriptor = descriptors[i]; 92 const std::string language_code = 93 chromeos::input_method::GetLanguageCodeFromDescriptor(descriptor); 94 const std::string display_name = 95 chromeos::input_method::GetInputMethodDisplayNameFromId(descriptor.id); 96 97 DictionaryValue* dictionary = new DictionaryValue(); 98 dictionary->SetString("id", descriptor.id); 99 dictionary->SetString("displayName", display_name); 100 101 // One input method can be associated with multiple languages, hence 102 // we use a dictionary here. 103 DictionaryValue* language_codes = new DictionaryValue(); 104 language_codes->SetBoolean(language_code, true); 105 // Check kExtraLanguages to see if there are languages associated with 106 // this input method. If these are present, add these. 107 for (size_t j = 0; j < arraysize(chromeos::input_method::kExtraLanguages); 108 ++j) { 109 const std::string extra_input_method_id = 110 chromeos::input_method::kExtraLanguages[j].input_method_id; 111 const std::string extra_language_code = 112 chromeos::input_method::kExtraLanguages[j].language_code; 113 if (extra_input_method_id == descriptor.id) { 114 language_codes->SetBoolean(extra_language_code, true); 115 } 116 } 117 dictionary->Set("languageCodeSet", language_codes); 118 119 input_method_list->Append(dictionary); 120 } 121 122 return input_method_list; 123 } 124 125 ListValue* CrosLanguageOptionsHandler::GetLanguageList( 126 const chromeos::InputMethodDescriptors& descriptors) { 127 std::set<std::string> language_codes; 128 // Collect the language codes from the supported input methods. 129 for (size_t i = 0; i < descriptors.size(); ++i) { 130 const chromeos::InputMethodDescriptor& descriptor = descriptors[i]; 131 const std::string language_code = 132 chromeos::input_method::GetLanguageCodeFromDescriptor(descriptor); 133 language_codes.insert(language_code); 134 } 135 // Collect the language codes from kExtraLanguages. 136 for (size_t i = 0; i < arraysize(chromeos::input_method::kExtraLanguages); 137 ++i) { 138 const char* language_code = 139 chromeos::input_method::kExtraLanguages[i].language_code; 140 language_codes.insert(language_code); 141 } 142 143 // Map of display name -> {language code, native_display_name}. 144 // In theory, we should be able to create a map that is sorted by 145 // display names using ICU comparator, but doing it is hard, thus we'll 146 // use an auxiliary vector to achieve the same result. 147 typedef std::pair<std::string, string16> LanguagePair; 148 typedef std::map<string16, LanguagePair> LanguageMap; 149 LanguageMap language_map; 150 // The auxiliary vector mentioned above. 151 std::vector<string16> display_names; 152 153 // Build the list of display names, and build the language map. 154 for (std::set<std::string>::const_iterator iter = language_codes.begin(); 155 iter != language_codes.end(); ++iter) { 156 const string16 display_name = 157 chromeos::input_method::GetLanguageDisplayNameFromCode(*iter); 158 const string16 native_display_name = 159 chromeos::input_method::GetLanguageNativeDisplayNameFromCode(*iter); 160 display_names.push_back(display_name); 161 language_map[display_name] = 162 std::make_pair(*iter, native_display_name); 163 } 164 DCHECK_EQ(display_names.size(), language_map.size()); 165 166 // Sort display names using locale specific sorter. 167 l10n_util::SortStrings16(g_browser_process->GetApplicationLocale(), 168 &display_names); 169 170 // Build the language list from the language map. 171 ListValue* language_list = new ListValue(); 172 for (size_t i = 0; i < display_names.size(); ++i) { 173 const LanguagePair& pair = language_map[display_names[i]]; 174 DictionaryValue* dictionary = new DictionaryValue(); 175 dictionary->SetString("code", pair.first); 176 dictionary->SetString("displayName", display_names[i]); 177 dictionary->SetString("nativeDisplayName", pair.second); 178 language_list->Append(dictionary); 179 } 180 181 return language_list; 182 } 183 184 string16 CrosLanguageOptionsHandler::GetProductName() { 185 return l10n_util::GetStringUTF16(IDS_PRODUCT_OS_NAME); 186 } 187 188 void CrosLanguageOptionsHandler::SetApplicationLocale( 189 const std::string& language_code) { 190 web_ui_->GetProfile()->ChangeAppLocale( 191 language_code, Profile::APP_LOCALE_CHANGED_VIA_SETTINGS); 192 } 193 194 void CrosLanguageOptionsHandler::RestartCallback(const ListValue* args) { 195 UserMetrics::RecordAction(UserMetricsAction("LanguageOptions_SignOut")); 196 197 Browser* browser = Browser::GetBrowserForController( 198 &web_ui_->tab_contents()->controller(), NULL); 199 if (browser) 200 browser->ExecuteCommand(IDC_EXIT); 201 } 202 203 void CrosLanguageOptionsHandler::InputMethodDisableCallback( 204 const ListValue* args) { 205 const std::string input_method_id = UTF16ToASCII(ExtractStringValue(args)); 206 const std::string action = StringPrintf( 207 "LanguageOptions_DisableInputMethod_%s", input_method_id.c_str()); 208 UserMetrics::RecordComputedAction(action); 209 } 210 211 void CrosLanguageOptionsHandler::InputMethodEnableCallback( 212 const ListValue* args) { 213 const std::string input_method_id = UTF16ToASCII(ExtractStringValue(args)); 214 const std::string action = StringPrintf( 215 "LanguageOptions_EnableInputMethod_%s", input_method_id.c_str()); 216 UserMetrics::RecordComputedAction(action); 217 } 218 219 void CrosLanguageOptionsHandler::InputMethodOptionsOpenCallback( 220 const ListValue* args) { 221 const std::string input_method_id = UTF16ToASCII(ExtractStringValue(args)); 222 const std::string action = StringPrintf( 223 "InputMethodOptions_Open_%s", input_method_id.c_str()); 224 UserMetrics::RecordComputedAction(action); 225 } 226 227 } // namespace chromeos 228