diff options
-rw-r--r-- | chrome/browser/character_encoding.cc | 104 | ||||
-rw-r--r-- | chrome/browser/character_encoding.h | 29 | ||||
-rw-r--r-- | chrome/browser/encoding_menu_controller_delegate.cc | 26 | ||||
-rw-r--r-- | chrome/browser/spellchecker.cc | 13 | ||||
-rw-r--r-- | chrome/common/l10n_util.cc | 97 | ||||
-rw-r--r-- | chrome/common/l10n_util.h | 73 | ||||
-rw-r--r-- | chrome/test/automated_ui_tests/automated_ui_tests.cc | 16 |
7 files changed, 234 insertions, 124 deletions
diff --git a/chrome/browser/character_encoding.cc b/chrome/browser/character_encoding.cc index afcbbcd..2be87ae 100644 --- a/chrome/browser/character_encoding.cc +++ b/chrome/browser/character_encoding.cc @@ -40,8 +40,8 @@ static CanonicalEncodingData canonical_encoding_names[] = { { IDC_ENCODING_BIG5HKSCS, L"Big5-HKSCS", IDS_ENCODING_TRAD_CHINESE }, { IDC_ENCODING_KOREAN, L"windows-949", IDS_ENCODING_KOREAN }, { IDC_ENCODING_SHIFTJIS, L"Shift_JIS", IDS_ENCODING_JAPANESE }, - { IDC_ENCODING_ISO2022JP, L"ISO-2022-JP", IDS_ENCODING_JAPANESE }, { IDC_ENCODING_EUCJP, L"EUC-JP", IDS_ENCODING_JAPANESE }, + { IDC_ENCODING_ISO2022JP, L"ISO-2022-JP", IDS_ENCODING_JAPANESE }, { IDC_ENCODING_THAI, L"windows-874", IDS_ENCODING_THAI }, { IDC_ENCODING_ISO885915, L"ISO-8859-15", IDS_ENCODING_WESTERN }, { IDC_ENCODING_MACINTOSH, L"macintosh", IDS_ENCODING_WESTERN }, @@ -71,7 +71,8 @@ static CanonicalEncodingData canonical_encoding_names[] = { static const int canonical_encoding_names_length = arraysize(canonical_encoding_names); -typedef std::map<int, std::pair<const wchar_t*, int> > IdToCanonicalEncodingNameMapType; +typedef std::map<int, std::pair<const wchar_t*, int> > + IdToCanonicalEncodingNameMapType; typedef std::map<const std::wstring, int> CanonicalEncodingNameToIdMapType; class CanonicalEncodingMap { @@ -85,15 +86,15 @@ class CanonicalEncodingMap { return &locale_dependent_encoding_ids_; } - std::vector<int>* const current_display_encoding_ids() { - return ¤t_display_encoding_ids_; + std::vector<CharacterEncoding::EncodingInfo>* const current_display_encodings() { + return ¤t_display_encodings_; } private: scoped_ptr<IdToCanonicalEncodingNameMapType> id_to_encoding_name_map_; scoped_ptr<CanonicalEncodingNameToIdMapType> encoding_name_to_id_map_; std::vector<int> locale_dependent_encoding_ids_; - std::vector<int> current_display_encoding_ids_; + std::vector<CharacterEncoding::EncodingInfo> current_display_encodings_; DISALLOW_EVIL_CONSTRUCTORS(CanonicalEncodingMap); }; @@ -131,33 +132,25 @@ static CanonicalEncodingMap canonical_encoding_name_map_singleton; const int default_encoding_menus[] = { IDC_ENCODING_UTF16LE, - 0, IDC_ENCODING_ISO88591, IDC_ENCODING_WINDOWS1252, - 0, IDC_ENCODING_GBK, IDC_ENCODING_GB18030, IDC_ENCODING_BIG5, IDC_ENCODING_BIG5HKSCS, - 0, IDC_ENCODING_KOREAN, - 0, IDC_ENCODING_SHIFTJIS, - IDC_ENCODING_ISO2022JP, IDC_ENCODING_EUCJP, - 0, + IDC_ENCODING_ISO2022JP, IDC_ENCODING_THAI, - 0, IDC_ENCODING_ISO885915, IDC_ENCODING_MACINTOSH, IDC_ENCODING_ISO88592, IDC_ENCODING_WINDOWS1250, - 0, IDC_ENCODING_ISO88595, IDC_ENCODING_WINDOWS1251, IDC_ENCODING_KOI8R, IDC_ENCODING_KOI8U, - 0, IDC_ENCODING_ISO88597, IDC_ENCODING_WINDOWS1253, IDC_ENCODING_WINDOWS1254, @@ -166,7 +159,6 @@ const int default_encoding_menus[] = { IDC_ENCODING_ISO88598, IDC_ENCODING_WINDOWS1255, IDC_ENCODING_WINDOWS1258, - IDC_ENCODING_ISO88594, IDC_ENCODING_ISO885913, IDC_ENCODING_WINDOWS1257, @@ -182,7 +174,7 @@ const int default_encoding_menus_length = arraysize(default_encoding_menus); // comma, get available encoding ids and save them to |available_list|. // The parameter |maximum_size| indicates maximum size of encoding items we // want to get from the |encoding_list|. -static void ParseEncodingListSeparatedWithComma( +void ParseEncodingListSeparatedWithComma( const std::wstring& encoding_list, std::vector<int>* const available_list, size_t maximum_size) { WStringTokenizer tokenizer(encoding_list, L","); @@ -211,8 +203,33 @@ std::wstring GetEncodingDisplayName(std::wstring encoding_name, return category_name; } +int GetEncodingCategoryStringIdByCommandId(int id) { + const IdToCanonicalEncodingNameMapType* map = + canonical_encoding_name_map_singleton. + GetIdToCanonicalEncodingNameMapData(); + DCHECK(map); + + IdToCanonicalEncodingNameMapType::const_iterator found_name = map->find(id); + if (found_name != map->end()) + return found_name->second.second; + return 0; +} + +std::wstring GetEncodingCategoryStringByCommandId(int id) { + int category_id = GetEncodingCategoryStringIdByCommandId(id); + if (category_id) + return l10n_util::GetString(category_id); + return std::wstring(); +} + } // namespace +CharacterEncoding::EncodingInfo::EncodingInfo(int id) + : encoding_id(id) { + encoding_category_name = GetEncodingCategoryStringByCommandId(id), + encoding_display_name = GetCanonicalEncodingDisplayNameByCommandId(id); +} + // Static. int CharacterEncoding::GetCommandIdByCanonicalEncodingName( const std::wstring& encoding_name) { @@ -314,13 +331,14 @@ std::wstring CharacterEncoding::GetCanonicalEncodingNameByAliasName( // FireFox, we always put UTF-8 as toppest position, after then put user // recently selected encodings, then put local dependent encoding items. // At last, we put all rest encoding items. -const std::vector<int>* CharacterEncoding::GetCurrentDisplayEncodings( +const std::vector<CharacterEncoding::EncodingInfo>* CharacterEncoding::GetCurrentDisplayEncodings( + const std::wstring& locale, const std::wstring& locale_encodings, const std::wstring& recently_select_encodings) { std::vector<int>* const locale_dependent_encoding_list = canonical_encoding_name_map_singleton.locale_dependent_encoding_ids(); - std::vector<int>* const encoding_list = - canonical_encoding_name_map_singleton.current_display_encoding_ids(); + std::vector<CharacterEncoding::EncodingInfo>* const encoding_list = + canonical_encoding_name_map_singleton.current_display_encodings(); // Initialize locale dependent static encoding list. if (locale_dependent_encoding_list->empty() && !locale_encodings.empty()) @@ -337,7 +355,7 @@ const std::vector<int>* CharacterEncoding::GetCurrentDisplayEncodings( // Clear old encoding list since user recently selected encodings changed. encoding_list->clear(); // Always add UTF-8 to first encoding position. - encoding_list->push_back(IDC_ENCODING_UTF8); + encoding_list->push_back(EncodingInfo(IDC_ENCODING_UTF8)); std::set<int> inserted_encoding; inserted_encoding.insert(IDC_ENCODING_UTF8); @@ -352,8 +370,7 @@ const std::vector<int>* CharacterEncoding::GetCurrentDisplayEncodings( recently_select_encoding_list.insert(recently_select_encoding_list.begin(), locale_dependent_encoding_list->begin(), locale_dependent_encoding_list->end()); - std::vector<int>::const_iterator it; - for (it = recently_select_encoding_list.begin(); + for (std::vector<int>::iterator it = recently_select_encoding_list.begin(); it != recently_select_encoding_list.end(); ++it) { // Test whether we have met this encoding id. bool ok = inserted_encoding.insert(*it).second; @@ -361,27 +378,40 @@ const std::vector<int>* CharacterEncoding::GetCurrentDisplayEncodings( // happened, but just in case some one manually edit preference file. if (!ok) continue; - encoding_list->push_back(*it); + encoding_list->push_back(EncodingInfo(*it)); } // Append a separator; - encoding_list->push_back(0); + encoding_list->push_back(EncodingInfo(0)); + + // We need to keep "Unicode (UTF-16LE)" always at the top (among the rest + // of encodings) instead of being sorted along with other encodings. So if + // "Unicode (UTF-16LE)" is already in previous encodings, sort the rest + // of encodings. Otherwise Put "Unicode (UTF-16LE)" on the first of the + // rest of encodings, skip "Unicode (UTF-16LE)" and sort all left encodings. + int start_sorted_index = encoding_list->size(); + if (inserted_encoding.find(IDC_ENCODING_UTF16LE) == + inserted_encoding.end()) { + encoding_list->push_back(EncodingInfo(IDC_ENCODING_UTF16LE)); + inserted_encoding.insert(IDC_ENCODING_UTF16LE); + start_sorted_index++; + } - // Add those encodings which are in default_encoding_menus and does not - // override with locale-dependent encodings list. - bool previous_is_separator = true; + // Add the rest of encodings that are neither in the static encoding list + // nor in the list of recently selected encodings. + // Build the encoding list sorted in the current locale sorting order. for (int i = 0; i < default_encoding_menus_length; ++i) { int id = default_encoding_menus[i]; - if (id) { - // We have inserted this encoding, skip it. - if (inserted_encoding.find(id) != inserted_encoding.end()) - continue; - encoding_list->push_back(id); - previous_is_separator = false; - } else if (!previous_is_separator) { - encoding_list->push_back(0); - previous_is_separator = true; - } + // We have inserted this encoding, skip it. + if (inserted_encoding.find(id) != inserted_encoding.end()) + continue; + encoding_list->push_back(EncodingInfo(id)); } + // Sort the encoding list. + l10n_util::SortVectorWithStringKey(locale, + encoding_list, + start_sorted_index, + encoding_list->size(), + true); } DCHECK(!encoding_list->empty()); return encoding_list; diff --git a/chrome/browser/character_encoding.h b/chrome/browser/character_encoding.h index 6ef1b05..74dff89 100644 --- a/chrome/browser/character_encoding.h +++ b/chrome/browser/character_encoding.h @@ -17,6 +17,23 @@ class CharacterEncoding { // currently support. This is defined outside of Browser // to avoid cyclical dependencies. + // Structure to save encoding information. + struct EncodingInfo { + explicit EncodingInfo(int id); + // Gets string key of EncodingInfo. With this method, we can use + // l10n_util::SortVectorWithStringKey to sort the encoding menu items + // by current locale character sequence. We need to keep the order within + // encoding category name, that's why we use category name as key. + const std::wstring& GetStringKey() const { return encoding_category_name; } + + // Encoding command id. + int encoding_id; + // Encoding display name. + std::wstring encoding_display_name; + // Encoding category name. + std::wstring encoding_category_name; + }; + // Return canonical encoding name according to the command ID. // THIS FUNCTION IS NOT THREADSAFE. You must run this function // only in UI thread. @@ -46,18 +63,20 @@ class CharacterEncoding { static std::wstring GetCanonicalEncodingNameByAliasName( const std::wstring& alias_name); - // Returns the pointer of a vector of command ids corresponding to - // encodings to display in the encoding menu. The list begins with - // the locale-dependent static encodings and recently selected - // encodings is followed by the rest of encodings belonging to neither. + // Returns the pointer of a vector of EncodingInfos corresponding to + // encodings to display in the encoding menu. The locale-dependent static + // encodings come at the top of the list and recently selected encodings + // come next. Finally, the rest of encodings are listed. // The vector will be created and destroyed by CharacterEncoding. // The returned std::vector is maintained by this class. The parameter + // |locale| points to the current application (UI) locale. The parameter // |locale_encodings| is string of static encodings list which is from the // corresponding string resource that is stored in the resource bundle. // The parameter |recently_select_encodings| is string of encoding list which // is from user recently selected. THIS FUNCTION IS NOT THREADSAFE. You must // run this function only in UI thread. - static const std::vector<int>* GetCurrentDisplayEncodings( + static const std::vector<EncodingInfo>* GetCurrentDisplayEncodings( + const std::wstring& locale, const std::wstring& locale_encodings, const std::wstring& recently_select_encodings); diff --git a/chrome/browser/encoding_menu_controller_delegate.cc b/chrome/browser/encoding_menu_controller_delegate.cc index 133569b..6d636a2 100644 --- a/chrome/browser/encoding_menu_controller_delegate.cc +++ b/chrome/browser/encoding_menu_controller_delegate.cc @@ -108,30 +108,30 @@ void EncodingMenuControllerDelegate::BuildEncodingMenu( encoding_menu->AppendSeparator(); // Create current display encoding list. std::wstring cur_locale = g_browser_process->GetApplicationLocale(); - const std::vector<int>* encoding_ids; + const std::vector<CharacterEncoding::EncodingInfo>* encodings; // Build the list of encoding ids : It is made of the // locale-dependent short list, the cache of recently selected // encodings and other encodings. - encoding_ids = CharacterEncoding::GetCurrentDisplayEncodings( + encodings = CharacterEncoding::GetCurrentDisplayEncodings( + cur_locale, profile->GetPrefs()->GetString(prefs::kStaticEncodings), profile->GetPrefs()->GetString(prefs::kRecentlySelectedEncoding)); - DCHECK(encoding_ids); - DCHECK(!encoding_ids->empty()); - unsigned len = static_cast<unsigned>(encoding_ids->size()); + DCHECK(encodings); + DCHECK(!encodings->empty()); + unsigned len = static_cast<unsigned>(encodings->size()); // Add encoding menus. - std::vector<int>::const_iterator it; - for (it = encoding_ids->begin(); it != encoding_ids->end(); ++it) { - if (*it) { - std::wstring encoding = - CharacterEncoding::GetCanonicalEncodingDisplayNameByCommandId(*it); + std::vector<CharacterEncoding::EncodingInfo>::const_iterator it; + for (it = encodings->begin(); it != encodings->end(); ++it) { + if (it->encoding_id) { + std::wstring encoding = it->encoding_display_name; std::wstring bidi_safe_encoding; if (l10n_util::AdjustStringForLocaleDirection(encoding, &bidi_safe_encoding)) encoding.swap(bidi_safe_encoding); - encoding_menu->AppendMenuItem(*it, encoding, Menu::RADIO); - } - else + encoding_menu->AppendMenuItem(it->encoding_id, encoding, Menu::RADIO); + } else { encoding_menu->AppendSeparator(); + } } } diff --git a/chrome/browser/spellchecker.cc b/chrome/browser/spellchecker.cc index c36c522..5f3f7d7 100644 --- a/chrome/browser/spellchecker.cc +++ b/chrome/browser/spellchecker.cc @@ -33,6 +33,7 @@ using base::TimeTicks; static const int kMaxSuggestions = 5; // Max number of dictionary suggestions. namespace { + static const struct { // The language. const wchar_t* language; @@ -120,8 +121,8 @@ SpellChecker::Language SpellChecker::GetCorrespondingSpellCheckLanguage( } // Look for a match by comparing only language parts. All the 'en-RR' - // except for 'en-GB' exactly matched in the above loop, will match - // 'en-US'. This is not ideal because 'en-AU', 'en-ZA', 'en-NZ' had + // except for 'en-GB' exactly matched in the above loop, will match + // 'en-US'. This is not ideal because 'en-AU', 'en-ZA', 'en-NZ' had // better be matched with 'en-GB'. This does not handle cases like // 'az-Latn-AZ' vs 'az-Arab-AZ', either, but we don't use 3-part // locale ids with a script code in the middle, yet. @@ -134,7 +135,7 @@ SpellChecker::Language SpellChecker::GetCorrespondingSpellCheckLanguage( if (spellcheck_language.substr(0, spellcheck_language.find(L'-')) == language_part) return spellcheck_language; - } + } // No match found - return blank. return Language(); @@ -343,7 +344,7 @@ std::wstring SpellChecker::GetVersionedFileName(const Language& input_language, // Use this struct to insert version strings for dictionary files which have // special version strings, other than the default version string. For eight // languages (included below in the struct), the version is kept at 1-1. The - // others (19 of them) have been updated to new default version 1-2 which + // others (19 of them) have been updated to new default version 1-2 which // contains many new words. // TODO (sidchat): Work on these 8 languages to bring them upto version 1-2. static const struct { @@ -363,7 +364,7 @@ std::wstring SpellChecker::GetVersionedFileName(const Language& input_language, {"hi-IN", "-1-1"} }; - // Generate the bdict file name using default version string or special + // Generate the bdict file name using default version string or special // version string, depending on the language. std::wstring language = GetSpellCheckLanguageRegion(input_language); std::wstring versioned_bdict_file_name(language + kDefaultVersionString + @@ -371,7 +372,7 @@ std::wstring SpellChecker::GetVersionedFileName(const Language& input_language, std::string language_string(WideToUTF8(language)); for (size_t i = 0; i < ARRAYSIZE_UNSAFE(special_version_string); ++i) { if (language_string == special_version_string[i].language) { - versioned_bdict_file_name = + versioned_bdict_file_name = language + UTF8ToWide(special_version_string[i].version) + L".bdic"; break; } diff --git a/chrome/common/l10n_util.cc b/chrome/common/l10n_util.cc index a8749c8..c4b276f 100644 --- a/chrome/common/l10n_util.cc +++ b/chrome/common/l10n_util.cc @@ -4,16 +4,11 @@ #include "build/build_config.h" -#include <algorithm> - #include "chrome/common/l10n_util.h" #include "base/command_line.h" #include "base/file_util.h" -#include "base/logging.h" #include "base/path_service.h" -#include "base/scoped_ptr.h" -#include "base/string_util.h" #include "chrome/common/chrome_paths.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/gfx/chrome_canvas.h" @@ -24,8 +19,6 @@ #if defined(OS_WIN) #include "chrome/views/view.h" #endif // defined(OS_WIN) -#include "unicode/coll.h" -#include "unicode/locid.h" #include "unicode/rbbi.h" #include "unicode/uchar.h" @@ -99,45 +92,6 @@ UBool SetICUDefaultLocale(const std::wstring& locale_string) { return U_SUCCESS(error_code); } -// Compares two wstrings and returns true if the first arg is less than the -// second arg. This uses the locale specified in the constructor. -class StringComparator : public std::binary_function<const std::wstring&, - const std::wstring&, - bool> { - public: - explicit StringComparator(Collator* collator) - : collator_(collator) { } - - // Returns true if lhs preceeds rhs. - bool operator() (const std::wstring& lhs, const std::wstring& rhs) { - UErrorCode error = U_ZERO_ERROR; -#if defined(WCHAR_T_IS_UTF32) - // Need to convert to UTF-16 to be compatible with UnicodeString's - // constructor. - string16 lhs_utf16 = WideToUTF16(lhs); - string16 rhs_utf16 = WideToUTF16(rhs); - - UCollationResult result = collator_->compare( - static_cast<const UChar*>(lhs_utf16.c_str()), - static_cast<int>(lhs_utf16.length()), - static_cast<const UChar*>(rhs_utf16.c_str()), - static_cast<int>(rhs_utf16.length()), - error); -#else - UCollationResult result = collator_->compare( - static_cast<const UChar*>(lhs.c_str()), static_cast<int>(lhs.length()), - static_cast<const UChar*>(rhs.c_str()), static_cast<int>(rhs.length()), - error); -#endif - DCHECK(U_SUCCESS(error)); - - return result == UCOL_LESS; - } - - private: - Collator* collator_; -}; - // Returns true if |locale_name| has an alias in the ICU data file. bool IsDuplicateName(const std::string& locale_name) { static const char* const kDuplicateNames[] = { @@ -250,6 +204,35 @@ std::wstring GetSystemLocale() { return ASCIIToWide(ret); } +// Compares the character data stored in two different strings by specified +// Collator instance. +UCollationResult CompareStringWithCollator(const Collator* collator, + const std::wstring& lhs, + const std::wstring& rhs) { + DCHECK(collator); + UErrorCode error = U_ZERO_ERROR; +#if defined(WCHAR_T_IS_UTF32) + // Need to convert to UTF-16 to be compatible with UnicodeString's + // constructor. + string16 lhs_utf16 = WideToUTF16(lhs); + string16 rhs_utf16 = WideToUTF16(rhs); + + UCollationResult result = collator->compare( + static_cast<const UChar*>(lhs_utf16.c_str()), + static_cast<int>(lhs_utf16.length()), + static_cast<const UChar*>(rhs_utf16.c_str()), + static_cast<int>(rhs_utf16.length()), + error); +#else + UCollationResult result = collator->compare( + static_cast<const UChar*>(lhs.c_str()), static_cast<int>(lhs.length()), + static_cast<const UChar*>(rhs.c_str()), static_cast<int>(rhs.length()), + error); +#endif + DCHECK(U_SUCCESS(error)); + return result; +} + } // namespace namespace l10n_util { @@ -601,18 +584,20 @@ void HWNDSetRTLLayout(HWND hwnd) { } #endif // defined(OS_WIN) +// Specialization of operator() method for std::wstring version. +template <> +bool StringComparator<std::wstring>::operator()(const std::wstring& lhs, + const std::wstring& rhs) { + // If we can not get collator instance for specified locale, just do simple + // string compare. + if (!collator_) + return lhs < rhs; + return CompareStringWithCollator(collator_, lhs, rhs) == UCOL_LESS; +}; + void SortStrings(const std::wstring& locale, std::vector<std::wstring>* strings) { - UErrorCode error = U_ZERO_ERROR; - Locale loc(WideToUTF8(locale).c_str()); - scoped_ptr<Collator> collator(Collator::createInstance(loc, error)); - if (U_FAILURE(error)) { - // Just do an string sort. - sort(strings->begin(), strings->end()); - return; - } - StringComparator c(collator.get()); - sort(strings->begin(), strings->end(), c); + SortVectorWithStringKey(locale, strings, false); } const std::vector<std::wstring>& GetAvailableLocales() { diff --git a/chrome/common/l10n_util.h b/chrome/common/l10n_util.h index e587d3b..51f784b 100644 --- a/chrome/common/l10n_util.h +++ b/chrome/common/l10n_util.h @@ -13,11 +13,17 @@ #if defined(OS_WIN) #include <windows.h> #endif +#include <algorithm> #include <string> #include <vector> #include "base/basictypes.h" +#include "base/logging.h" +#include "base/scoped_ptr.h" +#include "base/string_util.h" #include "third_party/icu38/public/common/unicode/ubidi.h" +#include "unicode/coll.h" +#include "unicode/locid.h" class PrefService; @@ -172,6 +178,73 @@ int DefaultCanvasTextAlignment(); void HWNDSetRTLLayout(HWND hwnd); #endif +// Compares two elements' string keys and returns true if the first element's +// string key is less than the second element's string key. The Element must +// have a method like the follow format to return the string key. +// const std::wstring& GetStringKey() const; +// This uses the locale specified in the constructor. +template <class Element> +class StringComparator : public std::binary_function<const Element&, + const Element&, + bool> { + public: + explicit StringComparator(Collator* collator) + : collator_(collator) { } + + // Returns true if lhs precedes rhs. + bool operator()(const Element& lhs, const Element& rhs) { + const std::wstring& lhs_string_key = lhs.GetStringKey(); + const std::wstring& rhs_string_key = rhs.GetStringKey(); + + return StringComparator<std::wstring>(collator_)(lhs_string_key, + rhs_string_key); + } + + private: + Collator* collator_; +}; + +// Specialization of operator() method for std::wstring version. +template <> +bool StringComparator<std::wstring>::operator()(const std::wstring& lhs, + const std::wstring& rhs); + +// In place sorting of |elements| of a vector according to the string key of +// each element in the vector by using collation rules for |locale|. +// |begin_index| points to the start position of elements in the vector which +// want to be sorted. |end_index| points to the end position of elements in the +// vector which want to be sorted +template <class Element> +void SortVectorWithStringKey(const std::wstring& locale, + std::vector<Element>* elements, + unsigned int begin_index, + unsigned int end_index, + bool needs_stable_sort) { + DCHECK(begin_index >= 0 && begin_index < end_index && + end_index <= static_cast<unsigned int>(elements->size())); + UErrorCode error = U_ZERO_ERROR; + Locale loc(WideToASCII(locale).c_str()); + scoped_ptr<Collator> collator(Collator::createInstance(loc, error)); + if (U_FAILURE(error)) + collator.reset(); + StringComparator<Element> c(collator.get()); + if (needs_stable_sort) { + stable_sort(elements->begin() + begin_index, + elements->begin() + end_index, + c); + } else { + sort(elements->begin() + begin_index, elements->begin() + end_index, c); + } +} + +template <class Element> +void SortVectorWithStringKey(const std::wstring& locale, + std::vector<Element>* elements, + bool needs_stable_sort) { + SortVectorWithStringKey<Element>(locale, elements, 0, elements->size(), + needs_stable_sort); +} + // In place sorting of strings using collation rules for |locale|. void SortStrings(const std::wstring& locale, std::vector<std::wstring>* strings); diff --git a/chrome/test/automated_ui_tests/automated_ui_tests.cc b/chrome/test/automated_ui_tests/automated_ui_tests.cc index 4cab4d5..d87d521 100644 --- a/chrome/test/automated_ui_tests/automated_ui_tests.cc +++ b/chrome/test/automated_ui_tests/automated_ui_tests.cc @@ -12,6 +12,7 @@ #include "base/string_util.h" #include "base/sys_info.h" #include "chrome/app/chrome_dll_resource.h" +#include "chrome/browser/browser_process.h" #include "chrome/browser/character_encoding.h" #include "chrome/browser/view_ids.h" #include "chrome/common/chrome_paths.h" @@ -420,21 +421,22 @@ bool AutomatedUITest::BackButton() { bool AutomatedUITest::ChangeEncoding() { // Get the encoding list that is used to populate the UI (encoding menu) - const std::vector<int>* encoding_ids = + std::wstring cur_locale = g_browser_process->GetApplicationLocale(); + const std::vector<CharacterEncoding::EncodingInfo>* encodings = CharacterEncoding::GetCurrentDisplayEncodings( - L"ISO-8859-1,windows-1252", L""); - DCHECK(encoding_ids); - DCHECK(!encoding_ids->empty()); - unsigned len = static_cast<unsigned>(encoding_ids->size()); + cur_locale, L"ISO-8859-1,windows-1252", L""); + DCHECK(encodings); + DCHECK(!encodings->empty()); + unsigned len = static_cast<unsigned>(encodings->size()); // The vector will contain mostly IDC values for encoding commands plus a few // menu separators (0 values). If we hit a separator we just retry. int index = base::RandInt(0, len); - while ((*encoding_ids)[index] == 0) { + while ((*encodings)[index].encoding_id == 0) { index = base::RandInt(0, len); } - return RunCommand((*encoding_ids)[index]); + return RunCommand((*encodings)[index].encoding_id); } bool AutomatedUITest::CloseActiveTab() { |