diff options
author | mattm@chromium.org <mattm@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-08-19 02:09:01 +0000 |
---|---|---|
committer | mattm@chromium.org <mattm@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-08-19 02:09:01 +0000 |
commit | 43422122cbfb5d18a905c4ce10032ac28d6b509a (patch) | |
tree | 8bb4c0b5cde9b916b0ca20cd2c9ebdcc1a4cfd81 /chrome/browser/language_combobox_model.cc | |
parent | 3a49803cc38cd15a86247ab696c065f0c17e86ac (diff) | |
download | chromium_src-43422122cbfb5d18a905c4ce10032ac28d6b509a.zip chromium_src-43422122cbfb5d18a905c4ce10032ac28d6b509a.tar.gz chromium_src-43422122cbfb5d18a905c4ce10032ac28d6b509a.tar.bz2 |
Move LanguageComboboxModel to chrome/browser
BUG=13524
TEST=none
Review URL: http://codereview.chromium.org/172083
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@23683 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/language_combobox_model.cc')
-rw-r--r-- | chrome/browser/language_combobox_model.cc | 164 |
1 files changed, 164 insertions, 0 deletions
diff --git a/chrome/browser/language_combobox_model.cc b/chrome/browser/language_combobox_model.cc new file mode 100644 index 0000000..97efadd --- /dev/null +++ b/chrome/browser/language_combobox_model.cc @@ -0,0 +1,164 @@ +// Copyright (c) 2009 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/language_combobox_model.h" + +#include "app/l10n_util.h" +#include "base/string_util.h" +#include "chrome/browser/browser_process.h" +#include "chrome/browser/metrics/user_metrics.h" +#include "chrome/common/pref_service.h" +#include "grit/generated_resources.h" +#include "unicode/uloc.h" + +/////////////////////////////////////////////////////////////////////////////// +// LanguageComboboxModel used to populate a combobox with native names +// corresponding to the language code (e.g. English (United States) for en-US) +// + +LanguageComboboxModel::LanguageComboboxModel() + : profile_(NULL) { + // Enumerate the languages we know about. + const std::vector<std::string>& locale_codes = + l10n_util::GetAvailableLocales(); + InitNativeNames(locale_codes); +} + +LanguageComboboxModel::LanguageComboboxModel( + Profile* profile, const std::vector<std::string>& locale_codes) + : profile_(profile) { + InitNativeNames(locale_codes); +} + +void LanguageComboboxModel::InitNativeNames( + const std::vector<std::string>& locale_codes) { + const std::string app_locale = g_browser_process->GetApplicationLocale(); + for (size_t i = 0; i < locale_codes.size(); ++i) { + std::string locale_code_str = locale_codes[i]; + const char* locale_code = locale_codes[i].c_str(); + + // Internally, we use the language code of zh-CN and zh-TW, but we want the + // display names to be Chinese (Simplified) and Chinese (Traditional). To + // do that, we use zh-hans and zh-hant when using ICU's + // uloc_getDisplayName. + if (locale_code_str == "zh-CN") { + locale_code = "zh-hans"; + } else if (locale_code_str == "zh-TW") { + locale_code = "zh-hant"; + } + + UErrorCode error = U_ZERO_ERROR; + const int buffer_size = 1024; + string16 name_local; + int actual_size = uloc_getDisplayName(locale_code, app_locale.c_str(), + WriteInto(&name_local, buffer_size + 1), buffer_size, &error); + DCHECK(U_SUCCESS(error)); + name_local.resize(actual_size); + + string16 name_native; + actual_size = uloc_getDisplayName(locale_code, locale_code, + WriteInto(&name_native, buffer_size + 1), buffer_size, &error); + DCHECK(U_SUCCESS(error)); + name_native.resize(actual_size); + + locale_names_.push_back(UTF16ToWideHack(name_local)); + native_names_[UTF16ToWideHack(name_local)] = LocaleData( + UTF16ToWideHack(name_native), locale_codes[i]); + } + + // Sort using locale specific sorter. + l10n_util::SortStrings(g_browser_process->GetApplicationLocale(), + &locale_names_); +} + +// Overridden from ComboboxModel: +int LanguageComboboxModel::GetItemCount() { + return static_cast<int>(locale_names_.size()); +} + +std::wstring LanguageComboboxModel::GetItemAt(int index) { + DCHECK(static_cast<int>(locale_names_.size()) > index); + LocaleDataMap::const_iterator it = + native_names_.find(locale_names_[index]); + DCHECK(it != native_names_.end()); + + // If the name is the same in the native language and local language, + // don't show it twice. + if (it->second.native_name == locale_names_[index]) + return it->second.native_name; + + // We must add directionality formatting to both the native name and the + // locale name in order to avoid text rendering problems such as misplaced + // parentheses or languages appearing in the wrong order. + std::wstring locale_name_localized; + std::wstring locale_name; + if (l10n_util::AdjustStringForLocaleDirection(locale_names_[index], + &locale_name_localized)) + locale_name.assign(locale_name_localized); + else + locale_name.assign(locale_names_[index]); + + std::wstring native_name_localized; + std::wstring native_name; + if (l10n_util::AdjustStringForLocaleDirection(it->second.native_name, + &native_name_localized)) + native_name.assign(native_name_localized); + else + native_name.assign(it->second.native_name); + + // We used to have a localizable template here, but none of translators + // changed the format. We also want to switch the order of locale_name + // and native_name without going back to translators. + std::wstring formatted_item; + SStringPrintf(&formatted_item, L"%ls - %ls", locale_name.c_str(), + native_name.c_str()); + if (l10n_util::GetTextDirection() == l10n_util::RIGHT_TO_LEFT) + // Somehow combo box (even with LAYOUTRTL flag) doesn't get this + // right so we add RTL BDO (U+202E) to set the direction + // explicitly. + formatted_item.insert(0, L"\x202E"); + return formatted_item; +} + +// Return the locale for the given index. E.g., may return pt-BR. +std::string LanguageComboboxModel::GetLocaleFromIndex(int index) { + DCHECK(static_cast<int>(locale_names_.size()) > index); + LocaleDataMap::const_iterator it = + native_names_.find(locale_names_[index]); + DCHECK(it != native_names_.end()); + + return it->second.locale_code; +} + +int LanguageComboboxModel::GetIndexFromLocale(const std::string& locale) { + for (size_t i = 0; i < locale_names_.size(); ++i) { + LocaleDataMap::const_iterator it = + native_names_.find(locale_names_[i]); + DCHECK(it != native_names_.end()); + if (it->second.locale_code == locale) + return static_cast<int>(i); + } + return -1; +} + +// Returns the index of the language currently specified in the user's +// preference file. Note that it's possible for language A to be picked +// while chrome is currently in language B if the user specified language B +// via --lang. Since --lang is not a persistent setting, it seems that it +// shouldn't be reflected in this combo box. We return -1 if the value in +// the pref doesn't map to a know language (possible if the user edited the +// prefs file manually). +int LanguageComboboxModel::GetSelectedLanguageIndex(const std::wstring& prefs) { + PrefService* local_state; + if (!profile_) + local_state = g_browser_process->local_state(); + else + local_state = profile_->GetPrefs(); + + DCHECK(local_state); + const std::string& current_locale = + WideToASCII(local_state->GetString(prefs.c_str())); + + return GetIndexFromLocale(current_locale); +} |