summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authorsatorux@chromium.org <satorux@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-06-17 02:07:49 +0000
committersatorux@chromium.org <satorux@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-06-17 02:07:49 +0000
commitffd6ed4a32b41b6f6ffa76b4deefc9d67f1df220 (patch)
tree5e66ce03f07c3f666b7a046400f6e6a62510a5a7 /chrome
parentff71b339daec8ebf0a4081a54451333aa2d99b96 (diff)
downloadchromium_src-ffd6ed4a32b41b6f6ffa76b4deefc9d67f1df220.zip
chromium_src-ffd6ed4a32b41b6f6ffa76b4deefc9d67f1df220.tar.gz
chromium_src-ffd6ed4a32b41b6f6ffa76b4deefc9d67f1df220.tar.bz2
The second step of refactoring LanguageConfigView.
No change in the logic. Just move the code around. - Add language_config_model.cc, .h, _test.cc - Sort function definitions and declarations so the order match in .cc and .h files. Search for OCD in http://www.chromium.org/developers/coding-style TEST=manually BUG=chromium-os:4063 Review URL: http://codereview.chromium.org/2856005 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@50069 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/chromeos/options/language_config_model.cc478
-rw-r--r--chrome/browser/chromeos/options/language_config_model.h198
-rw-r--r--chrome/browser/chromeos/options/language_config_model_unittest.cc (renamed from chrome/browser/chromeos/options/language_config_view_test.cc)2
-rw-r--r--chrome/browser/chromeos/options/language_config_view.cc830
-rw-r--r--chrome/browser/chromeos/options/language_config_view.h205
-rwxr-xr-xchrome/chrome_browser.gypi2
-rwxr-xr-xchrome/chrome_tests.gypi2
7 files changed, 879 insertions, 838 deletions
diff --git a/chrome/browser/chromeos/options/language_config_model.cc b/chrome/browser/chromeos/options/language_config_model.cc
new file mode 100644
index 0000000..e1af5a47
--- /dev/null
+++ b/chrome/browser/chromeos/options/language_config_model.cc
@@ -0,0 +1,478 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/chromeos/options/language_config_model.h"
+
+#include <algorithm>
+#include <functional>
+#include <utility>
+
+#include "app/l10n_util_collator.h"
+#include "base/utf_string_conversions.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/chromeos/cros/cros_library.h"
+#include "chrome/browser/chromeos/cros/language_library.h"
+#include "chrome/browser/chromeos/preferences.h"
+#include "chrome/browser/chromeos/status/language_menu_l10n_util.h"
+#include "chrome/common/notification_type.h"
+#include "chrome/common/pref_names.h"
+
+namespace chromeos {
+
+namespace {
+
+// The code should be compatible with one of codes used for UI languages,
+// defined in app/l10_util.cc.
+const char kDefaultLanguageCode[] = "en-US";
+
+// The list of language that do not have associated input methods. For
+// these languages, we associate input methods here.
+const struct ExtraLanguage {
+ const char* language_code;
+ const char* input_method_id;
+} kExtraLanguages[] = {
+ { "id", "xkb:us::eng" }, // For Indonesian, use US keyboard layout.
+ // The code "fil" comes from app/l10_util.cc.
+ { "fil", "xkb:us::eng" }, // For Filipino, use US keyboard layout.
+ // The code "es-419" comes from app/l10_util.cc.
+ // For Spanish in Latin America, use Spanish keyboard layout.
+ { "es-419", "xkb:es::spa" },
+};
+
+// The list defines pairs of language code and the default input method
+// id. The list is used for reordering input method ids.
+//
+// TODO(satorux): We may need to handle secondary, and ternary input
+// methods, rather than handling the default input method only.
+const struct LanguageDefaultInputMethodId {
+ const char* language_code;
+ const char* input_method_id;
+} kLanguageDefaultInputMethodIds[] = {
+ { "en-US", "xkb:us::eng", }, // US - English
+ { "fr", "xkb:fr::fra", }, // France - French
+ { "de", "xkb:de::ger", }, // Germany - German
+};
+
+} // namespace
+
+AddLanguageComboboxModel::AddLanguageComboboxModel(
+ Profile* profile,
+ const std::vector<std::string>& locale_codes)
+ : LanguageComboboxModel(profile, locale_codes) {
+}
+
+int AddLanguageComboboxModel::GetItemCount() {
+ // +1 for "Add language".
+ return get_languages_count() + 1 - ignore_set_.size();
+}
+
+std::wstring AddLanguageComboboxModel::GetItemAt(int index) {
+ // Show "Add language" as the first item.
+ if (index == 0) {
+ return l10n_util::GetString(
+ IDS_OPTIONS_SETTINGS_LANGUAGES_ADD_LANGUAGE_COMBOBOX);
+ }
+ return LanguageConfigModel::MaybeRewriteLanguageName(
+ GetLanguageNameAt(GetLanguageIndex(index)));
+}
+
+int AddLanguageComboboxModel::GetLanguageIndex(int index) const {
+ // The adjusted_index is counted while ignoring languages in ignore_set_.
+ int adjusted_index = 0;
+ for (int i = 0; i < get_languages_count(); ++i) {
+ if (ignore_set_.count(GetLocaleFromIndex(i)) > 0) {
+ continue;
+ }
+ // -1 for "Add language".
+ if (adjusted_index == index - 1) {
+ return i;
+ }
+ ++adjusted_index;
+ }
+ return 0;
+}
+
+void AddLanguageComboboxModel::SetIgnored(
+ const std::string& language_code, bool ignored) {
+ if (ignored) {
+ // Add to the ignore_set_ if the language code is known (i.e. reject
+ // unknown language codes just in case).
+ if (GetIndexFromLocale(language_code) != -1) {
+ ignore_set_.insert(language_code);
+ } else {
+ LOG(ERROR) << "Unknown language code: " << language_code;
+ }
+ } else {
+ ignore_set_.erase(language_code);
+ }
+}
+
+LanguageConfigModel::LanguageConfigModel(PrefService* pref_service)
+ : pref_service_(pref_service) {
+}
+
+void LanguageConfigModel::Init() {
+ // Initialize the maps and vectors.
+ InitInputMethodIdMapsAndVectors();
+
+ preload_engines_.Init(
+ prefs::kLanguagePreloadEngines, pref_service_, this);
+ // TODO(yusukes): It might be safer to call GetActiveLanguages() cros API
+ // here and compare the result and preload_engines_.GetValue(). If there's
+ // a discrepancy between IBus setting and Chrome prefs, we can resolve it
+ // by calling preload_engines_SetValue() here.
+}
+
+size_t LanguageConfigModel::CountNumActiveInputMethods(
+ const std::string& language_code) {
+ int num_selected_active_input_methods = 0;
+ std::pair<LanguageCodeToIdsMap::const_iterator,
+ LanguageCodeToIdsMap::const_iterator> range =
+ language_code_to_ids_map_.equal_range(language_code);
+ for (LanguageCodeToIdsMap::const_iterator iter = range.first;
+ iter != range.second; ++iter) {
+ if (InputMethodIsActivated(iter->second)) {
+ ++num_selected_active_input_methods;
+ }
+ }
+ return num_selected_active_input_methods;
+}
+
+bool LanguageConfigModel::HasLanguageCode(
+ const std::string& language_code) const {
+ return std::find(preferred_language_codes_.begin(),
+ preferred_language_codes_.end(),
+ language_code) != preferred_language_codes_.end();
+}
+
+size_t LanguageConfigModel::AddLanguageCode(
+ const std::string& language_code) {
+ preferred_language_codes_.push_back(language_code);
+ // Sort the language codes by names. This is not efficient, but
+ // acceptable as the language list is about 40 item long at most. In
+ // theory, we could find the position to insert rather than sorting, but
+ // it would be complex as we need to use unicode string comparator.
+ SortLanguageCodesByNames(&preferred_language_codes_);
+ // Find the language code just added in the sorted language codes.
+ const int added_at =
+ std::distance(preferred_language_codes_.begin(),
+ std::find(preferred_language_codes_.begin(),
+ preferred_language_codes_.end(),
+ language_code));
+ return added_at;
+}
+
+void LanguageConfigModel::RemoveLanguageAt(size_t row) {
+ preferred_language_codes_.erase(preferred_language_codes_.begin() + row);
+}
+
+void LanguageConfigModel::UpdateInputMethodPreferences(
+ const std::vector<std::string>& in_new_input_method_ids) {
+ std::vector<std::string> new_input_method_ids = in_new_input_method_ids;
+ // Note: Since |new_input_method_ids| is alphabetically sorted and the sort
+ // function below uses stable sort, the relateve order of input methods that
+ // belong to the same language (e.g. "mozc" and "xkb:jp::jpn") is maintained.
+ SortInputMethodIdsByNames(id_to_language_code_map_, &new_input_method_ids);
+ preload_engines_.SetValue(UTF8ToWide(JoinString(new_input_method_ids, ',')));
+}
+
+void LanguageConfigModel::DeactivateInputMethodsFor(
+ const std::string& language_code) {
+ for (size_t i = 0; i < num_supported_input_method_ids(); ++i) {
+ if (GetLanguageCodeFromInputMethodId(
+ supported_input_method_id_at(i)) ==
+ language_code) {
+ // What happens if we disable the input method currently active?
+ // IBus should take care of it, so we don't do anything special
+ // here. See crosbug.com/2443.
+ SetInputMethodActivated(supported_input_method_id_at(i), false);
+ // Do not break; here in order to disable all engines that belong to
+ // |language_code|.
+ }
+ }
+}
+
+void LanguageConfigModel::SetInputMethodActivated(
+ const std::string& input_method_id, bool activated) {
+ DCHECK(!input_method_id.empty());
+ std::vector<std::string> input_method_ids;
+ GetActiveInputMethodIds(&input_method_ids);
+
+ std::set<std::string> input_method_id_set(input_method_ids.begin(),
+ input_method_ids.end());
+ if (activated) {
+ // Add |id| if it's not already added.
+ input_method_id_set.insert(input_method_id);
+ } else {
+ input_method_id_set.erase(input_method_id);
+ }
+
+ // Update Chrome's preference.
+ std::vector<std::string> new_input_method_ids(input_method_id_set.begin(),
+ input_method_id_set.end());
+ UpdateInputMethodPreferences(new_input_method_ids);
+}
+
+bool LanguageConfigModel::InputMethodIsActivated(
+ const std::string& input_method_id) {
+ std::vector<std::string> input_method_ids;
+ GetActiveInputMethodIds(&input_method_ids);
+ return (std::find(input_method_ids.begin(), input_method_ids.end(),
+ input_method_id) != input_method_ids.end());
+}
+
+void LanguageConfigModel::GetActiveInputMethodIds(
+ std::vector<std::string>* out_input_method_ids) {
+ const std::wstring value = preload_engines_.GetValue();
+ out_input_method_ids->clear();
+ if (!value.empty()) {
+ SplitString(WideToUTF8(value), ',', out_input_method_ids);
+ }
+}
+
+std::string LanguageConfigModel::GetLanguageCodeFromInputMethodId(
+ const std::string& input_method_id) const {
+ std::map<std::string, std::string>::const_iterator iter
+ = id_to_language_code_map_.find(input_method_id);
+ return (iter == id_to_language_code_map_.end()) ?
+ // Returning |kDefaultLanguageCode| is not for Chrome OS but for Ubuntu
+ // where the ibus-xkb-layouts module could be missing.
+ kDefaultLanguageCode : iter->second;
+}
+
+std::string LanguageConfigModel::GetInputMethodDisplayNameFromId(
+ const std::string& input_method_id) const {
+ // |kDefaultDisplayName| is not for Chrome OS. See the comment above.
+ static const char kDefaultDisplayName[] = "USA";
+ std::map<std::string, std::string>::const_iterator iter
+ = id_to_display_name_map_.find(input_method_id);
+ return (iter == id_to_display_name_map_.end()) ?
+ kDefaultDisplayName : iter->second;
+}
+
+void LanguageConfigModel::GetInputMethodIdsFromLanguageCode(
+ const std::string& language_code,
+ std::vector<std::string>* input_method_ids) const {
+ DCHECK(input_method_ids);
+ input_method_ids->clear();
+
+ std::pair<LanguageCodeToIdsMap::const_iterator,
+ LanguageCodeToIdsMap::const_iterator> range =
+ language_code_to_ids_map_.equal_range(language_code);
+ for (LanguageCodeToIdsMap::const_iterator iter = range.first;
+ iter != range.second; ++iter) {
+ input_method_ids->push_back(iter->second);
+ }
+ // Reorder the input methods.
+ ReorderInputMethodIdsForLanguageCode(language_code, input_method_ids);
+}
+
+void LanguageConfigModel::NotifyPrefChanged() {
+ std::vector<std::string> input_method_ids;
+ GetActiveInputMethodIds(&input_method_ids);
+
+ std::set<std::string> language_code_set;
+ for (size_t i = 0; i < input_method_ids.size(); ++i) {
+ const std::string language_code =
+ GetLanguageCodeFromInputMethodId(input_method_ids[i]);
+ language_code_set.insert(language_code);
+ }
+
+ preferred_language_codes_.clear();
+ preferred_language_codes_.assign(
+ language_code_set.begin(), language_code_set.end());
+ LanguageConfigModel::SortLanguageCodesByNames(&preferred_language_codes_);
+}
+
+void LanguageConfigModel::Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details) {
+ if (type == NotificationType::PREF_CHANGED) {
+ NotifyPrefChanged();
+ }
+}
+
+std::wstring LanguageConfigModel::MaybeRewriteLanguageName(
+ const std::wstring& language_name) {
+ // "t" is used as the language code for input methods that don't fall
+ // under any other languages.
+ if (language_name == L"t") {
+ return l10n_util::GetString(
+ IDS_OPTIONS_SETTINGS_LANGUAGES_OTHERS);
+ }
+ return language_name;
+}
+
+std::wstring LanguageConfigModel::GetLanguageDisplayNameFromCode(
+ const std::string& language_code) {
+ return MaybeRewriteLanguageName(UTF16ToWide(
+ l10n_util::GetDisplayNameForLocale(
+ language_code, g_browser_process->GetApplicationLocale(),
+ true)));
+}
+
+namespace {
+
+// The comparator is used for sorting language codes by their
+// corresponding language names, using the ICU collator.
+struct CompareLanguageCodesByLanguageName
+ : std::binary_function<const std::string&, const std::string&, bool> {
+ explicit CompareLanguageCodesByLanguageName(icu::Collator* collator)
+ : collator_(collator) {
+ }
+
+ // Calling GetLanguageDisplayNameFromCode() in the comparator is not
+ // efficient, but acceptable as the function is cheap, and the language
+ // list is short (about 40 at most).
+ bool operator()(const std::string& s1, const std::string& s2) const {
+ const std::wstring key1 =
+ LanguageConfigModel::GetLanguageDisplayNameFromCode(s1);
+ const std::wstring key2 =
+ LanguageConfigModel::GetLanguageDisplayNameFromCode(s2);
+ return l10n_util::StringComparator<std::wstring>(collator_)(key1, key2);
+ }
+
+ icu::Collator* collator_;
+};
+
+// The comparator is used for sorting input method ids by their
+// corresponding language names, using the ICU collator.
+struct CompareInputMethodIdsByLanguageName
+ : std::binary_function<const std::string&, const std::string&, bool> {
+ CompareInputMethodIdsByLanguageName(
+ icu::Collator* collator,
+ const std::map<std::string, std::string>& id_to_language_code_map)
+ : comparator_(collator),
+ id_to_language_code_map_(id_to_language_code_map) {
+ }
+
+ bool operator()(const std::string& s1, const std::string& s2) const {
+ std::string language_code_1;
+ std::map<std::string, std::string>::const_iterator iter =
+ id_to_language_code_map_.find(s1);
+ if (iter != id_to_language_code_map_.end()) {
+ language_code_1 = iter->second;
+ }
+ std::string language_code_2;
+ iter = id_to_language_code_map_.find(s2);
+ if (iter != id_to_language_code_map_.end()) {
+ language_code_2 = iter->second;
+ }
+ return comparator_(language_code_1, language_code_2);
+ }
+
+ const CompareLanguageCodesByLanguageName comparator_;
+ const std::map<std::string, std::string>& id_to_language_code_map_;
+};
+
+} // namespace
+
+void LanguageConfigModel::SortLanguageCodesByNames(
+ std::vector<std::string>* language_codes) {
+ // We should build collator outside of the comparator. We cannot have
+ // scoped_ptr<> in the comparator for a subtle STL reason.
+ UErrorCode error = U_ZERO_ERROR;
+ icu::Locale locale(g_browser_process->GetApplicationLocale().c_str());
+ scoped_ptr<icu::Collator> collator(
+ icu::Collator::createInstance(locale, error));
+ if (U_FAILURE(error)) {
+ collator.reset();
+ }
+ std::sort(language_codes->begin(), language_codes->end(),
+ CompareLanguageCodesByLanguageName(collator.get()));
+}
+
+void LanguageConfigModel::SortInputMethodIdsByNames(
+ const std::map<std::string, std::string>& id_to_language_code_map,
+ std::vector<std::string>* input_method_ids) {
+ UErrorCode error = U_ZERO_ERROR;
+ icu::Locale locale(g_browser_process->GetApplicationLocale().c_str());
+ scoped_ptr<icu::Collator> collator(
+ icu::Collator::createInstance(locale, error));
+ if (U_FAILURE(error)) {
+ collator.reset();
+ }
+ std::stable_sort(input_method_ids->begin(), input_method_ids->end(),
+ CompareInputMethodIdsByLanguageName(
+ collator.get(), id_to_language_code_map));
+}
+
+void LanguageConfigModel::ReorderInputMethodIdsForLanguageCode(
+ const std::string& language_code,
+ std::vector<std::string>* input_method_ids) {
+ for (size_t i = 0; i < arraysize(kLanguageDefaultInputMethodIds); ++i) {
+ if (language_code == kLanguageDefaultInputMethodIds[i].language_code) {
+ std::vector<std::string>::iterator iter =
+ std::find(input_method_ids->begin(), input_method_ids->end(),
+ kLanguageDefaultInputMethodIds[i].input_method_id);
+ // If it's not on the top of |input_method_id|, swap it with the top one.
+ if (iter != input_method_ids->end() &&
+ iter != input_method_ids->begin()) {
+ std::swap(*input_method_ids->begin(), *iter);
+ }
+ break; // Don't have to check other language codes.
+ }
+ }
+}
+
+void LanguageConfigModel::InitInputMethodIdMapsAndVectors() {
+ // The two sets are used to build lists without duplication.
+ std::set<std::string> supported_language_code_set;
+ std::set<std::string> supported_input_method_id_set;
+ // Build the id to descriptor map for handling kExtraLanguages later.
+ std::map<std::string, const InputMethodDescriptor*> id_to_descriptor_map;
+
+ // GetSupportedLanguages() never return NULL.
+ scoped_ptr<InputMethodDescriptors> supported_input_methods(
+ CrosLibrary::Get()->GetLanguageLibrary()->GetSupportedInputMethods());
+ for (size_t i = 0; i < supported_input_methods->size(); ++i) {
+ const InputMethodDescriptor& input_method = supported_input_methods->at(i);
+ const std::string language_code =
+ LanguageLibrary::GetLanguageCodeFromDescriptor(input_method);
+ AddInputMethodToMaps(language_code, input_method);
+ // Add the language code and the input method id to the sets.
+ supported_language_code_set.insert(language_code);
+ supported_input_method_id_set.insert(input_method.id);
+ // Remember the pair.
+ id_to_descriptor_map.insert(
+ std::make_pair(input_method.id, &input_method));
+ }
+
+ // Go through the languages listed in kExtraLanguages.
+ for (size_t i = 0; i < arraysize(kExtraLanguages); ++i) {
+ const char* language_code = kExtraLanguages[i].language_code;
+ const char* input_method_id = kExtraLanguages[i].input_method_id;
+ std::map<std::string, const InputMethodDescriptor*>::const_iterator iter =
+ id_to_descriptor_map.find(input_method_id);
+ // If the associated input method descriptor is found, add the
+ // language code and the input method.
+ if (iter != id_to_descriptor_map.end()) {
+ const InputMethodDescriptor& input_method = *(iter->second);
+ AddInputMethodToMaps(language_code, input_method);
+ // Add the language code and the input method id to the sets.
+ supported_language_code_set.insert(language_code);
+ supported_input_method_id_set.insert(input_method.id);
+ }
+ }
+
+ // Build the vectors from the sets.
+ supported_language_codes_.assign(supported_language_code_set.begin(),
+ supported_language_code_set.end());
+ supported_input_method_ids_.assign(supported_input_method_id_set.begin(),
+ supported_input_method_id_set.end());
+}
+
+void LanguageConfigModel::AddInputMethodToMaps(
+ const std::string& language_code,
+ const InputMethodDescriptor& input_method) {
+ id_to_language_code_map_.insert(
+ std::make_pair(input_method.id, language_code));
+ id_to_display_name_map_.insert(
+ std::make_pair(input_method.id, LanguageMenuL10nUtil::GetStringUTF8(
+ input_method.display_name)));
+ language_code_to_ids_map_.insert(
+ std::make_pair(language_code, input_method.id));
+}
+
+} // namespace chromeos
diff --git a/chrome/browser/chromeos/options/language_config_model.h b/chrome/browser/chromeos/options/language_config_model.h
new file mode 100644
index 0000000..a0440d4
--- /dev/null
+++ b/chrome/browser/chromeos/options/language_config_model.h
@@ -0,0 +1,198 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_CHROMEOS_OPTIONS_LANGUAGE_CONFIG_MODEL_H_
+#define CHROME_BROWSER_CHROMEOS_OPTIONS_LANGUAGE_CONFIG_MODEL_H_
+
+#include <map>
+#include <set>
+#include <string>
+#include <vector>
+
+#include "chrome/browser/language_combobox_model.h"
+#include "chrome/browser/pref_member.h"
+#include "chrome/browser/pref_service.h"
+#include "chrome/browser/profile.h"
+#include "chrome/common/notification_service.h"
+#include "third_party/cros/chromeos_input_method.h"
+
+namespace chromeos {
+
+// The combobox model is used for adding languages in the language config
+// view.
+class AddLanguageComboboxModel : public LanguageComboboxModel {
+ public:
+ AddLanguageComboboxModel(Profile* profile,
+ const std::vector<std::string>& locale_codes);
+ // LanguageComboboxModel overrides.
+ virtual int GetItemCount();
+ virtual std::wstring GetItemAt(int index);
+
+ // Converts the given index (index of the items in the combobox) to the
+ // index of the internal language list. The returned index can be used
+ // for GetLocaleFromIndex() and GetLanguageNameAt().
+ int GetLanguageIndex(int index) const;
+
+ // Marks the given language code to be ignored. Ignored languages won't
+ // be shown in the combobox. It would be simpler if we could remove and
+ // add language codes from the model, but ComboboxModel does not allow
+ // items to be added/removed. Thus we use |ignore_set_| instead.
+ void SetIgnored(const std::string& language_code, bool ignored);
+
+ private:
+ std::set<std::string> ignore_set_;
+ DISALLOW_COPY_AND_ASSIGN(AddLanguageComboboxModel);
+};
+
+// The model of LanguageConfigView.
+class LanguageConfigModel : public NotificationObserver {
+ public:
+ LanguageConfigModel(PrefService* pref_service);
+
+ // Initializes the model.
+ void Init();
+
+ // Counts the number of active input methods for the given language code.
+ size_t CountNumActiveInputMethods(const std::string& language_code);
+
+ // Returns true if the language code is in the preferred language list.
+ bool HasLanguageCode(const std::string& language_code) const;
+
+ // Adds the given language to the preferred language list, and returns
+ // the index of the row where the language is added.
+ size_t AddLanguageCode(const std::string& language_code);
+
+ // Removes the language at the given row.
+ void RemoveLanguageAt(size_t row);
+
+ // Updates Chrome's input method preferences.
+ void UpdateInputMethodPreferences(
+ const std::vector<std::string>& new_input_method_ids);
+
+ // Deactivates the input methods for the given language code.
+ void DeactivateInputMethodsFor(const std::string& language_code);
+
+ // Activates or deactivates an IME whose ID is |input_method_id|.
+ void SetInputMethodActivated(const std::string& input_method_id,
+ bool activated);
+
+ // Returns true if an IME of |input_method_id| is activated.
+ bool InputMethodIsActivated(const std::string& input_method_id);
+
+ // Gets the list of active IME IDs like "pinyin" and "m17n:ar:kbd".
+ void GetActiveInputMethodIds(
+ std::vector<std::string>* out_input_method_ids);
+
+ // Converts an input method ID to a language code of the IME. Returns "Eng"
+ // when |input_method_id| is unknown.
+ // Example: "hangul" => "ko"
+ std::string GetLanguageCodeFromInputMethodId(
+ const std::string& input_method_id) const;
+
+ // Converts an input method ID to a display name of the IME. Returns
+ // "USA" (US keyboard) when |input_method_id| is unknown.
+ // Examples: "pinyin" => "Pinyin"
+ // "m17n:ar:kbd" => "kbd (m17n)"
+ std::string GetInputMethodDisplayNameFromId(
+ const std::string& input_method_id) const;
+
+ // Gets the list of input method ids associated with the given language
+ // code. The original contents of |input_method_ids| will be lost.
+ void GetInputMethodIdsFromLanguageCode(
+ const std::string& language_code,
+ std::vector<std::string>* input_method_ids) const;
+
+ // Callback for |preload_engines_| pref updates. Initializes the preferred
+ // language codes based on the updated pref value.
+ void NotifyPrefChanged();
+
+ // NotificationObserver overrides.
+ virtual void Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details);
+
+ const std::string& preferred_language_code_at(size_t at) const {
+ return preferred_language_codes_[at];
+ }
+
+ size_t num_preferred_language_codes() const {
+ return preferred_language_codes_.size();
+ }
+
+ const std::string& supported_input_method_id_at(size_t at) const {
+ return supported_input_method_ids_[at];
+ }
+
+ size_t num_supported_input_method_ids() const {
+ return supported_input_method_ids_.size();
+ }
+
+ const std::vector<std::string>& supported_language_codes() const {
+ return supported_language_codes_;
+ }
+
+ // Rewrites the language name and returns the modified version if
+ // necessary. Otherwise, returns the given language name as is.
+ // In particular, this rewrites the special language name used for input
+ // methods that don't fall under any other languages.
+ static std::wstring MaybeRewriteLanguageName(
+ const std::wstring& language_name);
+
+ // Converts a language code to a language display name, using the
+ // current application locale. MaybeRewriteLanguageName() is called
+ // internally.
+ // Examples: "fr" => "French"
+ // "en-US" => "English (United States)"
+ static std::wstring GetLanguageDisplayNameFromCode(
+ const std::string& language_code);
+
+ // Sorts the given language codes by their corresponding language names,
+ // using the unicode string comparator. Uses unstable sorting.
+ static void SortLanguageCodesByNames(
+ std::vector<std::string>* language_codes);
+
+ // Sorts the given input method ids by their corresponding language names,
+ // using the unicode string comparator. Uses stable sorting.
+ static void SortInputMethodIdsByNames(
+ const std::map<std::string, std::string>& id_to_language_code_map,
+ std::vector<std::string>* input_method_ids);
+
+ // Reorders the given input method ids for the language code. For
+ // example, if |language_codes| is "fr" and |input_method_ids| contains
+ // ["xkb:be::fra", and "xkb:fr::fra"], the list is reordered to
+ // ["xkb:fr::fra", and "xkb:be::fra"], so that French keyboard layout
+ // comes before Belgian keyboard layout.
+ static void ReorderInputMethodIdsForLanguageCode(
+ const std::string& language_code,
+ std::vector<std::string>* input_method_ids);
+
+ private:
+ // Initializes id_to_{code,display_name}_map_ maps,
+ // as well as supported_{language_codes,input_method_ids}_ vectors.
+ void InitInputMethodIdMapsAndVectors();
+
+ // Adds the given language code and input method pair to the internal maps.
+ void AddInputMethodToMaps(const std::string& language_code,
+ const InputMethodDescriptor& input_method);
+
+ PrefService* pref_service_;
+ // The codes of the preferred languages.
+ std::vector<std::string> preferred_language_codes_;
+ StringPrefMember preload_engines_;
+ std::map<std::string, std::string> id_to_language_code_map_;
+ std::map<std::string, std::string> id_to_display_name_map_;
+ // List of supported language codes like "en" and "ja".
+ std::vector<std::string> supported_language_codes_;
+ // List of supported IME IDs like "pinyin" and "m17n:ar:kbd".
+ std::vector<std::string> supported_input_method_ids_;
+ // Map from language code to associated input method IDs.
+ typedef std::multimap<std::string, std::string> LanguageCodeToIdsMap;
+ LanguageCodeToIdsMap language_code_to_ids_map_;
+
+ DISALLOW_COPY_AND_ASSIGN(LanguageConfigModel);
+};
+
+} // namespace chromeos
+
+#endif // CHROME_BROWSER_CHROMEOS_OPTIONS_LANGUAGE_CONFIG_MODEL_H_
diff --git a/chrome/browser/chromeos/options/language_config_view_test.cc b/chrome/browser/chromeos/options/language_config_model_unittest.cc
index abf8db0..758488d 100644
--- a/chrome/browser/chromeos/options/language_config_view_test.cc
+++ b/chrome/browser/chromeos/options/language_config_model_unittest.cc
@@ -9,7 +9,7 @@
#include "app/l10n_util.h"
#include "base/utf_string_conversions.h"
-#include "chrome/browser/chromeos/options/language_config_view.h"
+#include "chrome/browser/chromeos/options/language_config_model.h"
#include "grit/generated_resources.h"
#include "testing/gtest/include/gtest/gtest.h"
diff --git a/chrome/browser/chromeos/options/language_config_view.cc b/chrome/browser/chromeos/options/language_config_view.cc
index 907190a..fddf73a 100644
--- a/chrome/browser/chromeos/options/language_config_view.cc
+++ b/chrome/browser/chromeos/options/language_config_view.cc
@@ -5,23 +5,16 @@
#include "chrome/browser/chromeos/options/language_config_view.h"
#include <algorithm>
-#include <functional>
-#include <utility>
-#include <vector>
#include "app/l10n_util.h"
-#include "app/l10n_util_collator.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/browser_process.h"
-#include "chrome/browser/chromeos/cros/cros_library.h"
-#include "chrome/browser/chromeos/cros/language_library.h"
#include "chrome/browser/chromeos/options/language_chewing_config_view.h"
#include "chrome/browser/chromeos/options/language_hangul_config_view.h"
#include "chrome/browser/chromeos/options/language_mozc_config_view.h"
#include "chrome/browser/chromeos/options/language_pinyin_config_view.h"
#include "chrome/browser/chromeos/options/options_window_view.h"
#include "chrome/browser/chromeos/preferences.h"
-#include "chrome/browser/chromeos/status/language_menu_l10n_util.h"
#include "chrome/browser/metrics/user_metrics.h"
#include "chrome/browser/pref_service.h"
#include "chrome/browser/profile.h"
@@ -44,38 +37,6 @@ using views::GridLayout;
namespace {
-// The code should be compatible with one of codes used for UI languages,
-// defined in app/l10_util.cc.
-const char kDefaultLanguageCode[] = "en-US";
-
-// The list of language that do not have associated input methods. For
-// these languages, we associate input methods here.
-const struct ExtraLanguage {
- const char* language_code;
- const char* input_method_id;
-} kExtraLanguages[] = {
- { "id", "xkb:us::eng" }, // For Indonesian, use US keyboard layout.
- // The code "fil" comes from app/l10_util.cc.
- { "fil", "xkb:us::eng" }, // For Filipino, use US keyboard layout.
- // The code "es-419" comes from app/l10_util.cc.
- // For Spanish in Latin America, use Spanish keyboard layout.
- { "es-419", "xkb:es::spa" },
-};
-
-// The list defines pairs of language code and the default input method
-// id. The list is used for reordering input method ids.
-//
-// TODO(satorux): We may need to handle secondary, and ternary input
-// methods, rather than handling the default input method only.
-const struct LanguageDefaultInputMethodId {
- const char* language_code;
- const char* input_method_id;
-} kLanguageDefaultInputMethodIds[] = {
- { "en-US", "xkb:us::eng", }, // US - English
- { "fr", "xkb:fr::fra", }, // France - French
- { "de", "xkb:de::ger", }, // Germany - German
-};
-
// The width of the preferred language table shown on the left side.
const int kPreferredLanguageTableWidth = 300;
@@ -109,58 +70,6 @@ const int kPerLanguageSingleColumnSetId = 3;
} // namespace
-AddLanguageComboboxModel::AddLanguageComboboxModel(
- Profile* profile,
- const std::vector<std::string>& locale_codes)
- : LanguageComboboxModel(profile, locale_codes) {
-}
-
-int AddLanguageComboboxModel::GetItemCount() {
- // +1 for "Add language".
- return get_languages_count() + 1 - ignore_set_.size();
-}
-
-std::wstring AddLanguageComboboxModel::GetItemAt(int index) {
- // Show "Add language" as the first item.
- if (index == 0) {
- return l10n_util::GetString(
- IDS_OPTIONS_SETTINGS_LANGUAGES_ADD_LANGUAGE_COMBOBOX);
- }
- return LanguageConfigModel::MaybeRewriteLanguageName(
- GetLanguageNameAt(GetLanguageIndex(index)));
-}
-
-int AddLanguageComboboxModel::GetLanguageIndex(int index) const {
- // The adjusted_index is counted while ignoring languages in ignore_set_.
- int adjusted_index = 0;
- for (int i = 0; i < get_languages_count(); ++i) {
- if (ignore_set_.count(GetLocaleFromIndex(i)) > 0) {
- continue;
- }
- // -1 for "Add language".
- if (adjusted_index == index - 1) {
- return i;
- }
- ++adjusted_index;
- }
- return 0;
-}
-
-void AddLanguageComboboxModel::SetIgnored(
- const std::string& language_code, bool ignored) {
- if (ignored) {
- // Add to the ignore_set_ if the language code is known (i.e. reject
- // unknown language codes just in case).
- if (GetIndexFromLocale(language_code) != -1) {
- ignore_set_.insert(language_code);
- } else {
- LOG(ERROR) << "Unknown language code: " << language_code;
- }
- } else {
- ignore_set_.erase(language_code);
- }
-}
-
// This is a native button associated with input method information.
class InputMethodButton : public views::NativeButton {
public:
@@ -217,75 +126,6 @@ class InputMethodCheckbox : public views::Checkbox {
DISALLOW_COPY_AND_ASSIGN(InputMethodCheckbox);
};
-LanguageConfigModel::LanguageConfigModel(PrefService* pref_service)
- : pref_service_(pref_service) {
-}
-
-void LanguageConfigModel::Init() {
- // Initialize the maps and vectors.
- InitInputMethodIdMapsAndVectors();
-
- preload_engines_.Init(
- prefs::kLanguagePreloadEngines, pref_service_, this);
- // TODO(yusukes): It might be safer to call GetActiveLanguages() cros API
- // here and compare the result and preload_engines_.GetValue(). If there's
- // a discrepancy between IBus setting and Chrome prefs, we can resolve it
- // by calling preload_engines_SetValue() here.
-}
-
-size_t LanguageConfigModel::CountNumActiveInputMethods(
- const std::string& language_code) {
- int num_selected_active_input_methods = 0;
- std::pair<LanguageCodeToIdsMap::const_iterator,
- LanguageCodeToIdsMap::const_iterator> range =
- language_code_to_ids_map_.equal_range(language_code);
- for (LanguageCodeToIdsMap::const_iterator iter = range.first;
- iter != range.second; ++iter) {
- if (InputMethodIsActivated(iter->second)) {
- ++num_selected_active_input_methods;
- }
- }
- return num_selected_active_input_methods;
-}
-
-bool LanguageConfigModel::HasLanguageCode(
- const std::string& language_code) const {
- return std::find(preferred_language_codes_.begin(),
- preferred_language_codes_.end(),
- language_code) != preferred_language_codes_.end();
-}
-
-size_t LanguageConfigModel::AddLanguageCode(
- const std::string& language_code) {
- preferred_language_codes_.push_back(language_code);
- // Sort the language codes by names. This is not efficient, but
- // acceptable as the language list is about 40 item long at most. In
- // theory, we could find the position to insert rather than sorting, but
- // it would be complex as we need to use unicode string comparator.
- SortLanguageCodesByNames(&preferred_language_codes_);
- // Find the language code just added in the sorted language codes.
- const int added_at =
- std::distance(preferred_language_codes_.begin(),
- std::find(preferred_language_codes_.begin(),
- preferred_language_codes_.end(),
- language_code));
- return added_at;
-}
-
-void LanguageConfigModel::RemoveLanguageAt(size_t row) {
- preferred_language_codes_.erase(preferred_language_codes_.begin() + row);
-}
-
-void LanguageConfigModel::UpdateInputMethodPreferences(
- const std::vector<std::string>& in_new_input_method_ids) {
- std::vector<std::string> new_input_method_ids = in_new_input_method_ids;
- // Note: Since |new_input_method_ids| is alphabetically sorted and the sort
- // function below uses stable sort, the relateve order of input methods that
- // belong to the same language (e.g. "mozc" and "xkb:jp::jpn") is maintained.
- SortInputMethodIdsByNames(id_to_language_code_map_, &new_input_method_ids);
- preload_engines_.SetValue(UTF8ToWide(JoinString(new_input_method_ids, ',')));
-}
-
LanguageConfigView::LanguageConfigView(Profile* profile)
: OptionsPageView(profile),
model(profile->GetPrefs()),
@@ -336,11 +176,6 @@ void LanguageConfigView::ButtonPressed(
}
}
-void LanguageConfigView::Layout() {
- // Not sure why but this is needed to show contents in the dialog.
- root_container_->SetBounds(0, 0, width(), height());
-}
-
std::wstring LanguageConfigView::GetDialogButtonLabel(
MessageBoxFlags::DialogButton button) const {
if (button == MessageBoxFlags::DIALOGBUTTON_OK) {
@@ -354,131 +189,17 @@ std::wstring LanguageConfigView::GetWindowTitle() const {
IDS_OPTIONS_SETTINGS_LANGUAGES_DIALOG_TITLE);
}
+void LanguageConfigView::Layout() {
+ // Not sure why but this is needed to show contents in the dialog.
+ root_container_->SetBounds(0, 0, width(), height());
+}
+
gfx::Size LanguageConfigView::GetPreferredSize() {
return gfx::Size(views::Window::GetLocalizedContentsSize(
IDS_LANGUAGES_INPUT_DIALOG_WIDTH_CHARS,
IDS_LANGUAGES_INPUT_DIALOG_HEIGHT_LINES));
}
-views::View* LanguageConfigView::CreatePerLanguageConfigView(
- const std::string& target_language_code) {
- views::View* contents = new views::View;
- GridLayout* layout = new GridLayout(contents);
- contents->SetLayoutManager(layout);
-
- // Set up column sets for the grid layout.
- ColumnSet* column_set = layout->AddColumnSet(kPerLanguageTitleColumnSetId);
- column_set->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 0,
- GridLayout::USE_PREF, 0, 0);
-
- column_set = layout->AddColumnSet(kPerLanguageDoubleColumnSetId);
- column_set->AddPaddingColumn(0, kUnrelatedControlHorizontalSpacing);
- column_set->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 0,
- GridLayout::USE_PREF, 0, 0);
- column_set->AddPaddingColumn(0, kRelatedControlHorizontalSpacing);
- column_set->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 0,
- GridLayout::USE_PREF, 0, 0);
-
- column_set = layout->AddColumnSet(kPerLanguageSingleColumnSetId);
- column_set->AddPaddingColumn(0, kUnrelatedControlHorizontalSpacing);
- column_set->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 0,
- GridLayout::USE_PREF, 0, 0);
-
- AddUiLanguageSection(target_language_code, layout);
- layout->AddPaddingRow(0, kUnrelatedControlVerticalSpacing);
- AddInputMethodSection(target_language_code, layout);
-
- return contents;
-}
-
-void LanguageConfigView::AddUiLanguageSection(const std::string& language_code,
- views::GridLayout* layout) {
- // Create the language name label.
- const std::string application_locale =
- g_browser_process->GetApplicationLocale();
- const string16 language_name16 = l10n_util::GetDisplayNameForLocale(
- language_code, application_locale, true);
- const std::wstring language_name
- = LanguageConfigModel::MaybeRewriteLanguageName(
- UTF16ToWide(language_name16));
- views::Label* language_name_label = new views::Label(language_name);
- language_name_label->SetFont(
- language_name_label->font().DeriveFont(0, gfx::Font::BOLD));
-
- // Add the language name label.
- layout->StartRow(0, kPerLanguageTitleColumnSetId);
- layout->AddView(language_name_label);
- layout->AddPaddingRow(0, kRelatedControlVerticalSpacing);
-
- layout->StartRow(0, kPerLanguageSingleColumnSetId);
- if (application_locale == language_code) {
- layout->AddView(
- new views::Label(
- l10n_util::GetStringF(
- IDS_OPTIONS_SETTINGS_LANGUAGES_IS_DISPLAYED_IN_THIS_LANGUAGE,
- l10n_util::GetString(IDS_PRODUCT_OS_NAME))));
- } else {
- UiLanguageButton* button = new UiLanguageButton(
- this, l10n_util::GetStringF(
- IDS_OPTIONS_SETTINGS_LANGUAGES_DISPLAY_IN_THIS_LANGUAGE,
- l10n_util::GetString(IDS_PRODUCT_OS_NAME)),
- language_code);
- button->set_tag(kChangeUiLanguageButton);
- layout->AddView(button);
- }
-}
-
-void LanguageConfigView::AddInputMethodSection(
- const std::string& language_code,
- views::GridLayout* layout) {
- // Create the input method title label.
- views::Label* input_method_title_label = new views::Label(
- l10n_util::GetString(
- IDS_OPTIONS_SETTINGS_LANGUAGES_INPUT_METHOD));
- input_method_title_label->SetFont(
- input_method_title_label->font().DeriveFont(0, gfx::Font::BOLD));
-
- // Add the input method title label.
- layout->StartRow(0, kPerLanguageTitleColumnSetId);
- layout->AddView(input_method_title_label);
- layout->AddPaddingRow(0, kRelatedControlVerticalSpacing);
-
- // Add input method names and configuration buttons.
- input_method_checkboxes_.clear();
-
- // Get the list of input method ids associated with the language code.
- std::vector<std::string> input_method_ids;
- model.GetInputMethodIdsFromLanguageCode(language_code, &input_method_ids);
-
- for (size_t i = 0; i < input_method_ids.size(); ++i) {
- const std::string& input_method_id = input_method_ids[i];
- const std::string display_name = model.GetInputMethodDisplayNameFromId(
- input_method_id);
- layout->StartRow(0, kPerLanguageDoubleColumnSetId);
- InputMethodCheckbox* checkbox
- = new InputMethodCheckbox(UTF8ToWide(display_name),
- input_method_id);
- checkbox->set_listener(this);
- checkbox->set_tag(kSelectInputMethodButton);
- if (model.InputMethodIsActivated(input_method_id)) {
- checkbox->SetChecked(true);
- }
-
- layout->AddView(checkbox);
- input_method_checkboxes_.insert(checkbox);
- // Add "configure" button for the input method if we have a
- // configuration dialog for it.
- if (input_method_config_view_map_.count(input_method_id) > 0) {
- InputMethodButton* button = new InputMethodButton(
- this,
- l10n_util::GetString(IDS_OPTIONS_SETTINGS_LANGUAGES_CONFIGURE),
- input_method_id);
- button->set_tag(kConfigureInputMethodButton);
- layout->AddView(button);
- }
- }
-}
-
void LanguageConfigView::OnSelectionChanged() {
right_container_->RemoveAllChildViews(true); // Delete the child views.
@@ -524,14 +245,6 @@ std::wstring LanguageConfigView::GetText(int row, int column_id) {
return L"";
}
-void LanguageConfigView::Show(Profile* profile, gfx::NativeWindow parent) {
- UserMetrics::RecordAction(UserMetricsAction("LanguageConfigView_Open"));
- views::Window* window = views::Window::CreateChromeWindow(
- parent, gfx::Rect(), new LanguageConfigView(profile));
- window->SetIsAlwaysOnTop(true);
- window->Show();
-}
-
void LanguageConfigView::SetObserver(TableModelObserver* observer) {
// We don't need the observer for the table mode, since we implement the
// table model as part of the LanguageConfigView class.
@@ -543,6 +256,20 @@ int LanguageConfigView::RowCount() {
return model.num_preferred_language_codes();
}
+void LanguageConfigView::ItemChanged(views::Combobox* combobox,
+ int prev_index,
+ int new_index) {
+ // Ignore the first item used for showing "Add language".
+ if (new_index <= 0) {
+ return;
+ }
+ // Get the language selected.
+ std::string language_selected = add_language_combobox_model_->
+ GetLocaleFromIndex(
+ add_language_combobox_model_->GetLanguageIndex(new_index));
+ OnAddLanguage(language_selected);
+}
+
void LanguageConfigView::InitControlLayout() {
// Initialize the model.
model.Init();
@@ -599,6 +326,14 @@ void LanguageConfigView::InitControlLayout() {
}
}
+void LanguageConfigView::Show(Profile* profile, gfx::NativeWindow parent) {
+ UserMetrics::RecordAction(UserMetricsAction("LanguageConfigView_Open"));
+ views::Window* window = views::Window::CreateChromeWindow(
+ parent, gfx::Rect(), new LanguageConfigView(profile));
+ window->SetIsAlwaysOnTop(true);
+ window->Show();
+}
+
void LanguageConfigView::InitInputMethodConfigViewMap() {
input_method_config_view_map_["chewing"] = CreateLanguageChewingConfigView;
input_method_config_view_map_["hangul"] = CreateLanguageHangulConfigView;
@@ -610,63 +345,64 @@ void LanguageConfigView::InitInputMethodConfigViewMap() {
// input_method_config_view_map_["mozc-jp"] = CreateLanguageMozcConfigView;
}
-void LanguageConfigModel::InitInputMethodIdMapsAndVectors() {
- // The two sets are used to build lists without duplication.
- std::set<std::string> supported_language_code_set;
- std::set<std::string> supported_input_method_id_set;
- // Build the id to descriptor map for handling kExtraLanguages later.
- std::map<std::string, const InputMethodDescriptor*> id_to_descriptor_map;
-
- // GetSupportedLanguages() never return NULL.
- scoped_ptr<InputMethodDescriptors> supported_input_methods(
- CrosLibrary::Get()->GetLanguageLibrary()->GetSupportedInputMethods());
- for (size_t i = 0; i < supported_input_methods->size(); ++i) {
- const InputMethodDescriptor& input_method = supported_input_methods->at(i);
- const std::string language_code =
- LanguageLibrary::GetLanguageCodeFromDescriptor(input_method);
- AddInputMethodToMaps(language_code, input_method);
- // Add the language code and the input method id to the sets.
- supported_language_code_set.insert(language_code);
- supported_input_method_id_set.insert(input_method.id);
- // Remember the pair.
- id_to_descriptor_map.insert(
- std::make_pair(input_method.id, &input_method));
+void LanguageConfigView::OnAddLanguage(const std::string& language_code) {
+ // Skip if the language is already in the preferred_language_codes_.
+ if (model.HasLanguageCode(language_code)) {
+ return;
}
-
- // Go through the languages listed in kExtraLanguages.
- for (size_t i = 0; i < arraysize(kExtraLanguages); ++i) {
- const char* language_code = kExtraLanguages[i].language_code;
- const char* input_method_id = kExtraLanguages[i].input_method_id;
- std::map<std::string, const InputMethodDescriptor*>::const_iterator iter =
- id_to_descriptor_map.find(input_method_id);
- // If the associated input method descriptor is found, add the
- // language code and the input method.
- if (iter != id_to_descriptor_map.end()) {
- const InputMethodDescriptor& input_method = *(iter->second);
- AddInputMethodToMaps(language_code, input_method);
- // Add the language code and the input method id to the sets.
- supported_language_code_set.insert(language_code);
- supported_input_method_id_set.insert(input_method.id);
- }
+ // Activate the first input language associated with the language. We have
+ // to call this before the OnItemsAdded() call below so the checkbox
+ // for the first input language gets checked.
+ std::vector<std::string> input_method_ids;
+ model.GetInputMethodIdsFromLanguageCode(language_code, &input_method_ids);
+ if (!input_method_ids.empty()) {
+ model.SetInputMethodActivated(input_method_ids[0], true);
}
- // Build the vectors from the sets.
- supported_language_codes_.assign(supported_language_code_set.begin(),
- supported_language_code_set.end());
- supported_input_method_ids_.assign(supported_input_method_id_set.begin(),
- supported_input_method_id_set.end());
+ // Append the language to the list of language codes.
+ const int added_at = model.AddLanguageCode(language_code);
+ // Notify the table that the new row added at |added_at|.
+ preferred_language_table_->OnItemsAdded(added_at, 1);
+ // For some reason, OnItemsAdded() alone does not redraw the table. Need
+ // to tell the table that items are changed. TODO(satorux): Investigate
+ // if it's a bug in TableView2.
+ preferred_language_table_->OnItemsChanged(
+ 0, model.num_preferred_language_codes());
+ // Switch to the row added.
+ preferred_language_table_->SelectRow(added_at);
+
+ // Mark the language to be ignored.
+ add_language_combobox_model_->SetIgnored(language_code, true);
+ ResetAddLanguageCombobox();
}
-void LanguageConfigModel::AddInputMethodToMaps(
- const std::string& language_code,
- const InputMethodDescriptor& input_method) {
- id_to_language_code_map_.insert(
- std::make_pair(input_method.id, language_code));
- id_to_display_name_map_.insert(
- std::make_pair(input_method.id, LanguageMenuL10nUtil::GetStringUTF8(
- input_method.display_name)));
- language_code_to_ids_map_.insert(
- std::make_pair(language_code, input_method.id));
+void LanguageConfigView::OnRemoveLanguage() {
+ const int row = preferred_language_table_->GetFirstSelectedRow();
+ const std::string& language_code = model.preferred_language_code_at(row);
+ // Mark the language not to be ignored.
+ add_language_combobox_model_->SetIgnored(language_code, false);
+ ResetAddLanguageCombobox();
+ // Deactivate the associated input methods.
+ model.DeactivateInputMethodsFor(language_code);
+ // Remove the language code and the row from the table.
+ model.RemoveLanguageAt(row);
+ preferred_language_table_->OnItemsRemoved(row, 1);
+ // Switch to the previous row, or the first row.
+ // There should be at least one row in the table.
+ preferred_language_table_->SelectRow(std::max(row - 1, 0));
+}
+
+void LanguageConfigView::ResetAddLanguageCombobox() {
+ // -1 to ignore "Add language". If there are more than one language,
+ // enable the combobox. Otherwise, disable it.
+ if (add_language_combobox_model_->GetItemCount() - 1 > 0) {
+ add_language_combobox_->SetEnabled(true);
+ } else {
+ add_language_combobox_->SetEnabled(false);
+ }
+ // Go back to the initial "Add language" state.
+ add_language_combobox_->ModelChanged();
+ add_language_combobox_->SetSelectedItem(0);
}
views::View* LanguageConfigView::CreateContentsOnLeft() {
@@ -748,78 +484,121 @@ views::View* LanguageConfigView::CreateContentsOnBottom() {
return contents;
}
-void LanguageConfigView::OnAddLanguage(const std::string& language_code) {
- // Skip if the language is already in the preferred_language_codes_.
- if (model.HasLanguageCode(language_code)) {
- return;
- }
- // Activate the first input language associated with the language. We have
- // to call this before the OnItemsAdded() call below so the checkbox
- // for the first input language gets checked.
- std::vector<std::string> input_method_ids;
- model.GetInputMethodIdsFromLanguageCode(language_code, &input_method_ids);
- if (!input_method_ids.empty()) {
- model.SetInputMethodActivated(input_method_ids[0], true);
- }
+views::View* LanguageConfigView::CreatePerLanguageConfigView(
+ const std::string& target_language_code) {
+ views::View* contents = new views::View;
+ GridLayout* layout = new GridLayout(contents);
+ contents->SetLayoutManager(layout);
- // Append the language to the list of language codes.
- const int added_at = model.AddLanguageCode(language_code);
- // Notify the table that the new row added at |added_at|.
- preferred_language_table_->OnItemsAdded(added_at, 1);
- // For some reason, OnItemsAdded() alone does not redraw the table. Need
- // to tell the table that items are changed. TODO(satorux): Investigate
- // if it's a bug in TableView2.
- preferred_language_table_->OnItemsChanged(
- 0, model.num_preferred_language_codes());
- // Switch to the row added.
- preferred_language_table_->SelectRow(added_at);
+ // Set up column sets for the grid layout.
+ ColumnSet* column_set = layout->AddColumnSet(kPerLanguageTitleColumnSetId);
+ column_set->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 0,
+ GridLayout::USE_PREF, 0, 0);
- // Mark the language to be ignored.
- add_language_combobox_model_->SetIgnored(language_code, true);
- ResetAddLanguageCombobox();
-}
+ column_set = layout->AddColumnSet(kPerLanguageDoubleColumnSetId);
+ column_set->AddPaddingColumn(0, kUnrelatedControlHorizontalSpacing);
+ column_set->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 0,
+ GridLayout::USE_PREF, 0, 0);
+ column_set->AddPaddingColumn(0, kRelatedControlHorizontalSpacing);
+ column_set->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 0,
+ GridLayout::USE_PREF, 0, 0);
-void LanguageConfigView::OnRemoveLanguage() {
- const int row = preferred_language_table_->GetFirstSelectedRow();
- const std::string& language_code = model.preferred_language_code_at(row);
- // Mark the language not to be ignored.
- add_language_combobox_model_->SetIgnored(language_code, false);
- ResetAddLanguageCombobox();
- // Deactivate the associated input methods.
- model.DeactivateInputMethodsFor(language_code);
- // Remove the language code and the row from the table.
- model.RemoveLanguageAt(row);
- preferred_language_table_->OnItemsRemoved(row, 1);
- // Switch to the previous row, or the first row.
- // There should be at least one row in the table.
- preferred_language_table_->SelectRow(std::max(row - 1, 0));
+ column_set = layout->AddColumnSet(kPerLanguageSingleColumnSetId);
+ column_set->AddPaddingColumn(0, kUnrelatedControlHorizontalSpacing);
+ column_set->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 0,
+ GridLayout::USE_PREF, 0, 0);
+
+ AddUiLanguageSection(target_language_code, layout);
+ layout->AddPaddingRow(0, kUnrelatedControlVerticalSpacing);
+ AddInputMethodSection(target_language_code, layout);
+
+ return contents;
}
-void LanguageConfigView::ResetAddLanguageCombobox() {
- // -1 to ignore "Add language". If there are more than one language,
- // enable the combobox. Otherwise, disable it.
- if (add_language_combobox_model_->GetItemCount() - 1 > 0) {
- add_language_combobox_->SetEnabled(true);
+void LanguageConfigView::AddUiLanguageSection(const std::string& language_code,
+ views::GridLayout* layout) {
+ // Create the language name label.
+ const std::string application_locale =
+ g_browser_process->GetApplicationLocale();
+ const string16 language_name16 = l10n_util::GetDisplayNameForLocale(
+ language_code, application_locale, true);
+ const std::wstring language_name
+ = LanguageConfigModel::MaybeRewriteLanguageName(
+ UTF16ToWide(language_name16));
+ views::Label* language_name_label = new views::Label(language_name);
+ language_name_label->SetFont(
+ language_name_label->font().DeriveFont(0, gfx::Font::BOLD));
+
+ // Add the language name label.
+ layout->StartRow(0, kPerLanguageTitleColumnSetId);
+ layout->AddView(language_name_label);
+ layout->AddPaddingRow(0, kRelatedControlVerticalSpacing);
+
+ layout->StartRow(0, kPerLanguageSingleColumnSetId);
+ if (application_locale == language_code) {
+ layout->AddView(
+ new views::Label(
+ l10n_util::GetStringF(
+ IDS_OPTIONS_SETTINGS_LANGUAGES_IS_DISPLAYED_IN_THIS_LANGUAGE,
+ l10n_util::GetString(IDS_PRODUCT_OS_NAME))));
} else {
- add_language_combobox_->SetEnabled(false);
+ UiLanguageButton* button = new UiLanguageButton(
+ this, l10n_util::GetStringF(
+ IDS_OPTIONS_SETTINGS_LANGUAGES_DISPLAY_IN_THIS_LANGUAGE,
+ l10n_util::GetString(IDS_PRODUCT_OS_NAME)),
+ language_code);
+ button->set_tag(kChangeUiLanguageButton);
+ layout->AddView(button);
}
- // Go back to the initial "Add language" state.
- add_language_combobox_->ModelChanged();
- add_language_combobox_->SetSelectedItem(0);
}
-void LanguageConfigModel::DeactivateInputMethodsFor(
- const std::string& language_code) {
- for (size_t i = 0; i < num_supported_input_method_ids(); ++i) {
- if (GetLanguageCodeFromInputMethodId(
- supported_input_method_id_at(i)) ==
- language_code) {
- // What happens if we disable the input method currently active?
- // IBus should take care of it, so we don't do anything special
- // here. See crosbug.com/2443.
- SetInputMethodActivated(supported_input_method_id_at(i), false);
- // Do not break; here in order to disable all engines that belong to
- // |language_code|.
+void LanguageConfigView::AddInputMethodSection(
+ const std::string& language_code,
+ views::GridLayout* layout) {
+ // Create the input method title label.
+ views::Label* input_method_title_label = new views::Label(
+ l10n_util::GetString(
+ IDS_OPTIONS_SETTINGS_LANGUAGES_INPUT_METHOD));
+ input_method_title_label->SetFont(
+ input_method_title_label->font().DeriveFont(0, gfx::Font::BOLD));
+
+ // Add the input method title label.
+ layout->StartRow(0, kPerLanguageTitleColumnSetId);
+ layout->AddView(input_method_title_label);
+ layout->AddPaddingRow(0, kRelatedControlVerticalSpacing);
+
+ // Add input method names and configuration buttons.
+ input_method_checkboxes_.clear();
+
+ // Get the list of input method ids associated with the language code.
+ std::vector<std::string> input_method_ids;
+ model.GetInputMethodIdsFromLanguageCode(language_code, &input_method_ids);
+
+ for (size_t i = 0; i < input_method_ids.size(); ++i) {
+ const std::string& input_method_id = input_method_ids[i];
+ const std::string display_name = model.GetInputMethodDisplayNameFromId(
+ input_method_id);
+ layout->StartRow(0, kPerLanguageDoubleColumnSetId);
+ InputMethodCheckbox* checkbox
+ = new InputMethodCheckbox(UTF8ToWide(display_name),
+ input_method_id);
+ checkbox->set_listener(this);
+ checkbox->set_tag(kSelectInputMethodButton);
+ if (model.InputMethodIsActivated(input_method_id)) {
+ checkbox->SetChecked(true);
+ }
+
+ layout->AddView(checkbox);
+ input_method_checkboxes_.insert(checkbox);
+ // Add "configure" button for the input method if we have a
+ // configuration dialog for it.
+ if (input_method_config_view_map_.count(input_method_id) > 0) {
+ InputMethodButton* button = new InputMethodButton(
+ this,
+ l10n_util::GetString(IDS_OPTIONS_SETTINGS_LANGUAGES_CONFIGURE),
+ input_method_id);
+ button->set_tag(kConfigureInputMethodButton);
+ layout->AddView(button);
}
}
}
@@ -835,66 +614,6 @@ views::DialogDelegate* LanguageConfigView::CreateInputMethodConfigureView(
return NULL;
}
-void LanguageConfigModel::Observe(NotificationType type,
- const NotificationSource& source,
- const NotificationDetails& details) {
- if (type == NotificationType::PREF_CHANGED) {
- NotifyPrefChanged();
- }
-}
-
-void LanguageConfigView::ItemChanged(views::Combobox* combobox,
- int prev_index,
- int new_index) {
- // Ignore the first item used for showing "Add language".
- if (new_index <= 0) {
- return;
- }
- // Get the language selected.
- std::string language_selected = add_language_combobox_model_->
- GetLocaleFromIndex(
- add_language_combobox_model_->GetLanguageIndex(new_index));
- OnAddLanguage(language_selected);
-}
-
-void LanguageConfigModel::SetInputMethodActivated(
- const std::string& input_method_id, bool activated) {
- DCHECK(!input_method_id.empty());
- std::vector<std::string> input_method_ids;
- GetActiveInputMethodIds(&input_method_ids);
-
- std::set<std::string> input_method_id_set(input_method_ids.begin(),
- input_method_ids.end());
- if (activated) {
- // Add |id| if it's not already added.
- input_method_id_set.insert(input_method_id);
- } else {
- input_method_id_set.erase(input_method_id);
- }
-
- // Update Chrome's preference.
- std::vector<std::string> new_input_method_ids(input_method_id_set.begin(),
- input_method_id_set.end());
- UpdateInputMethodPreferences(new_input_method_ids);
-}
-
-bool LanguageConfigModel::InputMethodIsActivated(
- const std::string& input_method_id) {
- std::vector<std::string> input_method_ids;
- GetActiveInputMethodIds(&input_method_ids);
- return (std::find(input_method_ids.begin(), input_method_ids.end(),
- input_method_id) != input_method_ids.end());
-}
-
-void LanguageConfigModel::GetActiveInputMethodIds(
- std::vector<std::string>* out_input_method_ids) {
- const std::wstring value = preload_engines_.GetValue();
- out_input_method_ids->clear();
- if (!value.empty()) {
- SplitString(WideToUTF8(value), ',', out_input_method_ids);
- }
-}
-
void LanguageConfigView::MaybeDisableLastCheckbox() {
std::vector<std::string> input_method_ids;
model.GetActiveInputMethodIds(&input_method_ids);
@@ -916,181 +635,4 @@ void LanguageConfigView::EnableAllCheckboxes() {
}
}
-std::string LanguageConfigModel::GetLanguageCodeFromInputMethodId(
- const std::string& input_method_id) const {
- std::map<std::string, std::string>::const_iterator iter
- = id_to_language_code_map_.find(input_method_id);
- return (iter == id_to_language_code_map_.end()) ?
- // Returning |kDefaultLanguageCode| is not for Chrome OS but for Ubuntu
- // where the ibus-xkb-layouts module could be missing.
- kDefaultLanguageCode : iter->second;
-}
-
-std::string LanguageConfigModel::GetInputMethodDisplayNameFromId(
- const std::string& input_method_id) const {
- // |kDefaultDisplayName| is not for Chrome OS. See the comment above.
- static const char kDefaultDisplayName[] = "USA";
- std::map<std::string, std::string>::const_iterator iter
- = id_to_display_name_map_.find(input_method_id);
- return (iter == id_to_display_name_map_.end()) ?
- kDefaultDisplayName : iter->second;
-}
-
-void LanguageConfigModel::GetInputMethodIdsFromLanguageCode(
- const std::string& language_code,
- std::vector<std::string>* input_method_ids) const {
- DCHECK(input_method_ids);
- input_method_ids->clear();
-
- std::pair<LanguageCodeToIdsMap::const_iterator,
- LanguageCodeToIdsMap::const_iterator> range =
- language_code_to_ids_map_.equal_range(language_code);
- for (LanguageCodeToIdsMap::const_iterator iter = range.first;
- iter != range.second; ++iter) {
- input_method_ids->push_back(iter->second);
- }
- // Reorder the input methods.
- ReorderInputMethodIdsForLanguageCode(language_code, input_method_ids);
-}
-
-void LanguageConfigModel::NotifyPrefChanged() {
- std::vector<std::string> input_method_ids;
- GetActiveInputMethodIds(&input_method_ids);
-
- std::set<std::string> language_code_set;
- for (size_t i = 0; i < input_method_ids.size(); ++i) {
- const std::string language_code =
- GetLanguageCodeFromInputMethodId(input_method_ids[i]);
- language_code_set.insert(language_code);
- }
-
- preferred_language_codes_.clear();
- preferred_language_codes_.assign(
- language_code_set.begin(), language_code_set.end());
- LanguageConfigModel::SortLanguageCodesByNames(&preferred_language_codes_);
-}
-
-std::wstring LanguageConfigModel::MaybeRewriteLanguageName(
- const std::wstring& language_name) {
- // "t" is used as the language code for input methods that don't fall
- // under any other languages.
- if (language_name == L"t") {
- return l10n_util::GetString(
- IDS_OPTIONS_SETTINGS_LANGUAGES_OTHERS);
- }
- return language_name;
-}
-
-std::wstring LanguageConfigModel::GetLanguageDisplayNameFromCode(
- const std::string& language_code) {
- return MaybeRewriteLanguageName(UTF16ToWide(
- l10n_util::GetDisplayNameForLocale(
- language_code, g_browser_process->GetApplicationLocale(),
- true)));
-}
-
-namespace {
-
-// The comparator is used for sorting language codes by their
-// corresponding language names, using the ICU collator.
-struct CompareLanguageCodesByLanguageName
- : std::binary_function<const std::string&, const std::string&, bool> {
- explicit CompareLanguageCodesByLanguageName(icu::Collator* collator)
- : collator_(collator) {
- }
-
- // Calling GetLanguageDisplayNameFromCode() in the comparator is not
- // efficient, but acceptable as the function is cheap, and the language
- // list is short (about 40 at most).
- bool operator()(const std::string& s1, const std::string& s2) const {
- const std::wstring key1 =
- LanguageConfigModel::GetLanguageDisplayNameFromCode(s1);
- const std::wstring key2 =
- LanguageConfigModel::GetLanguageDisplayNameFromCode(s2);
- return l10n_util::StringComparator<std::wstring>(collator_)(key1, key2);
- }
-
- icu::Collator* collator_;
-};
-
-// The comparator is used for sorting input method ids by their
-// corresponding language names, using the ICU collator.
-struct CompareInputMethodIdsByLanguageName
- : std::binary_function<const std::string&, const std::string&, bool> {
- CompareInputMethodIdsByLanguageName(
- icu::Collator* collator,
- const std::map<std::string, std::string>& id_to_language_code_map)
- : comparator_(collator),
- id_to_language_code_map_(id_to_language_code_map) {
- }
-
- bool operator()(const std::string& s1, const std::string& s2) const {
- std::string language_code_1;
- std::map<std::string, std::string>::const_iterator iter =
- id_to_language_code_map_.find(s1);
- if (iter != id_to_language_code_map_.end()) {
- language_code_1 = iter->second;
- }
- std::string language_code_2;
- iter = id_to_language_code_map_.find(s2);
- if (iter != id_to_language_code_map_.end()) {
- language_code_2 = iter->second;
- }
- return comparator_(language_code_1, language_code_2);
- }
-
- const CompareLanguageCodesByLanguageName comparator_;
- const std::map<std::string, std::string>& id_to_language_code_map_;
-};
-
-} // namespace
-
-void LanguageConfigModel::SortLanguageCodesByNames(
- std::vector<std::string>* language_codes) {
- // We should build collator outside of the comparator. We cannot have
- // scoped_ptr<> in the comparator for a subtle STL reason.
- UErrorCode error = U_ZERO_ERROR;
- icu::Locale locale(g_browser_process->GetApplicationLocale().c_str());
- scoped_ptr<icu::Collator> collator(
- icu::Collator::createInstance(locale, error));
- if (U_FAILURE(error)) {
- collator.reset();
- }
- std::sort(language_codes->begin(), language_codes->end(),
- CompareLanguageCodesByLanguageName(collator.get()));
-}
-
-void LanguageConfigModel::SortInputMethodIdsByNames(
- const std::map<std::string, std::string>& id_to_language_code_map,
- std::vector<std::string>* input_method_ids) {
- UErrorCode error = U_ZERO_ERROR;
- icu::Locale locale(g_browser_process->GetApplicationLocale().c_str());
- scoped_ptr<icu::Collator> collator(
- icu::Collator::createInstance(locale, error));
- if (U_FAILURE(error)) {
- collator.reset();
- }
- std::stable_sort(input_method_ids->begin(), input_method_ids->end(),
- CompareInputMethodIdsByLanguageName(
- collator.get(), id_to_language_code_map));
-}
-
-void LanguageConfigModel::ReorderInputMethodIdsForLanguageCode(
- const std::string& language_code,
- std::vector<std::string>* input_method_ids) {
- for (size_t i = 0; i < arraysize(kLanguageDefaultInputMethodIds); ++i) {
- if (language_code == kLanguageDefaultInputMethodIds[i].language_code) {
- std::vector<std::string>::iterator iter =
- std::find(input_method_ids->begin(), input_method_ids->end(),
- kLanguageDefaultInputMethodIds[i].input_method_id);
- // If it's not on the top of |input_method_id|, swap it with the top one.
- if (iter != input_method_ids->end() &&
- iter != input_method_ids->begin()) {
- std::swap(*input_method_ids->begin(), *iter);
- }
- break; // Don't have to check other language codes.
- }
- }
-}
-
} // namespace chromeos
diff --git a/chrome/browser/chromeos/options/language_config_view.h b/chrome/browser/chromeos/options/language_config_view.h
index ce0972e..932167c 100644
--- a/chrome/browser/chromeos/options/language_config_view.h
+++ b/chrome/browser/chromeos/options/language_config_view.h
@@ -11,11 +11,8 @@
#include <vector>
#include "app/table_model.h"
-#include "chrome/browser/language_combobox_model.h"
-#include "chrome/browser/pref_member.h"
+#include "chrome/browser/chromeos/options/language_config_model.h"
#include "chrome/browser/views/options/options_page_view.h"
-#include "chrome/common/notification_service.h"
-#include "third_party/cros/chromeos_input_method.h"
#include "views/controls/button/native_button.h"
#include "views/controls/combobox/combobox.h"
#include "views/controls/label.h"
@@ -24,188 +21,12 @@
#include "views/grid_layout.h"
#include "views/window/dialog_delegate.h"
-class Profile;
-
namespace chromeos {
class InputMethodButton;
class InputMethodCheckbox;
class PreferredLanguageTableModel;
-// The combobox model is used for adding languages in the language config
-// view.
-class AddLanguageComboboxModel : public LanguageComboboxModel {
- public:
- AddLanguageComboboxModel(Profile* profile,
- const std::vector<std::string>& locale_codes);
- // LanguageComboboxModel overrides.
- virtual int GetItemCount();
- virtual std::wstring GetItemAt(int index);
-
- // Converts the given index (index of the items in the combobox) to the
- // index of the internal language list. The returned index can be used
- // for GetLocaleFromIndex() and GetLanguageNameAt().
- int GetLanguageIndex(int index) const;
-
- // Marks the given language code to be ignored. Ignored languages won't
- // be shown in the combobox. It would be simpler if we could remove and
- // add language codes from the model, but ComboboxModel does not allow
- // items to be added/removed. Thus we use |ignore_set_| instead.
- void SetIgnored(const std::string& language_code, bool ignored);
-
- private:
- std::set<std::string> ignore_set_;
- DISALLOW_COPY_AND_ASSIGN(AddLanguageComboboxModel);
-};
-
-// The model of LanguageConfigView.
-class LanguageConfigModel : public NotificationObserver {
- public:
- LanguageConfigModel(PrefService* pref_service);
-
- // Initializes the model.
- void Init();
-
- // Gets the list of active IME IDs like "pinyin" and "m17n:ar:kbd".
- void GetActiveInputMethodIds(
- std::vector<std::string>* out_input_method_ids);
-
- // Converts an input method ID to a language code of the IME. Returns "Eng"
- // when |input_method_id| is unknown.
- // Example: "hangul" => "ko"
- std::string GetLanguageCodeFromInputMethodId(
- const std::string& input_method_id) const;
-
- // Converts an input method ID to a display name of the IME. Returns
- // "USA" (US keyboard) when |input_method_id| is unknown.
- // Examples: "pinyin" => "Pinyin"
- // "m17n:ar:kbd" => "kbd (m17n)"
- std::string GetInputMethodDisplayNameFromId(
- const std::string& input_method_id) const;
-
- // Gets the list of input method ids associated with the given language
- // code. The original contents of |input_method_ids| will be lost.
- void GetInputMethodIdsFromLanguageCode(
- const std::string& language_code,
- std::vector<std::string>* input_method_ids) const;
-
- // Deactivates the input methods for the given language code.
- void DeactivateInputMethodsFor(const std::string& language_code);
-
- // Activates or deactivates an IME whose ID is |input_method_id|.
- void SetInputMethodActivated(const std::string& input_method_id,
- bool activated);
-
- // Returns true if an IME of |input_method_id| is activated.
- bool InputMethodIsActivated(const std::string& input_method_id);
-
- // Counts the number of active input methods for the given language code.
- size_t CountNumActiveInputMethods(const std::string& language_code);
-
- // Returns true if the language code is in the preferred language list.
- bool HasLanguageCode(const std::string& language_code) const;
-
- // Adds the given language to the preferred language list, and returns
- // the index of the row where the language is added.
- size_t AddLanguageCode(const std::string& language_code);
-
- // Removes the language at the given row.
- void RemoveLanguageAt(size_t row);
-
- // Updates Chrome's input method preferences.
- void UpdateInputMethodPreferences(
- const std::vector<std::string>& new_input_method_ids);
-
- // Callback for |preload_engines_| pref updates. Initializes the preferred
- // language codes based on the updated pref value.
- void NotifyPrefChanged();
-
- // NotificationObserver overrides.
- virtual void Observe(NotificationType type,
- const NotificationSource& source,
- const NotificationDetails& details);
-
- const std::string& preferred_language_code_at(size_t at) const {
- return preferred_language_codes_[at];
- }
-
- size_t num_preferred_language_codes() const {
- return preferred_language_codes_.size();
- }
-
- const std::string& supported_input_method_id_at(size_t at) const {
- return supported_input_method_ids_[at];
- }
-
- size_t num_supported_input_method_ids() const {
- return supported_input_method_ids_.size();
- }
-
- const std::vector<std::string>& supported_language_codes() const {
- return supported_language_codes_;
- }
-
- // Rewrites the language name and returns the modified version if
- // necessary. Otherwise, returns the given language name as is.
- // In particular, this rewrites the special language name used for input
- // methods that don't fall under any other languages.
- static std::wstring MaybeRewriteLanguageName(
- const std::wstring& language_name);
-
- // Converts a language code to a language display name, using the
- // current application locale. MaybeRewriteLanguageName() is called
- // internally.
- // Examples: "fr" => "French"
- // "en-US" => "English (United States)"
- static std::wstring GetLanguageDisplayNameFromCode(
- const std::string& language_code);
-
- // Sorts the given language codes by their corresponding language names,
- // using the unicode string comparator. Uses unstable sorting.
- static void SortLanguageCodesByNames(
- std::vector<std::string>* language_codes);
-
- // Sorts the given input method ids by their corresponding language names,
- // using the unicode string comparator. Uses stable sorting.
- static void SortInputMethodIdsByNames(
- const std::map<std::string, std::string>& id_to_language_code_map,
- std::vector<std::string>* input_method_ids);
-
- // Reorders the given input method ids for the language code. For
- // example, if |language_codes| is "fr" and |input_method_ids| contains
- // ["xkb:be::fra", and "xkb:fr::fra"], the list is reordered to
- // ["xkb:fr::fra", and "xkb:be::fra"], so that French keyboard layout
- // comes before Belgian keyboard layout.
- static void ReorderInputMethodIdsForLanguageCode(
- const std::string& language_code,
- std::vector<std::string>* input_method_ids);
-
- private:
- // Adds the given language code and input method pair to the internal maps.
- void AddInputMethodToMaps(const std::string& language_code,
- const InputMethodDescriptor& input_method);
-
- // Initializes id_to_{code,display_name}_map_ maps,
- // as well as supported_{language_codes,input_method_ids}_ vectors.
- void InitInputMethodIdMapsAndVectors();
-
- PrefService* pref_service_;
- // The codes of the preferred languages.
- std::vector<std::string> preferred_language_codes_;
- StringPrefMember preload_engines_;
- std::map<std::string, std::string> id_to_language_code_map_;
- std::map<std::string, std::string> id_to_display_name_map_;
- // List of supported language codes like "en" and "ja".
- std::vector<std::string> supported_language_codes_;
- // List of supported IME IDs like "pinyin" and "m17n:ar:kbd".
- std::vector<std::string> supported_input_method_ids_;
- // Map from language code to associated input method IDs.
- typedef std::multimap<std::string, std::string> LanguageCodeToIdsMap;
- LanguageCodeToIdsMap language_code_to_ids_map_;
-
- DISALLOW_COPY_AND_ASSIGN(LanguageConfigModel);
-};
-
// A dialog box for configuring the languages.
class LanguageConfigView : public TableModel,
public views::ButtonListener,
@@ -247,23 +68,14 @@ class LanguageConfigView : public TableModel,
virtual void SetObserver(TableModelObserver* observer);
virtual int RowCount();
- // Invoked when a language is added by the add combobox.
- void OnAddLanguage(const std::string& language_code);
-
- // Invoked when a language is removed by the remove button.
- void OnRemoveLanguage();
-
- // Resets the add language combobox to the initial "Add language" state.
- void ResetAddLanguageCombobox();
-
- // OptionsPageView overrides.
- virtual void InitControlLayout();
-
// views::Combobox::Listener overrides:
virtual void ItemChanged(views::Combobox* combobox,
int prev_index,
int new_index);
+ // OptionsPageView overrides.
+ virtual void InitControlLayout();
+
// Shows the language config dialog in a new window.
static void Show(Profile* profile, gfx::NativeWindow parent);
@@ -271,6 +83,15 @@ class LanguageConfigView : public TableModel,
// Initializes the input method config view.
void InitInputMethodConfigViewMap();
+ // Invoked when a language is added by the add combobox.
+ void OnAddLanguage(const std::string& language_code);
+
+ // Invoked when a language is removed by the remove button.
+ void OnRemoveLanguage();
+
+ // Resets the add language combobox to the initial "Add language" state.
+ void ResetAddLanguageCombobox();
+
// Creates the contents on the left, including the language table.
views::View* CreateContentsOnLeft();
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index 2604138..ee57084 100755
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -491,6 +491,8 @@
'browser/chromeos/options/internet_page_view.h',
'browser/chromeos/options/ip_config_view.cc',
'browser/chromeos/options/ip_config_view.h',
+ 'browser/chromeos/options/language_config_model.cc',
+ 'browser/chromeos/options/language_config_model.h',
'browser/chromeos/options/language_config_util.h',
'browser/chromeos/options/language_config_view.cc',
'browser/chromeos/options/language_config_view.h',
diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi
index c9a60d9..31f31a5 100755
--- a/chrome/chrome_tests.gypi
+++ b/chrome/chrome_tests.gypi
@@ -612,7 +612,7 @@
'browser/chromeos/login/cookie_fetcher_unittest.cc',
'browser/chromeos/login/google_authenticator_unittest.cc',
'browser/chromeos/login/mock_auth_response_handler.cc',
- 'browser/chromeos/options/language_config_view_test.cc',
+ 'browser/chromeos/options/language_config_model_unittest.cc',
'browser/chromeos/pipe_reader_unittest.cc',
'browser/chromeos/status/language_menu_button_unittest.cc',
'browser/chromeos/status/language_menu_l10n_util_unittest.cc',