Home | History | Annotate | Download | only in options
      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/language_options_handler_common.h"
      6 
      7 #include <map>
      8 #include <string>
      9 #include <utility>
     10 #include <vector>
     11 
     12 #include "base/basictypes.h"
     13 #include "base/bind.h"
     14 #include "base/command_line.h"
     15 #include "base/prefs/pref_service.h"
     16 #include "base/strings/string_util.h"
     17 #include "base/strings/stringprintf.h"
     18 #include "base/strings/utf_string_conversions.h"
     19 #include "base/values.h"
     20 #include "chrome/browser/browser_process.h"
     21 #include "chrome/browser/profiles/profile.h"
     22 #include "chrome/browser/spellchecker/spellcheck_factory.h"
     23 #include "chrome/browser/spellchecker/spellcheck_service.h"
     24 #include "chrome/browser/translate/chrome_translate_client.h"
     25 #include "chrome/browser/translate/translate_service.h"
     26 #include "chrome/browser/ui/browser_list.h"
     27 #include "chrome/common/chrome_switches.h"
     28 #include "chrome/common/pref_names.h"
     29 #include "chrome/common/spellcheck_common.h"
     30 #include "chrome/grit/chromium_strings.h"
     31 #include "chrome/grit/generated_resources.h"
     32 #include "components/translate/core/browser/translate_download_manager.h"
     33 #include "components/translate/core/browser/translate_prefs.h"
     34 #include "content/public/browser/user_metrics.h"
     35 #include "content/public/browser/web_ui.h"
     36 #include "ui/base/l10n/l10n_util.h"
     37 
     38 using base::UserMetricsAction;
     39 
     40 namespace options {
     41 
     42 LanguageOptionsHandlerCommon::LanguageOptionsHandlerCommon() {
     43 }
     44 
     45 LanguageOptionsHandlerCommon::~LanguageOptionsHandlerCommon() {
     46 }
     47 
     48 void LanguageOptionsHandlerCommon::GetLocalizedValues(
     49     base::DictionaryValue* localized_strings) {
     50   DCHECK(localized_strings);
     51   static OptionsStringResource resources[] = {
     52     { "addButton", IDS_OPTIONS_SETTINGS_LANGUAGES_ADD_BUTTON },
     53     { "languages", IDS_OPTIONS_SETTINGS_LANGUAGES_LANGUAGES },
     54     { "addLanguageInstructions",
     55       IDS_OPTIONS_SETTINGS_LANGUAGES_ADD_LANGUAGE_INSTRUCTIONS },
     56     { "cannotBeDisplayedInThisLanguage",
     57       IDS_OPTIONS_SETTINGS_LANGUAGES_CANNOT_BE_DISPLAYED_IN_THIS_LANGUAGE,
     58       IDS_PRODUCT_NAME },
     59     { "isDisplayedInThisLanguage",
     60       IDS_OPTIONS_SETTINGS_LANGUAGES_IS_DISPLAYED_IN_THIS_LANGUAGE,
     61       IDS_PRODUCT_NAME },
     62     { "displayInThisLanguage",
     63       IDS_OPTIONS_SETTINGS_LANGUAGES_DISPLAY_IN_THIS_LANGUAGE,
     64       IDS_PRODUCT_NAME },
     65     { "restartRequired", IDS_OPTIONS_RELAUNCH_REQUIRED },
     66   // OS X uses the OS native spellchecker so no need for these strings.
     67 #if !defined(OS_MACOSX)
     68     { "useThisForSpellChecking",
     69       IDS_OPTIONS_SETTINGS_USE_THIS_FOR_SPELL_CHECKING },
     70     { "cannotBeUsedForSpellChecking",
     71       IDS_OPTIONS_SETTINGS_CANNOT_BE_USED_FOR_SPELL_CHECKING },
     72     { "isUsedForSpellChecking",
     73       IDS_OPTIONS_SETTINGS_IS_USED_FOR_SPELL_CHECKING },
     74     { "enableSpellCheck", IDS_OPTIONS_ENABLE_SPELLCHECK },
     75     { "enableAutoSpellCorrection",
     76       IDS_OPTIONS_ENABLE_AUTO_SPELL_CORRECTION },
     77     { "downloadingDictionary", IDS_OPTIONS_DICTIONARY_DOWNLOADING },
     78     { "downloadFailed", IDS_OPTIONS_DICTIONARY_DOWNLOAD_FAILED },
     79     { "retryButton", IDS_OPTIONS_DICTIONARY_DOWNLOAD_RETRY },
     80     { "downloadFailHelp", IDS_OPTIONS_DICTIONARY_DOWNLOAD_FAIL_HELP },
     81 #endif  // !OS_MACOSX
     82     { "addLanguageTitle", IDS_OPTIONS_LANGUAGES_ADD_TITLE },
     83     { "addLanguageSelectLabel", IDS_OPTIONS_LANGUAGES_ADD_SELECT_LABEL },
     84     { "restartButton", IDS_OPTIONS_SETTINGS_LANGUAGES_RELAUNCH_BUTTON },
     85     { "offerToTranslateInThisLanguage",
     86       IDS_OPTIONS_LANGUAGES_OFFER_TO_TRANSLATE_IN_THIS_LANGUAGE },
     87     { "cannotTranslateInThisLanguage",
     88       IDS_OPTIONS_LANGUAGES_CANNOT_TRANSLATE_IN_THIS_LANGUAGE },
     89   };
     90 
     91 #if defined(ENABLE_SETTINGS_APP)
     92   static OptionsStringResource app_resources[] = {
     93     { "cannotBeDisplayedInThisLanguage",
     94       IDS_OPTIONS_SETTINGS_LANGUAGES_CANNOT_BE_DISPLAYED_IN_THIS_LANGUAGE,
     95       IDS_SETTINGS_APP_LAUNCHER_PRODUCT_NAME },
     96     { "isDisplayedInThisLanguage",
     97       IDS_OPTIONS_SETTINGS_LANGUAGES_IS_DISPLAYED_IN_THIS_LANGUAGE,
     98       IDS_SETTINGS_APP_LAUNCHER_PRODUCT_NAME },
     99     { "displayInThisLanguage",
    100       IDS_OPTIONS_SETTINGS_LANGUAGES_DISPLAY_IN_THIS_LANGUAGE,
    101       IDS_SETTINGS_APP_LAUNCHER_PRODUCT_NAME },
    102   };
    103   base::DictionaryValue* app_values = NULL;
    104   CHECK(localized_strings->GetDictionary(kSettingsAppKey, &app_values));
    105   RegisterStrings(app_values, app_resources, arraysize(app_resources));
    106 #endif
    107 
    108   RegisterStrings(localized_strings, resources, arraysize(resources));
    109 
    110   // The following are resources, rather than local strings.
    111   std::string application_locale = g_browser_process->GetApplicationLocale();
    112   localized_strings->SetString("currentUiLanguageCode", application_locale);
    113   std::string prospective_locale =
    114       g_browser_process->local_state()->GetString(prefs::kApplicationLocale);
    115   localized_strings->SetString("prospectiveUiLanguageCode",
    116       !prospective_locale.empty() ? prospective_locale : application_locale);
    117   localized_strings->Set("spellCheckLanguageCodeSet",
    118                          GetSpellCheckLanguageCodeSet());
    119   localized_strings->Set("uiLanguageCodeSet", GetUILanguageCodeSet());
    120 
    121   const CommandLine& command_line = *CommandLine::ForCurrentProcess();
    122   bool enable_spelling_auto_correct =
    123       command_line.HasSwitch(switches::kEnableSpellingAutoCorrect);
    124   localized_strings->SetBoolean("enableSpellingAutoCorrect",
    125                                 enable_spelling_auto_correct);
    126 
    127   Profile* profile = Profile::FromWebUI(web_ui());
    128   PrefService* prefs = profile->GetPrefs();
    129   std::string default_target_language =
    130       TranslateService::GetTargetLanguage(prefs);
    131   localized_strings->SetString("defaultTargetLanguage",
    132                                default_target_language);
    133 
    134   std::vector<std::string> languages;
    135   translate::TranslateDownloadManager::GetSupportedLanguages(&languages);
    136 
    137   base::ListValue* languages_list = new base::ListValue();
    138   for (std::vector<std::string>::iterator it = languages.begin();
    139        it != languages.end(); ++it) {
    140     languages_list->Append(new base::StringValue(*it));
    141   }
    142 
    143   localized_strings->Set("translateSupportedLanguages", languages_list);
    144 }
    145 
    146 void LanguageOptionsHandlerCommon::Uninitialize() {
    147   if (hunspell_dictionary_.get())
    148     hunspell_dictionary_->RemoveObserver(this);
    149   hunspell_dictionary_.reset();
    150 }
    151 
    152 void LanguageOptionsHandlerCommon::RegisterMessages() {
    153   web_ui()->RegisterMessageCallback("languageOptionsOpen",
    154       base::Bind(
    155           &LanguageOptionsHandlerCommon::LanguageOptionsOpenCallback,
    156           base::Unretained(this)));
    157   web_ui()->RegisterMessageCallback("spellCheckLanguageChange",
    158       base::Bind(
    159           &LanguageOptionsHandlerCommon::SpellCheckLanguageChangeCallback,
    160           base::Unretained(this)));
    161   web_ui()->RegisterMessageCallback("uiLanguageChange",
    162       base::Bind(
    163           &LanguageOptionsHandlerCommon::UiLanguageChangeCallback,
    164           base::Unretained(this)));
    165   web_ui()->RegisterMessageCallback("retryDictionaryDownload",
    166       base::Bind(
    167           &LanguageOptionsHandlerCommon::RetrySpellcheckDictionaryDownload,
    168           base::Unretained(this)));
    169   web_ui()->RegisterMessageCallback("updateLanguageList",
    170       base::Bind(
    171           &LanguageOptionsHandlerCommon::UpdateLanguageListCallback,
    172           base::Unretained(this)));
    173 }
    174 
    175 void LanguageOptionsHandlerCommon::OnHunspellDictionaryInitialized() {
    176 }
    177 
    178 void LanguageOptionsHandlerCommon::OnHunspellDictionaryDownloadBegin() {
    179   web_ui()->CallJavascriptFunction(
    180       "options.LanguageOptions.onDictionaryDownloadBegin",
    181       base::StringValue(GetHunspellDictionary()->GetLanguage()));
    182 }
    183 
    184 void LanguageOptionsHandlerCommon::OnHunspellDictionaryDownloadSuccess() {
    185   web_ui()->CallJavascriptFunction(
    186       "options.LanguageOptions.onDictionaryDownloadSuccess",
    187       base::StringValue(GetHunspellDictionary()->GetLanguage()));
    188 }
    189 
    190 void LanguageOptionsHandlerCommon::OnHunspellDictionaryDownloadFailure() {
    191   web_ui()->CallJavascriptFunction(
    192       "options.LanguageOptions.onDictionaryDownloadFailure",
    193       base::StringValue(GetHunspellDictionary()->GetLanguage()));
    194 }
    195 
    196 base::DictionaryValue* LanguageOptionsHandlerCommon::GetUILanguageCodeSet() {
    197   base::DictionaryValue* dictionary = new base::DictionaryValue();
    198   const std::vector<std::string>& available_locales =
    199       l10n_util::GetAvailableLocales();
    200   for (size_t i = 0; i < available_locales.size(); ++i)
    201     dictionary->SetBoolean(available_locales[i], true);
    202   return dictionary;
    203 }
    204 
    205 base::DictionaryValue*
    206 LanguageOptionsHandlerCommon::GetSpellCheckLanguageCodeSet() {
    207   base::DictionaryValue* dictionary = new base::DictionaryValue();
    208   std::vector<std::string> spell_check_languages;
    209   chrome::spellcheck_common::SpellCheckLanguages(&spell_check_languages);
    210   for (size_t i = 0; i < spell_check_languages.size(); ++i) {
    211     dictionary->SetBoolean(spell_check_languages[i], true);
    212   }
    213   return dictionary;
    214 }
    215 
    216 void LanguageOptionsHandlerCommon::LanguageOptionsOpenCallback(
    217     const base::ListValue* args) {
    218   content::RecordAction(UserMetricsAction("LanguageOptions_Open"));
    219   RefreshHunspellDictionary();
    220   if (hunspell_dictionary_->IsDownloadInProgress())
    221     OnHunspellDictionaryDownloadBegin();
    222   else if (hunspell_dictionary_->IsDownloadFailure())
    223     OnHunspellDictionaryDownloadFailure();
    224   else
    225     OnHunspellDictionaryDownloadSuccess();
    226 }
    227 
    228 void LanguageOptionsHandlerCommon::UiLanguageChangeCallback(
    229     const base::ListValue* args) {
    230   const std::string language_code =
    231       base::UTF16ToASCII(ExtractStringValue(args));
    232   CHECK(!language_code.empty());
    233   const std::string action = base::StringPrintf(
    234       "LanguageOptions_UiLanguageChange_%s", language_code.c_str());
    235   content::RecordComputedAction(action);
    236   SetApplicationLocale(language_code);
    237   base::StringValue language_value(language_code);
    238   web_ui()->CallJavascriptFunction("options.LanguageOptions.uiLanguageSaved",
    239                                    language_value);
    240 }
    241 
    242 void LanguageOptionsHandlerCommon::SpellCheckLanguageChangeCallback(
    243     const base::ListValue* args) {
    244   const std::string language_code =
    245       base::UTF16ToASCII(ExtractStringValue(args));
    246   CHECK(!language_code.empty());
    247   const std::string action = base::StringPrintf(
    248       "LanguageOptions_SpellCheckLanguageChange_%s", language_code.c_str());
    249   content::RecordComputedAction(action);
    250   RefreshHunspellDictionary();
    251 }
    252 
    253 void LanguageOptionsHandlerCommon::UpdateLanguageListCallback(
    254     const base::ListValue* args) {
    255   CHECK_EQ(args->GetSize(), 1u);
    256   const base::ListValue* language_list;
    257   args->GetList(0, &language_list);
    258   DCHECK(language_list);
    259 
    260   std::vector<std::string> languages;
    261   for (base::ListValue::const_iterator it = language_list->begin();
    262        it != language_list->end(); ++it) {
    263     std::string lang;
    264     (*it)->GetAsString(&lang);
    265     languages.push_back(lang);
    266   }
    267 
    268   Profile* profile = Profile::FromWebUI(web_ui());
    269   scoped_ptr<translate::TranslatePrefs> translate_prefs =
    270       ChromeTranslateClient::CreateTranslatePrefs(profile->GetPrefs());
    271   translate_prefs->UpdateLanguageList(languages);
    272 }
    273 
    274 void LanguageOptionsHandlerCommon::RetrySpellcheckDictionaryDownload(
    275     const base::ListValue* args) {
    276   GetHunspellDictionary()->RetryDownloadDictionary(
    277       Profile::FromWebUI(web_ui())->GetRequestContext());
    278 }
    279 
    280 void LanguageOptionsHandlerCommon::RefreshHunspellDictionary() {
    281   if (hunspell_dictionary_.get())
    282     hunspell_dictionary_->RemoveObserver(this);
    283   hunspell_dictionary_.reset();
    284   SpellcheckService* service = SpellcheckServiceFactory::GetForContext(
    285       Profile::FromWebUI(web_ui()));
    286   hunspell_dictionary_ = service->GetHunspellDictionary()->AsWeakPtr();
    287   hunspell_dictionary_->AddObserver(this);
    288 }
    289 
    290 base::WeakPtr<SpellcheckHunspellDictionary>&
    291     LanguageOptionsHandlerCommon::GetHunspellDictionary() {
    292   if (!hunspell_dictionary_.get())
    293     RefreshHunspellDictionary();
    294   return hunspell_dictionary_;
    295 }
    296 
    297 }  // namespace options
    298