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