Home | History | Annotate | Download | only in chromeos
      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