cros_language_options_handler.cc revision ddb351dbec246cf1fab5ec20d2d5520909041de1
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
26namespace chromeos {
27
28CrosLanguageOptionsHandler::CrosLanguageOptionsHandler() {
29}
30
31CrosLanguageOptionsHandler::~CrosLanguageOptionsHandler() {
32}
33
34void 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
70void 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
86ListValue* 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
125ListValue* 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
184string16 CrosLanguageOptionsHandler::GetProductName() {
185  return l10n_util::GetStringUTF16(IDS_PRODUCT_OS_NAME);
186}
187
188void CrosLanguageOptionsHandler::SetApplicationLocale(
189    const std::string& language_code) {
190  web_ui_->GetProfile()->ChangeAppLocale(
191      language_code, Profile::APP_LOCALE_CHANGED_VIA_SETTINGS);
192}
193
194void 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
203void 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
211void 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
219void 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