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 14namespace chromeos { 15 16LanguageList::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 23LanguageList::~LanguageList() {} 24 25base::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 base::string16 locale_name = locale_names_[index]; 40 base::i18n::AdjustStringForLocaleDirection(&locale_name); 41 42 base::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 base::UTF16ToUTF8(locale_name).c_str(), 51 base::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 base::UTF8ToUTF16(formatted_item); 58} 59 60std::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 68int 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 79void 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 90void 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 base::string16 name_in_current_ui = 100 l10n_util::GetDisplayNameForLocale(locale_code, app_locale, false); 101 base::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