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
CrosLanguageOptionsHandler()28 CrosLanguageOptionsHandler::CrosLanguageOptionsHandler() {
29 }
30
~CrosLanguageOptionsHandler()31 CrosLanguageOptionsHandler::~CrosLanguageOptionsHandler() {
32 }
33
GetLocalizedValues(DictionaryValue * localized_strings)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
RegisterMessages()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
GetInputMethodList(const chromeos::InputMethodDescriptors & descriptors)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
GetLanguageList(const chromeos::InputMethodDescriptors & descriptors)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
GetProductName()184 string16 CrosLanguageOptionsHandler::GetProductName() {
185 return l10n_util::GetStringUTF16(IDS_PRODUCT_OS_NAME);
186 }
187
SetApplicationLocale(const std::string & language_code)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
RestartCallback(const ListValue * args)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
InputMethodDisableCallback(const ListValue * args)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
InputMethodEnableCallback(const ListValue * args)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
InputMethodOptionsOpenCallback(const ListValue * args)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