Home | History | Annotate | Download | only in login
      1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "chrome/browser/chromeos/login/language_list.h"
      6 
      7 #include "base/i18n/rtl.h"
      8 #include "base/strings/string_split.h"
      9 #include "base/strings/stringprintf.h"
     10 #include "base/strings/utf_string_conversions.h"
     11 #include "chrome/browser/browser_process.h"
     12 #include "ui/base/l10n/l10n_util.h"
     13 
     14 namespace chromeos {
     15 
     16 LanguageList::LanguageList() {
     17   // Enumerate the languages we know about.
     18   const std::vector<std::string>& locale_codes =
     19       l10n_util::GetAvailableLocales();
     20   InitNativeNames(locale_codes);
     21 }
     22 
     23 LanguageList::~LanguageList() {}
     24 
     25 string16 LanguageList::GetLanguageNameAt(int index) const {
     26   DCHECK_LT(index, languages_count());
     27   LocaleDataMap::const_iterator locale_data =
     28       native_names_.find(locale_names_[index]);
     29   DCHECK(locale_data != native_names_.end());
     30 
     31   // If the name is the same in the native language and local language,
     32   // don't show it twice.
     33   if (locale_data->second.native_name == locale_names_[index])
     34     return locale_data->second.native_name;
     35 
     36   // We must add directionality formatting to both the native name and the
     37   // locale name in order to avoid text rendering problems such as misplaced
     38   // parentheses or languages appearing in the wrong order.
     39   string16 locale_name = locale_names_[index];
     40   base::i18n::AdjustStringForLocaleDirection(&locale_name);
     41 
     42   string16 native_name = locale_data->second.native_name;
     43   base::i18n::AdjustStringForLocaleDirection(&native_name);
     44 
     45   // We used to have a localizable template here, but none of translators
     46   // changed the format. We also want to switch the order of locale_name
     47   // and native_name without going back to translators.
     48   std::string formatted_item;
     49   base::SStringPrintf(&formatted_item, "%s - %s",
     50                       UTF16ToUTF8(locale_name).c_str(),
     51                       UTF16ToUTF8(native_name).c_str());
     52   if (base::i18n::IsRTL())
     53     // Somehow combo box (even with LAYOUTRTL flag) doesn't get this
     54     // right so we add RTL BDO (U+202E) to set the direction
     55     // explicitly.
     56     formatted_item.insert(0, "\xE2\x80\xAE");  // U+202E = UTF-8 0xE280AE
     57   return UTF8ToUTF16(formatted_item);
     58 }
     59 
     60 std::string LanguageList::GetLocaleFromIndex(int index) const {
     61   DCHECK(static_cast<int>(locale_names_.size()) > index);
     62   LocaleDataMap::const_iterator locale_data =
     63       native_names_.find(locale_names_[index]);
     64   DCHECK(locale_data != native_names_.end());
     65   return locale_data->second.locale_code;
     66 }
     67 
     68 int LanguageList::GetIndexFromLocale(const std::string& locale) const {
     69   for (size_t i = 0; i < locale_names_.size(); ++i) {
     70     LocaleDataMap::const_iterator locale_data =
     71         native_names_.find(locale_names_[i]);
     72     DCHECK(locale_data != native_names_.end());
     73     if (locale_data->second.locale_code == locale)
     74       return static_cast<int>(i);
     75   }
     76   return -1;
     77 }
     78 
     79 void LanguageList::CopySpecifiedLanguagesUp(const std::string& locale_codes) {
     80   DCHECK(!locale_names_.empty());
     81   std::vector<std::string> locale_codes_vector;
     82   base::SplitString(locale_codes, ',', &locale_codes_vector);
     83   for (size_t i = 0; i != locale_codes_vector.size(); ++i) {
     84     const int locale_index = GetIndexFromLocale(locale_codes_vector[i]);
     85     CHECK_NE(locale_index, -1);
     86     locale_names_.insert(locale_names_.begin(), locale_names_[locale_index]);
     87   }
     88 }
     89 
     90 void LanguageList::InitNativeNames(
     91     const std::vector<std::string>& locale_codes) {
     92   const std::string app_locale = g_browser_process->GetApplicationLocale();
     93   for (size_t i = 0; i < locale_codes.size(); ++i) {
     94     const char* locale_code = locale_codes[i].c_str();
     95 
     96     // TODO(jungshik): Even though these strings are used for the UI,
     97     // the old code does not add an RTL mark for RTL locales. Make sure
     98     // that it's ok without that.
     99     string16 name_in_current_ui =
    100         l10n_util::GetDisplayNameForLocale(locale_code, app_locale, false);
    101     string16 name_native =
    102         l10n_util::GetDisplayNameForLocale(locale_code, locale_code, false);
    103 
    104     locale_names_.push_back(name_in_current_ui);
    105     native_names_[name_in_current_ui] =
    106         LocaleData(name_native, locale_codes[i]);
    107   }
    108 
    109   // Sort using locale specific sorter.
    110   l10n_util::SortStrings16(g_browser_process->GetApplicationLocale(),
    111                            &locale_names_);
    112 }
    113 
    114 }  // namespace chromeos
    115