summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/character_encoding.cc104
-rw-r--r--chrome/browser/character_encoding.h29
-rw-r--r--chrome/browser/encoding_menu_controller_delegate.cc26
-rw-r--r--chrome/browser/spellchecker.cc13
-rw-r--r--chrome/common/l10n_util.cc97
-rw-r--r--chrome/common/l10n_util.h73
-rw-r--r--chrome/test/automated_ui_tests/automated_ui_tests.cc16
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 &current_display_encoding_ids_;
+ std::vector<CharacterEncoding::EncodingInfo>* const current_display_encodings() {
+ return &current_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() {