Chromium Code Reviews| Index: chrome/browser/extensions/api/language_settings_private/language_settings_private_api.cc |
| diff --git a/chrome/browser/extensions/api/language_settings_private/language_settings_private_api.cc b/chrome/browser/extensions/api/language_settings_private/language_settings_private_api.cc |
| index ea03265a38f10b9956ef296fec17f35290b86010..2d820c3880ef8304d67dba243a43792973a1e646 100644 |
| --- a/chrome/browser/extensions/api/language_settings_private/language_settings_private_api.cc |
| +++ b/chrome/browser/extensions/api/language_settings_private/language_settings_private_api.cc |
| @@ -4,8 +4,31 @@ |
| #include "chrome/browser/extensions/api/language_settings_private/language_settings_private_api.h" |
| +#include <map> |
| +#include <string> |
| +#include <unordered_set> |
| +#include <utility> |
| +#include <vector> |
| + |
| +#include "base/i18n/rtl.h" |
| +#include "base/memory/scoped_ptr.h" |
| +#include "base/strings/string16.h" |
| +#include "base/strings/utf_string_conversions.h" |
| #include "base/values.h" |
| +#include "chrome/browser/browser_process.h" |
| +#include "chrome/browser/extensions/api/language_settings_private/language_settings_private_delegate.h" |
| +#include "chrome/browser/extensions/api/language_settings_private/language_settings_private_delegate_factory.h" |
| +#include "chrome/browser/profiles/profile.h" |
| +#include "chrome/browser/spellchecker/spellcheck_factory.h" |
| +#include "chrome/browser/spellchecker/spellcheck_service.h" |
| +#include "chrome/browser/translate/chrome_translate_client.h" |
| +#include "chrome/browser/translate/translate_service.h" |
| #include "chrome/common/extensions/api/language_settings_private.h" |
| +#include "chrome/common/spellcheck_common.h" |
| +#include "components/translate/core/browser/translate_download_manager.h" |
| +#include "third_party/icu/source/i18n/unicode/coll.h" |
| +#include "ui/base/l10n/l10n_util.h" |
| +#include "ui/base/l10n/l10n_util_collator.h" |
| namespace extensions { |
| @@ -21,11 +44,91 @@ LanguageSettingsPrivateGetLanguageListFunction:: |
| ExtensionFunction::ResponseAction |
| LanguageSettingsPrivateGetLanguageListFunction::Run() { |
| - return RespondNow(OneArgument(new base::ListValue())); |
| + // Collect the language codes from the supported accept-languages. |
| + const std::string app_locale = g_browser_process->GetApplicationLocale(); |
| + std::vector<std::string> language_codes; |
| + l10n_util::GetAcceptLanguagesForLocale(app_locale, &language_codes); |
| + |
| + // Map of display name -> {language code, native display name}. |
| + typedef std::pair<std::string, base::string16> LanguagePair; |
| + typedef std::map<base::string16, LanguagePair, |
| + l10n_util::StringComparator<base::string16>> LanguageMap; |
| + |
| + // Collator used to sort display names in the current locale. |
| + UErrorCode error = U_ZERO_ERROR; |
| + scoped_ptr<icu::Collator> collator(icu::Collator::createInstance( |
| + icu::Locale(app_locale.c_str()), error)); |
| + if (U_FAILURE(error)) |
| + collator.reset(); |
| + l10n_util::StringComparator<base::string16> c(collator.get()); |
| + LanguageMap language_map(c); |
|
stevenjb
2015/08/10 16:13:54
nit: elim |c|
michaelpg
2015/08/10 23:31:50
I don't write enough C++ these days to be confiden
stevenjb
2015/08/11 19:30:19
Right. It's just a nit, but the reasoning is: decl
|
| + |
| + // Build the list of display names and the language map. |
| + for (size_t i = 0; i < language_codes.size(); ++i) { |
|
stevenjb
2015/08/10 16:13:54
for (auto code : language_codes)
michaelpg
2015/08/10 23:31:51
Done (using const auto&)
|
| + base::string16 display_name = l10n_util::GetDisplayNameForLocale( |
| + language_codes[i], app_locale, false); |
| + base::string16 native_display_name = l10n_util::GetDisplayNameForLocale( |
| + language_codes[i], language_codes[i], false); |
| + language_map[display_name] = |
| + std::make_pair(language_codes[i], native_display_name); |
| + } |
| + |
| + // Get the list of available locales (display languages) and convert to a set. |
| + const std::vector<std::string>& locales = l10n_util::GetAvailableLocales(); |
| + const std::unordered_set<std::string> locale_set( |
| + locales.begin(), locales.end()); |
| + |
| + // Get the list of spell check languages and convert to a set. |
| + std::vector<std::string> spellcheck_languages; |
| + chrome::spellcheck_common::SpellCheckLanguages(&spellcheck_languages); |
| + const std::unordered_set<std::string> spellcheck_language_set( |
| + spellcheck_languages.begin(), spellcheck_languages.end()); |
| + |
| + // Get the list of translatable languages and convert to a set. |
| + std::vector<std::string> translate_languages; |
| + translate::TranslateDownloadManager::GetSupportedLanguages( |
| + &translate_languages); |
| + const std::unordered_set<std::string> translate_language_set( |
| + translate_languages.begin(), translate_languages.end()); |
| + |
| + // Build the language list from the language map. |
| + scoped_ptr<base::ListValue> language_list(new base::ListValue); |
| + for (LanguageMap::iterator it = language_map.begin(); |
| + it != language_map.end(); |
| + ++it) { |
|
stevenjb
2015/08/10 16:13:54
for (auto it : language_map)
michaelpg
2015/08/10 23:31:50
Done (using const auto&, and renaming because it's
|
| + const base::string16& display_name = it->first; |
| + const LanguagePair& pair = it->second; |
| + |
| + language_settings_private::Language language; |
| + language.code = pair.first; |
| + |
| + base::string16 adjusted_display_name(display_name); |
| + base::i18n::AdjustStringForLocaleDirection(&adjusted_display_name); |
| + language.display_name = base::UTF16ToUTF8(adjusted_display_name); |
| + |
| + base::string16 adjusted_native_display_name(pair.second); |
| + base::i18n::AdjustStringForLocaleDirection(&adjusted_native_display_name); |
| + language.native_display_name = |
| + base::UTF16ToUTF8(adjusted_native_display_name); |
| + |
| + // Set optional fields only if they differ from the default. |
| + if (base::i18n::StringContainsStrongRTLChars(display_name)) |
| + language.rtl.reset(new bool(true)); |
| + if (locale_set.count(pair.first) > 0) |
| + language.supports_ui.reset(new bool(true)); |
| + if (spellcheck_language_set.count(pair.first) > 0) |
| + language.supports_spellcheck.reset(new bool(true)); |
| + if (translate_language_set.count(pair.first) > 0) |
| + language.supports_translate.reset(new bool(true)); |
| + |
| + language_list->Append(language.ToValue()); |
| + } |
| + return RespondNow(OneArgument(language_list.release())); |
| } |
| LanguageSettingsPrivateSetLanguageListFunction:: |
| - LanguageSettingsPrivateSetLanguageListFunction() { |
| + LanguageSettingsPrivateSetLanguageListFunction() |
| + : chrome_details_(this) { |
| } |
| LanguageSettingsPrivateSetLanguageListFunction:: |
| @@ -38,6 +141,11 @@ LanguageSettingsPrivateSetLanguageListFunction::Run() { |
| language_settings_private::SetLanguageList::Params::Create(*args_); |
| EXTENSION_FUNCTION_VALIDATE(parameters.get()); |
| + Profile* profile = chrome_details_.GetProfile(); |
| + scoped_ptr<translate::TranslatePrefs> translate_prefs = |
| + ChromeTranslateClient::CreateTranslatePrefs(profile->GetPrefs()); |
| + translate_prefs->UpdateLanguageList(parameters->language_codes); |
| + |
| return RespondNow(NoArguments()); |
| } |
| @@ -51,7 +159,17 @@ LanguageSettingsPrivateGetSpellcheckDictionaryStatusesFunction:: |
| ExtensionFunction::ResponseAction |
| LanguageSettingsPrivateGetSpellcheckDictionaryStatusesFunction::Run() { |
| - return RespondNow(OneArgument(new base::ListValue())); |
| + LanguageSettingsPrivateDelegate* delegate = |
| + LanguageSettingsPrivateDelegateFactory::GetForBrowserContext( |
| + browser_context()); |
| + const std::vector<scoped_ptr< |
| + language_settings_private::SpellcheckDictionaryStatus>>& statuses = |
| + delegate->GetHunspellDictionaryStatuses(); |
| + |
| + scoped_ptr<base::ListValue> return_list(new base::ListValue()); |
| + for (const auto& status : statuses) |
| + return_list->Append(status->ToValue()); |
| + return RespondNow(OneArgument(return_list.release())); |
| } |
| LanguageSettingsPrivateGetSpellcheckWordsFunction:: |
| @@ -64,11 +182,23 @@ LanguageSettingsPrivateGetSpellcheckWordsFunction:: |
| ExtensionFunction::ResponseAction |
| LanguageSettingsPrivateGetSpellcheckWordsFunction::Run() { |
| - return RespondNow(OneArgument(new base::ListValue())); |
| + SpellcheckService* service = |
| + SpellcheckServiceFactory::GetForContext(browser_context()); |
| + SpellcheckCustomDictionary* dictionary = service->GetCustomDictionary(); |
| + |
| + scoped_ptr<base::ListValue> word_list(new base::ListValue()); |
| + // TODO(michaelpg): observe the dictionary and respond later if not loaded. |
| + if (dictionary->IsLoaded()) { |
| + const std::set<std::string>& words = dictionary->GetWords(); |
| + for (const std::string& word : words) |
| + word_list->AppendString(word); |
| + } |
| + return RespondNow(OneArgument(word_list.release())); |
| } |
| LanguageSettingsPrivateGetTranslateTargetLanguageFunction:: |
| - LanguageSettingsPrivateGetTranslateTargetLanguageFunction() { |
| + LanguageSettingsPrivateGetTranslateTargetLanguageFunction() |
| + : chrome_details_(this) { |
| } |
| LanguageSettingsPrivateGetTranslateTargetLanguageFunction:: |
| @@ -77,7 +207,11 @@ LanguageSettingsPrivateGetTranslateTargetLanguageFunction:: |
| ExtensionFunction::ResponseAction |
| LanguageSettingsPrivateGetTranslateTargetLanguageFunction::Run() { |
| - return RespondNow(OneArgument(new base::StringValue(""))); |
| + Profile* profile = chrome_details_.GetProfile(); |
| + PrefService* prefs = profile->GetPrefs(); |
| + std::string target_language = |
| + TranslateService::GetTargetLanguage(prefs); |
|
stevenjb
2015/08/10 16:13:54
nit: no need for local var
michaelpg
2015/08/10 23:31:50
Done. Hope this isn't too much.
stevenjb
2015/08/11 19:30:19
Occasionally, a well named local used only once he
|
| + return RespondNow(OneArgument(new base::StringValue(target_language))); |
| } |
| LanguageSettingsPrivateGetInputMethodListsFunction:: |