diff options
author | jnd@chromium.org <jnd@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-02-20 04:51:28 +0000 |
---|---|---|
committer | jnd@chromium.org <jnd@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-02-20 04:51:28 +0000 |
commit | f8fae18a398d4925bd59e80e81890c12195146cc (patch) | |
tree | 3e51f6555f284d7c532d8b8d70e00c483f63675d /chrome/common | |
parent | 0cf8d378a8e819083dd38b38d4e5d2e2375b2497 (diff) | |
download | chromium_src-f8fae18a398d4925bd59e80e81890c12195146cc.zip chromium_src-f8fae18a398d4925bd59e80e81890c12195146cc.tar.gz chromium_src-f8fae18a398d4925bd59e80e81890c12195146cc.tar.bz2 |
We will sort the encoding menu items according to current used UI language except the UTF-8 encoding and the recently selectd encodings.
For details, see Fix bug http://code.google.com/p/chromium/issues/detail?id=7647
BUG=7647
Review URL: http://codereview.chromium.org/21414
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@10077 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/common')
-rw-r--r-- | chrome/common/l10n_util.cc | 97 | ||||
-rw-r--r-- | chrome/common/l10n_util.h | 73 |
2 files changed, 114 insertions, 56 deletions
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); |