diff options
author | ben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-01-21 23:30:17 +0000 |
---|---|---|
committer | ben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-01-21 23:30:17 +0000 |
commit | c051a1b531d77e7d2eb3afd1dec67e13aab39154 (patch) | |
tree | a6dcc2760d1cdc216a329298052723cb0e25e242 /app | |
parent | 28df88370f358468bffa1e1f6bc43aa25c11e388 (diff) | |
download | chromium_src-c051a1b531d77e7d2eb3afd1dec67e13aab39154.zip chromium_src-c051a1b531d77e7d2eb3afd1dec67e13aab39154.tar.gz chromium_src-c051a1b531d77e7d2eb3afd1dec67e13aab39154.tar.bz2 |
Move l10n_util to ui/base
BUG=none
TEST=none
TBR=brettw
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@72227 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'app')
-rw-r--r-- | app/app.gyp | 4 | ||||
-rw-r--r-- | app/app_base.gypi | 16 | ||||
-rw-r--r-- | app/l10n_util.cc | 876 | ||||
-rw-r--r-- | app/l10n_util.h | 161 | ||||
-rw-r--r-- | app/l10n_util_collator.h | 154 | ||||
-rw-r--r-- | app/l10n_util_mac.h | 82 | ||||
-rw-r--r-- | app/l10n_util_mac.mm | 167 | ||||
-rw-r--r-- | app/l10n_util_mac_unittest.mm | 46 | ||||
-rw-r--r-- | app/l10n_util_posix.cc | 14 | ||||
-rw-r--r-- | app/l10n_util_unittest.cc | 397 | ||||
-rw-r--r-- | app/l10n_util_win.cc | 185 | ||||
-rw-r--r-- | app/l10n_util_win.h | 63 | ||||
-rw-r--r-- | app/win/win_util.cc | 4 |
13 files changed, 12 insertions, 2157 deletions
diff --git a/app/app.gyp b/app/app.gyp index a7f4da8..6aea564 100644 --- a/app/app.gyp +++ b/app/app.gyp @@ -45,6 +45,8 @@ '../ui/base/animation/slide_animation_unittest.cc', '../ui/base/clipboard/clipboard_unittest.cc', '../ui/base/dragdrop/os_exchange_data_win_unittest.cc', + '../ui/base/l10n/l10n_util_mac_unittest.mm', + '../ui/base/l10n/l10n_util_unittest.cc', '../ui/base/models/tree_node_iterator_unittest.cc', '../ui/base/models/tree_node_model_unittest.cc', '../ui/base/resource/data_pack_unittest.cc', @@ -52,8 +54,6 @@ '../ui/base/test/data/resource.h', '../ui/base/text/text_elider_unittest.cc', '../ui/base/view_prop_unittest.cc', - 'l10n_util_mac_unittest.mm', - 'l10n_util_unittest.cc', 'run_all_unittests.cc', 'sql/connection_unittest.cc', 'sql/statement_unittest.cc', diff --git a/app/app_base.gypi b/app/app_base.gypi index e435f9d..5e17b4b 100644 --- a/app/app_base.gypi +++ b/app/app_base.gypi @@ -151,6 +151,14 @@ '../ui/base/keycodes/keyboard_codes_posix.h', '../ui/base/l10n/l10n_font_util.h', '../ui/base/l10n/l10n_font_util.cc', + '../ui/base/l10n/l10n_util.cc', + '../ui/base/l10n/l10n_util.h', + '../ui/base/l10n/l10n_util_collator.h', + '../ui/base/l10n/l10n_util_mac.h', + '../ui/base/l10n/l10n_util_mac.mm', + '../ui/base/l10n/l10n_util_posix.cc', + '../ui/base/l10n/l10n_util_win.cc', + '../ui/base/l10n/l10n_util_win.h', '../ui/base/message_box_flags.h', '../ui/base/models/accelerator.h', '../ui/base/models/accelerator_gtk.h', @@ -206,14 +214,6 @@ 'gfx/gl/gl_implementation_win.cc', 'gfx/gl/gl_interface.h', 'gfx/gl/gl_interface.cc', - 'l10n_util.cc', - 'l10n_util.h', - 'l10n_util_collator.h', - 'l10n_util_mac.h', - 'l10n_util_mac.mm', - 'l10n_util_posix.cc', - 'l10n_util_win.cc', - 'l10n_util_win.h', 'mac/nsimage_cache.h', 'mac/nsimage_cache.mm', 'mac/scoped_nsdisable_screen_updates.h', diff --git a/app/l10n_util.cc b/app/l10n_util.cc deleted file mode 100644 index 64189e99..0000000 --- a/app/l10n_util.cc +++ /dev/null @@ -1,876 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "app/l10n_util.h" - -#if defined(TOOLKIT_USES_GTK) -#include <glib/gutils.h> -#endif - -#include <algorithm> -#include <cstdlib> -#include <iterator> - -#include "app/l10n_util_collator.h" -#include "base/command_line.h" -#include "base/file_util.h" -#include "base/i18n/file_util_icu.h" -#include "base/i18n/rtl.h" -#include "base/path_service.h" -#include "base/scoped_ptr.h" -#include "base/string16.h" -#include "base/string_number_conversions.h" -#include "base/string_split.h" -#include "base/sys_string_conversions.h" -#include "base/utf_string_conversions.h" -#include "build/build_config.h" -#include "gfx/canvas.h" -#include "ui/base/resource/resource_bundle.h" -#include "ui/base/ui_base_paths.h" -#include "unicode/rbbi.h" -#include "unicode/uloc.h" - -#if defined(OS_MACOSX) -#include "app/l10n_util_mac.h" -#elif defined(OS_WIN) -#include "app/l10n_util_win.h" -#endif - -namespace { - -#if defined(OS_WIN) -static const FilePath::CharType kLocaleFileExtension[] = L".dll"; -#elif defined(OS_POSIX) -static const FilePath::CharType kLocaleFileExtension[] = ".pak"; -#endif - -static const char* const kAcceptLanguageList[] = { - "af", // Afrikaans - "am", // Amharic - "ar", // Arabic - "az", // Azerbaijani - "be", // Belarusian - "bg", // Bulgarian - "bh", // Bihari - "bn", // Bengali - "br", // Breton - "bs", // Bosnian - "ca", // Catalan - "co", // Corsican - "cs", // Czech - "cy", // Welsh - "da", // Danish - "de", // German - "de-AT", // German (Austria) - "de-CH", // German (Switzerland) - "de-DE", // German (Germany) - "el", // Greek - "en", // English - "en-AU", // English (Austrailia) - "en-CA", // English (Canada) - "en-GB", // English (UK) - "en-NZ", // English (New Zealand) - "en-US", // English (US) - "en-ZA", // English (South Africa) - "eo", // Esperanto - // TODO(jungshik) : Do we want to list all es-Foo for Latin-American - // Spanish speaking countries? - "es", // Spanish - "et", // Estonian - "eu", // Basque - "fa", // Persian - "fi", // Finnish - "fil", // Filipino - "fo", // Faroese - "fr", // French - "fr-CA", // French (Canada) - "fr-CH", // French (Switzerland) - "fr-FR", // French (France) - "fy", // Frisian - "ga", // Irish - "gd", // Scots Gaelic - "gl", // Galician - "gn", // Guarani - "gu", // Gujarati - "ha", // Hausa - "haw", // Hawaiian - "he", // Hebrew - "hi", // Hindi - "hr", // Croatian - "hu", // Hungarian - "hy", // Armenian - "ia", // Interlingua - "id", // Indonesian - "is", // Icelandic - "it", // Italian - "it-CH", // Italian (Switzerland) - "it-IT", // Italian (Italy) - "ja", // Japanese - "jw", // Javanese - "ka", // Georgian - "kk", // Kazakh - "km", // Cambodian - "kn", // Kannada - "ko", // Korean - "ku", // Kurdish - "ky", // Kyrgyz - "la", // Latin - "ln", // Lingala - "lo", // Laothian - "lt", // Lithuanian - "lv", // Latvian - "mk", // Macedonian - "ml", // Malayalam - "mn", // Mongolian - "mo", // Moldavian - "mr", // Marathi - "ms", // Malay - "mt", // Maltese - "nb", // Norwegian (Bokmal) - "ne", // Nepali - "nl", // Dutch - "nn", // Norwegian (Nynorsk) - "no", // Norwegian - "oc", // Occitan - "om", // Oromo - "or", // Oriya - "pa", // Punjabi - "pl", // Polish - "ps", // Pashto - "pt", // Portuguese - "pt-BR", // Portuguese (Brazil) - "pt-PT", // Portuguese (Portugal) - "qu", // Quechua - "rm", // Romansh - "ro", // Romanian - "ru", // Russian - "sd", // Sindhi - "sh", // Serbo-Croatian - "si", // Sinhalese - "sk", // Slovak - "sl", // Slovenian - "sn", // Shona - "so", // Somali - "sq", // Albanian - "sr", // Serbian - "st", // Sesotho - "su", // Sundanese - "sv", // Swedish - "sw", // Swahili - "ta", // Tamil - "te", // Telugu - "tg", // Tajik - "th", // Thai - "ti", // Tigrinya - "tk", // Turkmen - "to", // Tonga - "tr", // Turkish - "tt", // Tatar - "tw", // Twi - "ug", // Uighur - "uk", // Ukrainian - "ur", // Urdu - "uz", // Uzbek - "vi", // Vietnamese - "xh", // Xhosa - "yi", // Yiddish - "yo", // Yoruba - "zh", // Chinese - "zh-CN", // Chinese (Simplified) - "zh-TW", // Chinese (Traditional) - "zu", // Zulu -}; - -// 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[] = { - "en", - "pt", - "zh", - "zh_hans_cn", - "zh_hant_tw" - }; - - // Skip all 'es_RR'. Currently, we use 'es' for es-ES (Spanish in Spain). - // 'es-419' (Spanish in Latin America) is not available in ICU so that it - // has to be added manually in GetAvailableLocales(). - if (LowerCaseEqualsASCII(locale_name.substr(0, 3), "es_")) - return true; - for (size_t i = 0; i < arraysize(kDuplicateNames); ++i) { - if (base::strcasecmp(kDuplicateNames[i], locale_name.c_str()) == 0) - return true; - } - return false; -} - -bool IsLocaleNameTranslated(const char* locale, - const std::string& display_locale) { - string16 display_name = - l10n_util::GetDisplayNameForLocale(locale, display_locale, false); - // Because ICU sets the error code to U_USING_DEFAULT_WARNING whether or not - // uloc_getDisplayName returns the actual translation or the default - // value (locale code), we have to rely on this hack to tell whether - // the translation is available or not. If ICU doesn't have a translated - // name for this locale, GetDisplayNameForLocale will just return the - // locale code. - return !IsStringASCII(display_name) || UTF16ToASCII(display_name) != locale; -} - -// We added 30+ minimally populated locales with only a few entries -// (exemplar character set, script, writing direction and its own -// lanaguage name). These locales have to be distinguished from the -// fully populated locales to which Chrome is localized. -bool IsLocalePartiallyPopulated(const std::string& locale_name) { - // For partially populated locales, even the translation for "English" - // is not available. A more robust/elegant way to check is to add a special - // field (say, 'isPartial' to our version of ICU locale files) and - // check its value, but this hack seems to work well. - return !IsLocaleNameTranslated("en", locale_name); -} - -#if !defined(OS_MACOSX) -bool IsLocaleAvailable(const std::string& locale, - const FilePath& locale_path) { - // If locale has any illegal characters in it, we don't want to try to - // load it because it may be pointing outside the locale data file directory. - if (!file_util::IsFilenameLegal(ASCIIToUTF16(locale))) - return false; - - // IsLocalePartiallyPopulated() can be called here for an early return w/o - // checking the resource availability below. It'd help when Chrome is run - // under a system locale Chrome is not localized to (e.g.Farsi on Linux), - // but it'd slow down the start up time a little bit for locales Chrome is - // localized to. So, we don't call it here. - if (!l10n_util::IsLocaleSupportedByOS(locale)) - return false; - - FilePath test_path = locale_path; - test_path = - test_path.AppendASCII(locale).ReplaceExtension(kLocaleFileExtension); - return file_util::PathExists(test_path); -} - -bool CheckAndResolveLocale(const std::string& locale, - const FilePath& locale_path, - std::string* resolved_locale) { - if (IsLocaleAvailable(locale, locale_path)) { - *resolved_locale = locale; - return true; - } - // If the locale matches language but not country, use that instead. - // TODO(jungshik) : Nothing is done about languages that Chrome - // does not support but available on Windows. We fall - // back to en-US in GetApplicationLocale so that it's a not critical, - // but we can do better. - std::string::size_type hyphen_pos = locale.find('-'); - if (hyphen_pos != std::string::npos && hyphen_pos > 0) { - std::string lang(locale, 0, hyphen_pos); - std::string region(locale, hyphen_pos + 1); - std::string tmp_locale(lang); - // Map es-RR other than es-ES to es-419 (Chrome's Latin American - // Spanish locale). - if (LowerCaseEqualsASCII(lang, "es") && !LowerCaseEqualsASCII(region, "es")) - tmp_locale.append("-419"); - else if (LowerCaseEqualsASCII(lang, "zh")) { - // Map zh-HK and zh-MK to zh-TW. Otherwise, zh-FOO is mapped to zh-CN. - if (LowerCaseEqualsASCII(region, "hk") || - LowerCaseEqualsASCII(region, "mk")) { - tmp_locale.append("-TW"); - } else { - tmp_locale.append("-CN"); - } - } - if (IsLocaleAvailable(tmp_locale, locale_path)) { - resolved_locale->swap(tmp_locale); - return true; - } - } - - // Google updater uses no, iw and en for our nb, he, and en-US. - // We need to map them to our codes. - struct { - const char* source; - const char* dest; - } alias_map[] = { - {"no", "nb"}, - {"tl", "fil"}, - {"iw", "he"}, - {"en", "en-US"}, - }; - - for (size_t i = 0; i < ARRAYSIZE_UNSAFE(alias_map); ++i) { - if (LowerCaseEqualsASCII(locale, alias_map[i].source)) { - std::string tmp_locale(alias_map[i].dest); - if (IsLocaleAvailable(tmp_locale, locale_path)) { - resolved_locale->swap(tmp_locale); - return true; - } - } - } - - return false; -} -#endif - -// On Linux, the text layout engine Pango determines paragraph directionality -// by looking at the first strongly-directional character in the text. This -// means text such as "Google Chrome foo bar..." will be layed out LTR even -// if "foo bar" is RTL. So this function prepends the necessary RLM in such -// cases. -void AdjustParagraphDirectionality(string16* paragraph) { -#if defined(OS_LINUX) - if (base::i18n::IsRTL() && - base::i18n::StringContainsStrongRTLChars(*paragraph)) { - paragraph->insert(0, 1, static_cast<char16>(base::i18n::kRightToLeftMark)); - } -#endif -} - -#if defined(OS_WIN) -std::string GetCanonicalLocale(const std::string& locale) { - return base::i18n::GetCanonicalLocale(locale.c_str()); -} -#endif - -} // namespace - -namespace l10n_util { - -std::string GetApplicationLocale(const std::string& pref_locale) { -#if defined(OS_MACOSX) - - // Use any override (Cocoa for the browser), otherwise use the preference - // passed to the function. - std::string app_locale = l10n_util::GetLocaleOverride(); - if (app_locale.empty()) - app_locale = pref_locale; - - // The above should handle all of the cases Chrome normally hits, but for some - // unit tests, we need something to fall back too. - if (app_locale.empty()) - app_locale = "en-US"; - - // Windows/Linux call SetICUDefaultLocale after determining the actual locale - // with CheckAndResolveLocal to make ICU APIs work in that locale. - // Mac doesn't use a locale directory tree of resources (it uses Mac style - // resources), so mirror the Windows/Linux behavior of calling - // SetICUDefaultLocale. - base::i18n::SetICUDefaultLocale(app_locale); - return app_locale; - -#else - - FilePath locale_path; - PathService::Get(ui::DIR_LOCALES, &locale_path); - std::string resolved_locale; - std::vector<std::string> candidates; - - // We only use --lang and the app pref on Windows. On Linux, we only - // look at the LC_*/LANG environment variables. We do, however, pass --lang - // to renderer and plugin processes so they know what language the parent - // process decided to use. - -#if defined(OS_WIN) - - // First, try the preference value. - if (!pref_locale.empty()) - candidates.push_back(pref_locale); - - // Next, try the overridden locale. - const std::vector<std::string>& languages = l10n_util::GetLocaleOverrides(); - if (!languages.empty()) { - candidates.reserve(candidates.size() + languages.size()); - std::transform(languages.begin(), languages.end(), - std::back_inserter(candidates), &GetCanonicalLocale); - } else { - // If no override was set, defer to ICU - candidates.push_back(base::i18n::GetConfiguredLocale()); - } - -#elif defined(OS_CHROMEOS) - - // On ChromeOS, use the application locale preference. - if (!pref_locale.empty()) - candidates.push_back(pref_locale); - -#elif defined(OS_POSIX) && defined(TOOLKIT_USES_GTK) - - // GLib implements correct environment variable parsing with - // the precedence order: LANGUAGE, LC_ALL, LC_MESSAGES and LANG. - // We used to use our custom parsing code along with ICU for this purpose. - // If we have a port that does not depend on GTK, we have to - // restore our custom code for that port. - const char* const* languages = g_get_language_names(); - DCHECK(languages); // A valid pointer is guaranteed. - DCHECK(*languages); // At least one entry, "C", is guaranteed. - - for (; *languages != NULL; ++languages) { - candidates.push_back(base::i18n::GetCanonicalLocale(*languages)); - } - -#else -#error Unsupported platform, see build/build_config.h -#endif - - std::vector<std::string>::const_iterator i = candidates.begin(); - for (; i != candidates.end(); ++i) { - if (CheckAndResolveLocale(*i, locale_path, &resolved_locale)) { - base::i18n::SetICUDefaultLocale(resolved_locale); - return resolved_locale; - } - } - - // Fallback on en-US. - const std::string fallback_locale("en-US"); - if (IsLocaleAvailable(fallback_locale, locale_path)) { - base::i18n::SetICUDefaultLocale(fallback_locale); - return fallback_locale; - } - - // No locale data file was found; we shouldn't get here. - NOTREACHED(); - - return std::string(); - -#endif -} - -string16 GetDisplayNameForLocale(const std::string& locale, - const std::string& display_locale, - bool is_for_ui) { - std::string locale_code = locale; - // Internally, we use the language code of zh-CN and zh-TW, but we want the - // display names to be Chinese (Simplified) and Chinese (Traditional) instead - // of Chinese (China) and Chinese (Taiwan). To do that, we pass zh-Hans - // and zh-Hant to ICU. Even with this mapping, we'd get - // 'Chinese (Simplified Han)' and 'Chinese (Traditional Han)' in English and - // even longer results in other languages. Arguably, they're better than - // the current results : Chinese (China) / Chinese (Taiwan). - // TODO(jungshik): Do one of the following: - // 1. Special-case Chinese by getting the custom-translation for them - // 2. Recycle IDS_ENCODING_{SIMP,TRAD}_CHINESE. - // 3. Get translations for two directly from the ICU resouce bundle - // because they're not accessible with other any API. - // 4. Patch ICU to special-case zh-Hans/zh-Hant for us. - // #1 and #2 wouldn't work if display_locale != current UI locale although - // we can think of additional hack to work around the problem. - // #3 can be potentially expensive. - if (locale_code == "zh-CN") - locale_code = "zh-Hans"; - else if (locale_code == "zh-TW") - locale_code = "zh-Hant"; - - UErrorCode error = U_ZERO_ERROR; - const int buffer_size = 1024; - - string16 display_name; - int actual_size = uloc_getDisplayName(locale_code.c_str(), - display_locale.c_str(), - WriteInto(&display_name, buffer_size + 1), buffer_size, &error); - DCHECK(U_SUCCESS(error)); - display_name.resize(actual_size); - // Add an RTL mark so parentheses are properly placed. - if (is_for_ui && base::i18n::IsRTL()) - display_name.push_back(static_cast<char16>(base::i18n::kRightToLeftMark)); - return display_name; -} - -std::string NormalizeLocale(const std::string& locale) { - std::string normalized_locale(locale); - std::replace(normalized_locale.begin(), normalized_locale.end(), '-', '_'); - - return normalized_locale; -} - -void GetParentLocales(const std::string& current_locale, - std::vector<std::string>* parent_locales) { - std::string locale(NormalizeLocale(current_locale)); - - const int kNameCapacity = 256; - char parent[kNameCapacity]; - base::strlcpy(parent, locale.c_str(), kNameCapacity); - parent_locales->push_back(parent); - UErrorCode err = U_ZERO_ERROR; - while (uloc_getParent(parent, parent, kNameCapacity, &err) > 0) { - if (U_FAILURE(err)) - break; - parent_locales->push_back(parent); - } -} - -bool IsValidLocaleSyntax(const std::string& locale) { - // Check that the length is plausible. - if (locale.size() < 2 || locale.size() >= ULOC_FULLNAME_CAPACITY) - return false; - - // Strip off the part after an '@' sign, which might contain keywords, - // as in en_IE@currency=IEP or fr@collation=phonebook;calendar=islamic-civil. - // We don't validate that part much, just check that there's at least one - // equals sign in a plausible place. Normalize the prefix so that hyphens - // are changed to underscores. - std::string prefix = NormalizeLocale(locale); - size_t split_point = locale.find("@"); - if (split_point != std::string::npos) { - std::string keywords = locale.substr(split_point + 1); - prefix = locale.substr(0, split_point); - - size_t equals_loc = keywords.find("="); - if (equals_loc == std::string::npos || - equals_loc < 1 || equals_loc > keywords.size() - 2) - return false; - } - - // Check that all characters before the at-sign are alphanumeric or - // underscore. - for (size_t i = 0; i < prefix.size(); i++) { - char ch = prefix[i]; - if (!IsAsciiAlpha(ch) && !IsAsciiDigit(ch) && ch != '_') - return false; - } - - // Check that the initial token (before the first hyphen/underscore) - // is 1 - 3 alphabetical characters (a language tag). - for (size_t i = 0; i < prefix.size(); i++) { - char ch = prefix[i]; - if (ch == '_') { - if (i < 1 || i > 3) - return false; - break; - } - if (!IsAsciiAlpha(ch)) - return false; - } - - // Check that the all tokens after the initial token are 1 - 8 characters. - // (Tokenize/StringTokenizer don't work here, they collapse multiple - // delimiters into one.) - int token_len = 0; - int token_index = 0; - for (size_t i = 0; i < prefix.size(); i++) { - if (prefix[i] != '_') { - token_len++; - continue; - } - - if (token_index > 0 && (token_len < 1 || token_len > 8)) { - return false; - } - token_index++; - token_len = 0; - } - if (token_index == 0 && (token_len < 1 || token_len > 3)) { - return false; - } else if (token_len < 1 || token_len > 8) { - return false; - } - - return true; -} - -std::string GetStringUTF8(int message_id) { - return UTF16ToUTF8(GetStringUTF16(message_id)); -} - -string16 GetStringUTF16(int message_id) { - ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - string16 str = rb.GetLocalizedString(message_id); - AdjustParagraphDirectionality(&str); - - return str; -} - -static string16 GetStringF(int message_id, - const std::vector<string16>& replacements, - std::vector<size_t>* offsets) { - // TODO(tc): We could save a string copy if we got the raw string as - // a StringPiece and were able to call ReplaceStringPlaceholders with - // a StringPiece format string and string16 substitution strings. In - // practice, the strings should be relatively short. - ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - const string16& format_string = rb.GetLocalizedString(message_id); - -#ifndef NDEBUG - // Make sure every replacement string is being used, so we don't just - // silently fail to insert one. If |offsets| is non-NULL, then don't do this - // check as the code may simply want to find the placeholders rather than - // actually replacing them. - if (!offsets) { - std::string utf8_string = UTF16ToUTF8(format_string); - - // $9 is the highest allowed placeholder. - for (size_t i = 0; i < 9; ++i) { - bool placeholder_should_exist = replacements.size() > i; - - std::string placeholder = StringPrintf("$%d", static_cast<int>(i + 1)); - size_t pos = utf8_string.find(placeholder.c_str()); - if (placeholder_should_exist) { - DCHECK_NE(std::string::npos, pos) << - " Didn't find a " << placeholder << " placeholder in " << - utf8_string; - } else { - DCHECK_EQ(std::string::npos, pos) << - " Unexpectedly found a " << placeholder << " placeholder in " << - utf8_string; - } - } - } -#endif - - string16 formatted = ReplaceStringPlaceholders(format_string, replacements, - offsets); - AdjustParagraphDirectionality(&formatted); - - return formatted; -} - -std::string GetStringFUTF8(int message_id, - const string16& a) { - return UTF16ToUTF8(GetStringFUTF16(message_id, a)); -} - -std::string GetStringFUTF8(int message_id, - const string16& a, - const string16& b) { - return UTF16ToUTF8(GetStringFUTF16(message_id, a, b)); -} - -std::string GetStringFUTF8(int message_id, - const string16& a, - const string16& b, - const string16& c) { - return UTF16ToUTF8(GetStringFUTF16(message_id, a, b, c)); -} - -std::string GetStringFUTF8(int message_id, - const string16& a, - const string16& b, - const string16& c, - const string16& d) { - return UTF16ToUTF8(GetStringFUTF16(message_id, a, b, c, d)); -} - -string16 GetStringFUTF16(int message_id, - const string16& a) { - std::vector<string16> replacements; - replacements.push_back(a); - return GetStringF(message_id, replacements, NULL); -} - -string16 GetStringFUTF16(int message_id, - const string16& a, - const string16& b) { - return GetStringFUTF16(message_id, a, b, NULL); -} - -string16 GetStringFUTF16(int message_id, - const string16& a, - const string16& b, - const string16& c) { - std::vector<string16> replacements; - replacements.push_back(a); - replacements.push_back(b); - replacements.push_back(c); - return GetStringF(message_id, replacements, NULL); -} - -string16 GetStringFUTF16(int message_id, - const string16& a, - const string16& b, - const string16& c, - const string16& d) { - std::vector<string16> replacements; - replacements.push_back(a); - replacements.push_back(b); - replacements.push_back(c); - replacements.push_back(d); - return GetStringF(message_id, replacements, NULL); -} - -string16 GetStringFUTF16(int message_id, const string16& a, size_t* offset) { - DCHECK(offset); - std::vector<size_t> offsets; - std::vector<string16> replacements; - replacements.push_back(a); - string16 result = GetStringF(message_id, replacements, &offsets); - DCHECK(offsets.size() == 1); - *offset = offsets[0]; - return result; -} - -string16 GetStringFUTF16(int message_id, - const string16& a, - const string16& b, - std::vector<size_t>* offsets) { - std::vector<string16> replacements; - replacements.push_back(a); - replacements.push_back(b); - return GetStringF(message_id, replacements, offsets); -} - -string16 GetStringFUTF16Int(int message_id, int a) { - return GetStringFUTF16(message_id, UTF8ToUTF16(base::IntToString(a))); -} - -string16 GetStringFUTF16Int(int message_id, int64 a) { - return GetStringFUTF16(message_id, UTF8ToUTF16(base::Int64ToString(a))); -} - -string16 TruncateString(const string16& string, size_t length) { - if (string.size() <= length) - // String fits, return it. - return string; - - if (length == 0) { - // No room for the elide string, return an empty string. - return string16(); - } - size_t max = length - 1; - - // Added to the end of strings that are too big. - static const char16 kElideString[] = { 0x2026, 0 }; - - if (max == 0) { - // Just enough room for the elide string. - return kElideString; - } - - // Use a line iterator to find the first boundary. - UErrorCode status = U_ZERO_ERROR; - scoped_ptr<icu::RuleBasedBreakIterator> bi( - static_cast<icu::RuleBasedBreakIterator*>( - icu::RuleBasedBreakIterator::createLineInstance( - icu::Locale::getDefault(), status))); - if (U_FAILURE(status)) - return string.substr(0, max) + kElideString; - bi->setText(string.c_str()); - int32_t index = bi->preceding(static_cast<int32_t>(max)); - if (index == icu::BreakIterator::DONE) { - index = static_cast<int32_t>(max); - } else { - // Found a valid break (may be the beginning of the string). Now use - // a character iterator to find the previous non-whitespace character. - icu::StringCharacterIterator char_iterator(string.c_str()); - if (index == 0) { - // No valid line breaks. Start at the end again. This ensures we break - // on a valid character boundary. - index = static_cast<int32_t>(max); - } - char_iterator.setIndex(index); - while (char_iterator.hasPrevious()) { - char_iterator.previous(); - if (!(u_isspace(char_iterator.current()) || - u_charType(char_iterator.current()) == U_CONTROL_CHAR || - u_charType(char_iterator.current()) == U_NON_SPACING_MARK)) { - // Not a whitespace character. Advance the iterator so that we - // include the current character in the truncated string. - char_iterator.next(); - break; - } - } - if (char_iterator.hasPrevious()) { - // Found a valid break point. - index = char_iterator.getIndex(); - } else { - // String has leading whitespace, return the elide string. - return kElideString; - } - } - return string.substr(0, index) + kElideString; -} - -string16 ToLower(const string16& string) { - icu::UnicodeString lower_u_str( - icu::UnicodeString(string.c_str()).toLower(icu::Locale::getDefault())); - string16 result; - lower_u_str.extract(0, lower_u_str.length(), - WriteInto(&result, lower_u_str.length() + 1)); - return result; -} - -string16 ToUpper(const string16& string) { - icu::UnicodeString upper_u_str( - icu::UnicodeString(string.c_str()).toUpper(icu::Locale::getDefault())); - string16 result; - upper_u_str.extract(0, upper_u_str.length(), - WriteInto(&result, upper_u_str.length() + 1)); - return result; -} - -// Compares the character data stored in two different string16 strings by -// specified Collator instance. -UCollationResult CompareString16WithCollator(const icu::Collator* collator, - const string16& lhs, - const string16& rhs) { - DCHECK(collator); - UErrorCode error = U_ZERO_ERROR; - 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); - DCHECK(U_SUCCESS(error)); - return result; -} - -// Specialization of operator() method for string16 version. -template <> -bool StringComparator<string16>::operator()(const string16& lhs, - const string16& rhs) { - // If we can not get collator instance for specified locale, just do simple - // string compare. - if (!collator_) - return lhs < rhs; - return CompareString16WithCollator(collator_, lhs, rhs) == UCOL_LESS; -}; - -void SortStrings16(const std::string& locale, - std::vector<string16>* strings) { - SortVectorWithStringKey(locale, strings, false); -} - -const std::vector<std::string>& GetAvailableLocales() { - static std::vector<std::string> locales; - if (locales.empty()) { - int num_locales = uloc_countAvailable(); - for (int i = 0; i < num_locales; ++i) { - std::string locale_name = uloc_getAvailable(i); - // Filter out the names that have aliases. - if (IsDuplicateName(locale_name)) - continue; - // Filter out locales for which we have only partially populated data - // and to which Chrome is not localized. - if (IsLocalePartiallyPopulated(locale_name)) - continue; - if (!IsLocaleSupportedByOS(locale_name)) - continue; - // Normalize underscores to hyphens because that's what our locale files - // use. - std::replace(locale_name.begin(), locale_name.end(), '_', '-'); - - // Map the Chinese locale names over to zh-CN and zh-TW. - if (LowerCaseEqualsASCII(locale_name, "zh-hans")) { - locale_name = "zh-CN"; - } else if (LowerCaseEqualsASCII(locale_name, "zh-hant")) { - locale_name = "zh-TW"; - } - locales.push_back(locale_name); - } - - // Manually add 'es-419' to the list. See the comment in IsDuplicateName(). - locales.push_back("es-419"); - } - return locales; -} - -void GetAcceptLanguagesForLocale(const std::string& display_locale, - std::vector<std::string>* locale_codes) { - for (size_t i = 0; i < arraysize(kAcceptLanguageList); ++i) { - if (!IsLocaleNameTranslated(kAcceptLanguageList[i], display_locale)) - // TODO(jungshik) : Put them at the of the list with language codes - // enclosed by brackets instead of skipping. - continue; - locale_codes->push_back(kAcceptLanguageList[i]); - } -} - -} // namespace l10n_util diff --git a/app/l10n_util.h b/app/l10n_util.h deleted file mode 100644 index b76f5d9..0000000 --- a/app/l10n_util.h +++ /dev/null @@ -1,161 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// This file contains utility functions for dealing with localized -// content. - -#ifndef APP_L10N_UTIL_H_ -#define APP_L10N_UTIL_H_ -#pragma once - -#include <algorithm> -#include <functional> -#include <string> -#include <vector> - -#include "build/build_config.h" - -#include "base/basictypes.h" -#include "base/scoped_ptr.h" -#include "base/string16.h" -#include "base/string_util.h" - -#if defined(OS_MACOSX) -#include "app/l10n_util_mac.h" -#endif // OS_MACOSX - -namespace l10n_util { - -// This method is responsible for determining the locale as defined below. In -// nearly all cases you shouldn't call this, rather use GetApplicationLocale -// defined on browser_process. -// -// Returns the locale used by the Application. First we use the value from the -// command line (--lang), second we try the value in the prefs file (passed in -// as |pref_locale|), finally, we fall back on the system locale. We only return -// a value if there's a corresponding resource DLL for the locale. Otherwise, -// we fall back to en-us. -std::string GetApplicationLocale(const std::string& pref_locale); - -// Given a locale code, return true if the OS is capable of supporting it. -// For instance, Oriya is not well supported on Windows XP and we return -// false for "or". -bool IsLocaleSupportedByOS(const std::string& locale); - -// This method returns the display name of the locale code in |display_locale|. - -// For example, for |locale| = "fr" and |display_locale| = "en", -// it returns "French". To get the display name of -// |locale| in the UI language of Chrome, |display_locale| can be -// set to the return value of g_browser_process->GetApplicationLocale() -// in the UI thread. -// If |is_for_ui| is true, U+200F is appended so that it can be -// rendered properly in a RTL Chrome. -string16 GetDisplayNameForLocale(const std::string& locale, - const std::string& display_locale, - bool is_for_ui); - -// Converts all - into _, to be consistent with ICU and file system names. -std::string NormalizeLocale(const std::string& locale); - -// Produce a vector of parent locales for given locale. -// It includes the current locale in the result. -// sr_Cyrl_RS generates sr_Cyrl_RS, sr_Cyrl and sr. -void GetParentLocales(const std::string& current_locale, - std::vector<std::string>* parent_locales); - -// Checks if a string is plausibly a syntactically-valid locale string, -// for cases where we want the valid input to be a locale string such as -// 'en', 'pt-BR', 'fil', 'es-419', 'zh-Hans-CN', 'i-klingon' or -// 'de_DE@collation=phonebook', but we don't want to limit it to -// locales that Chrome actually knows about, so 'xx-YY' should be -// accepted, but 'z', 'German', 'en-$1', or 'abcd-1234' should not. -// Case-insensitive. Based on BCP 47, see: -// http://unicode.org/reports/tr35/#Unicode_Language_and_Locale_Identifiers -bool IsValidLocaleSyntax(const std::string& locale); - -// -// Mac Note: See l10n_util_mac.h for some NSString versions and other support. -// - -// Pulls resource string from the string bundle and returns it. -std::string GetStringUTF8(int message_id); -string16 GetStringUTF16(int message_id); - -// Get a resource string and replace $1-$2-$3 with |a| and |b| -// respectively. Additionally, $$ is replaced by $. -string16 GetStringFUTF16(int message_id, - const string16& a); -string16 GetStringFUTF16(int message_id, - const string16& a, - const string16& b); -string16 GetStringFUTF16(int message_id, - const string16& a, - const string16& b, - const string16& c); -string16 GetStringFUTF16(int message_id, - const string16& a, - const string16& b, - const string16& c, - const string16& d); -std::string GetStringFUTF8(int message_id, - const string16& a); -std::string GetStringFUTF8(int message_id, - const string16& a, - const string16& b); -std::string GetStringFUTF8(int message_id, - const string16& a, - const string16& b, - const string16& c); -std::string GetStringFUTF8(int message_id, - const string16& a, - const string16& b, - const string16& c, - const string16& d); - -// Variants that return the offset(s) of the replaced parameters. The -// vector based version returns offsets ordered by parameter. For example if -// invoked with a and b offsets[0] gives the offset for a and offsets[1] the -// offset of b regardless of where the parameters end up in the string. -string16 GetStringFUTF16(int message_id, - const string16& a, - size_t* offset); -string16 GetStringFUTF16(int message_id, - const string16& a, - const string16& b, - std::vector<size_t>* offsets); - -// Convenience functions to get a string with a single number as a parameter. -string16 GetStringFUTF16Int(int message_id, int a); -string16 GetStringFUTF16Int(int message_id, int64 a); - -// Truncates the string to length characters. This breaks the string at -// the first word break before length, adding the horizontal ellipsis -// character (unicode character 0x2026) to render ... -// The supplied string is returned if the string has length characters or -// less. -string16 TruncateString(const string16& string, size_t length); - -// Returns the lower case equivalent of string. -string16 ToLower(const string16& string); - -// Returns the upper case equivalent of string. -string16 ToUpper(const string16& string); - -// In place sorting of string16 strings using collation rules for |locale|. -void SortStrings16(const std::string& locale, - std::vector<string16>* strings); - -// Returns a vector of available locale codes. E.g., a vector containing -// en-US, es, fr, fi, pt-PT, pt-BR, etc. -const std::vector<std::string>& GetAvailableLocales(); - -// Returns a vector of locale codes usable for accept-languages. -void GetAcceptLanguagesForLocale(const std::string& display_locale, - std::vector<std::string>* locale_codes); - - -} // namespace l10n_util - -#endif // APP_L10N_UTIL_H_ diff --git a/app/l10n_util_collator.h b/app/l10n_util_collator.h deleted file mode 100644 index bcbfd82..0000000 --- a/app/l10n_util_collator.h +++ /dev/null @@ -1,154 +0,0 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef APP_L10N_UTIL_COLLATOR_H_ -#define APP_L10N_UTIL_COLLATOR_H_ -#pragma once - -#include <algorithm> -#include <functional> -#include <string> -#include <vector> - -#include "base/utf_string_conversions.h" -#include "unicode/coll.h" - -namespace l10n_util { - -// Compares the two strings using the specified collator. -UCollationResult CompareString16WithCollator(const icu::Collator* collator, - const string16& lhs, - const string16& rhs); - -// Used by SortStringsUsingMethod. Invokes a method on the objects passed to -// operator (), comparing the string results using a collator. -template <class T, class Method> -class StringMethodComparatorWithCollator - : public std::binary_function<const string16&, - const string16&, - bool> { - public: - StringMethodComparatorWithCollator(icu::Collator* collator, Method method) - : collator_(collator), - method_(method) { } - - // Returns true if lhs preceeds rhs. - bool operator() (T* lhs_t, T* rhs_t) { - return CompareString16WithCollator(collator_, (lhs_t->*method_)(), - (rhs_t->*method_)()) == UCOL_LESS; - } - - private: - icu::Collator* collator_; - Method method_; -}; - -// Used by SortStringsUsingMethod. Invokes a method on the objects passed to -// operator (), comparing the string results using <. -template <class T, class Method> -class StringMethodComparator : public std::binary_function<const string16&, - const string16&, - bool> { - public: - explicit StringMethodComparator(Method method) : method_(method) { } - - // Returns true if lhs preceeds rhs. - bool operator() (T* lhs_t, T* rhs_t) { - return (lhs_t->*method_)() < (rhs_t->*method_)(); - } - - private: - Method method_; -}; - -// Sorts the objects in |elements| using the method |method|, which must return -// a string. Sorting is done using a collator, unless a collator can not be -// found in which case the strings are sorted using the operator <. -template <class T, class Method> -void SortStringsUsingMethod(const std::string& locale, - std::vector<T*>* elements, - Method method) { - UErrorCode error = U_ZERO_ERROR; - icu::Locale loc(locale.c_str()); - scoped_ptr<icu::Collator> collator(icu::Collator::createInstance(loc, error)); - if (U_FAILURE(error)) { - sort(elements->begin(), elements->end(), - StringMethodComparator<T, Method>(method)); - return; - } - - std::sort(elements->begin(), elements->end(), - StringMethodComparatorWithCollator<T, Method>(collator.get(), method)); -} - -// 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 string16& 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(icu::Collator* collator) - : collator_(collator) { } - - // Returns true if lhs precedes rhs. - bool operator()(const Element& lhs, const Element& rhs) { - const string16& lhs_string_key = lhs.GetStringKey(); - const string16& rhs_string_key = rhs.GetStringKey(); - - return StringComparator<string16>(collator_)(lhs_string_key, - rhs_string_key); - } - - private: - icu::Collator* collator_; -}; - -// Specialization of operator() method for string16 version. -template <> -bool StringComparator<string16>::operator()(const string16& lhs, - const string16& 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::string& locale, - std::vector<Element>* elements, - unsigned int begin_index, - unsigned int end_index, - bool needs_stable_sort) { - DCHECK(begin_index < end_index && - end_index <= static_cast<unsigned int>(elements->size())); - UErrorCode error = U_ZERO_ERROR; - icu::Locale loc(locale.c_str()); - scoped_ptr<icu::Collator> collator(icu::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::string& locale, - std::vector<Element>* elements, - bool needs_stable_sort) { - SortVectorWithStringKey<Element>(locale, elements, 0, elements->size(), - needs_stable_sort); -} - -} // namespace l10n_util - -#endif // APP_L10N_UTIL_COLLATOR_H_ diff --git a/app/l10n_util_mac.h b/app/l10n_util_mac.h deleted file mode 100644 index 309a7f0..0000000 --- a/app/l10n_util_mac.h +++ /dev/null @@ -1,82 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef APP_L10N_UTIL_MAC_H_ -#define APP_L10N_UTIL_MAC_H_ -#pragma once - -#include <string> -#include <vector> - -#include "base/basictypes.h" -#include "base/string16.h" - -#ifdef __OBJC__ -@class NSString; -#else -class NSString; -#endif - -namespace l10n_util { - -// Remove the Windows-style accelerator marker (for labels, menuitems, etc.) -// and change "..." into an ellipsis. -// Returns the result in an autoreleased NSString. -NSString* FixUpWindowsStyleLabel(const string16& label); - -// Pulls resource string from the string bundle and returns it. -NSString* GetNSString(int message_id); - -// Get a resource string and replace $1-$2-$3 with |a| and |b| -// respectively. Additionally, $$ is replaced by $. -NSString* GetNSStringF(int message_id, - const string16& a); -NSString* GetNSStringF(int message_id, - const string16& a, - const string16& b); -NSString* GetNSStringF(int message_id, - const string16& a, - const string16& b, - const string16& c); -NSString* GetNSStringF(int message_id, - const string16& a, - const string16& b, - const string16& c, - const string16& d); - -// Variants that return the offset(s) of the replaced parameters. (See -// app/l10n_util.h for more details.) -NSString* GetNSStringF(int message_id, - const string16& a, - const string16& b, - std::vector<size_t>* offsets); - -// Same as GetNSString, but runs the result through FixUpWindowsStyleLabel -// before returning it. -NSString* GetNSStringWithFixup(int message_id); - -// Same as GetNSStringF, but runs the result through FixUpWindowsStyleLabel -// before returning it. -NSString* GetNSStringFWithFixup(int message_id, - const string16& a); -NSString* GetNSStringFWithFixup(int message_id, - const string16& a, - const string16& b); -NSString* GetNSStringFWithFixup(int message_id, - const string16& a, - const string16& b, - const string16& c); -NSString* GetNSStringFWithFixup(int message_id, - const string16& a, - const string16& b, - const string16& c, - const string16& d); - -// Support the override of the locale with the value from Cocoa. -void OverrideLocaleWithCocoaLocale(); -const std::string& GetLocaleOverride(); - -} // namespace l10n_util - -#endif // APP_L10N_UTIL_MAC_H_ diff --git a/app/l10n_util_mac.mm b/app/l10n_util_mac.mm deleted file mode 100644 index c0be5d8..0000000 --- a/app/l10n_util_mac.mm +++ /dev/null @@ -1,167 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#import <Foundation/Foundation.h> - -#include "app/l10n_util.h" -#include "app/l10n_util_mac.h" -#include "base/sys_string_conversions.h" -#include "base/lazy_instance.h" -#include "base/logging.h" - -namespace { - -class OverrideLocaleHolder { - public: - OverrideLocaleHolder() {} - const std::string& value() const { return value_; } - void set_value(const std::string override_value) { value_ = override_value; } - private: - DISALLOW_COPY_AND_ASSIGN(OverrideLocaleHolder); - std::string value_; -}; - -base::LazyInstance<OverrideLocaleHolder> - override_locale_holder(base::LINKER_INITIALIZED); - -} // namespace - -namespace l10n_util { - -const std::string& GetLocaleOverride() { - return override_locale_holder.Get().value(); -} - -void OverrideLocaleWithCocoaLocale() { - // NSBundle really should only be called on the main thread. - DCHECK([NSThread isMainThread]); - - // Chrome really only has one concept of locale, but Mac OS X has locale and - // language that can be set independently. After talking with Chrome UX folks - // (Cole), the best path from an experience point of view is to map the Mac OS - // X language into the Chrome locale. This way strings like "Yesterday" and - // "Today" are in the same language as raw dates like "March 20, 1999" (Chrome - // strings resources vs ICU generated strings). This also makes the Mac acts - // like other Chrome platforms. - NSArray* languageList = [[NSBundle mainBundle] preferredLocalizations]; - NSString* firstLocale = [languageList objectAtIndex:0]; - // Mac OS X uses "_" instead of "-", so swap to get a real locale value. - std::string locale_value = - [[firstLocale stringByReplacingOccurrencesOfString:@"_" - withString:@"-"] UTF8String]; - - // On disk the "en-US" resources are just "en" (http://crbug.com/25578), so - // the reverse mapping is done here to continue to feed Chrome the same values - // in all cases on all platforms. (l10n_util maps en to en-US if it gets - // passed this on the command line) - if (locale_value == "en") - locale_value = "en-US"; - - override_locale_holder.Get().set_value(locale_value); -} - -// Remove the Windows-style accelerator marker and change "..." into an -// ellipsis. Returns the result in an autoreleased NSString. -NSString* FixUpWindowsStyleLabel(const string16& label) { - const char16 kEllipsisUTF16 = 0x2026; - string16 ret; - size_t label_len = label.length(); - ret.reserve(label_len); - for (size_t i = 0; i < label_len; ++i) { - char16 c = label[i]; - if (c == '&') { - if (i + 1 < label_len && label[i + 1] == '&') { - ret.push_back(c); - ++i; - } - } else if (c == '.' && i + 2 < label_len && label[i + 1] == '.' - && label[i + 2] == '.') { - ret.push_back(kEllipsisUTF16); - i += 2; - } else { - ret.push_back(c); - } - } - - return base::SysUTF16ToNSString(ret); -} - -NSString* GetNSString(int message_id) { - return base::SysUTF16ToNSString(l10n_util::GetStringUTF16(message_id)); -} - -NSString* GetNSStringF(int message_id, - const string16& a) { - return base::SysUTF16ToNSString(l10n_util::GetStringFUTF16(message_id, - a)); -} - -NSString* GetNSStringF(int message_id, - const string16& a, - const string16& b) { - return base::SysUTF16ToNSString(l10n_util::GetStringFUTF16(message_id, - a, b)); -} - -NSString* GetNSStringF(int message_id, - const string16& a, - const string16& b, - const string16& c) { - return base::SysUTF16ToNSString(l10n_util::GetStringFUTF16(message_id, - a, b, c)); -} - -NSString* GetNSStringF(int message_id, - const string16& a, - const string16& b, - const string16& c, - const string16& d) { - return base::SysUTF16ToNSString(l10n_util::GetStringFUTF16(message_id, - a, b, c, d)); -} - -NSString* GetNSStringF(int message_id, - const string16& a, - const string16& b, - std::vector<size_t>* offsets) { - return base::SysUTF16ToNSString(l10n_util::GetStringFUTF16(message_id, - a, b, offsets)); -} - -NSString* GetNSStringWithFixup(int message_id) { - return FixUpWindowsStyleLabel(l10n_util::GetStringUTF16(message_id)); -} - -NSString* GetNSStringFWithFixup(int message_id, - const string16& a) { - return FixUpWindowsStyleLabel(l10n_util::GetStringFUTF16(message_id, - a)); -} - -NSString* GetNSStringFWithFixup(int message_id, - const string16& a, - const string16& b) { - return FixUpWindowsStyleLabel(l10n_util::GetStringFUTF16(message_id, - a, b)); -} - -NSString* GetNSStringFWithFixup(int message_id, - const string16& a, - const string16& b, - const string16& c) { - return FixUpWindowsStyleLabel(l10n_util::GetStringFUTF16(message_id, - a, b, c)); -} - -NSString* GetNSStringFWithFixup(int message_id, - const string16& a, - const string16& b, - const string16& c, - const string16& d) { - return FixUpWindowsStyleLabel(l10n_util::GetStringFUTF16(message_id, - a, b, c, d)); -} - - -} // namespace l10n_util diff --git a/app/l10n_util_mac_unittest.mm b/app/l10n_util_mac_unittest.mm deleted file mode 100644 index e6c4485..0000000 --- a/app/l10n_util_mac_unittest.mm +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#import <Foundation/Foundation.h> - -#include "base/sys_string_conversions.h" -#include "app/l10n_util_mac.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "testing/platform_test.h" - -typedef PlatformTest L10nUtilMacTest; - -TEST_F(L10nUtilMacTest, FixUpWindowsStyleLabel) { - struct TestData { - NSString* input; - NSString* output; - }; - - TestData data[] = { - { @"", @"" }, - { @"nothing", @"nothing" }, - { @"foo &bar", @"foo bar" }, - { @"foo &&bar", @"foo &bar" }, - { @"foo &&&bar", @"foo &bar" }, - { @"&foo &&bar", @"foo &bar" }, - { @"&foo &bar", @"foo bar" }, - { @"foo bar.", @"foo bar." }, - { @"foo bar..", @"foo bar.." }, - { @"foo bar...", @"foo bar\u2026" }, - { @"foo.bar", @"foo.bar" }, - { @"foo..bar", @"foo..bar" }, - { @"foo...bar", @"foo\u2026bar" }, - { @"foo...bar...", @"foo\u2026bar\u2026" }, - }; - for (size_t idx = 0; idx < ARRAYSIZE_UNSAFE(data); ++idx) { - string16 input16(base::SysNSStringToUTF16(data[idx].input)); - - NSString* result = l10n_util::FixUpWindowsStyleLabel(input16); - EXPECT_TRUE(result != nil) << "Fixup Failed, idx = " << idx; - - EXPECT_TRUE([data[idx].output isEqualTo:result]) - << "For idx " << idx << ", expected '" << [data[idx].output UTF8String] - << "', got '" << [result UTF8String] << "'"; - } -} diff --git a/app/l10n_util_posix.cc b/app/l10n_util_posix.cc deleted file mode 100644 index f5f8b56c..0000000 --- a/app/l10n_util_posix.cc +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include <string> - -namespace l10n_util { - -// Return true blindly for now. -bool IsLocaleSupportedByOS(const std::string& locale) { - return true; -} - -} // namespace l10n_util diff --git a/app/l10n_util_unittest.cc b/app/l10n_util_unittest.cc deleted file mode 100644 index d767c22..0000000 --- a/app/l10n_util_unittest.cc +++ /dev/null @@ -1,397 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "build/build_config.h" - -#if defined(OS_POSIX) && !defined(OS_MACOSX) -#include <cstdlib> -#endif - -#include "app/l10n_util.h" -#include "app/l10n_util_collator.h" -#if !defined(OS_MACOSX) -#include "app/test/data/resource.h" -#endif -#include "base/basictypes.h" -#include "base/environment.h" -#include "base/file_util.h" -#include "base/path_service.h" -#include "base/stl_util-inl.h" -#include "base/string_util.h" -#include "base/utf_string_conversions.h" -#if defined(OS_WIN) -#include "base/win/windows_version.h" -#endif -#include "testing/gtest/include/gtest/gtest.h" -#include "testing/platform_test.h" -#include "ui/base/ui_base_paths.h" -#include "unicode/locid.h" - -namespace { - -class StringWrapper { - public: - explicit StringWrapper(const string16& string) : string_(string) {} - const string16& string() const { return string_; } - - private: - string16 string_; - - DISALLOW_COPY_AND_ASSIGN(StringWrapper); -}; - -} // namespace - -class L10nUtilTest : public PlatformTest { -}; - -#if defined(OS_WIN) -// TODO(beng): disabled until app strings move to app. -TEST_F(L10nUtilTest, DISABLED_GetString) { - std::string s = l10n_util::GetStringUTF8(IDS_SIMPLE); - EXPECT_EQ(std::string("Hello World!"), s); - - s = l10n_util::GetStringFUTF8(IDS_PLACEHOLDERS, - UTF8ToUTF16("chrome"), - UTF8ToUTF16("10")); - EXPECT_EQ(std::string("Hello, chrome. Your number is 10."), s); - - string16 s16 = l10n_util::GetStringFUTF16Int(IDS_PLACEHOLDERS_2, 20); - EXPECT_EQ(UTF8ToUTF16("You owe me $20."), s16); -} -#endif // defined(OS_WIN) - -TEST_F(L10nUtilTest, TruncateString) { - string16 string = ASCIIToUTF16("foooooey bxxxar baz"); - - // Make sure it doesn't modify the string if length > string length. - EXPECT_EQ(string, l10n_util::TruncateString(string, 100)); - - // Test no characters. - EXPECT_EQ(L"", UTF16ToWide(l10n_util::TruncateString(string, 0))); - - // Test 1 character. - EXPECT_EQ(L"\x2026", UTF16ToWide(l10n_util::TruncateString(string, 1))); - - // Test adds ... at right spot when there is enough room to break at a - // word boundary. - EXPECT_EQ(L"foooooey\x2026", - UTF16ToWide(l10n_util::TruncateString(string, 14))); - - // Test adds ... at right spot when there is not enough space in first word. - EXPECT_EQ(L"f\x2026", UTF16ToWide(l10n_util::TruncateString(string, 2))); - - // Test adds ... at right spot when there is not enough room to break at a - // word boundary. - EXPECT_EQ(L"foooooey\x2026", - UTF16ToWide(l10n_util::TruncateString(string, 11))); - - // Test completely truncates string if break is on initial whitespace. - EXPECT_EQ(L"\x2026", - UTF16ToWide(l10n_util::TruncateString(ASCIIToUTF16(" "), 2))); -} - -void SetICUDefaultLocale(const std::string& locale_string) { - icu::Locale locale(locale_string.c_str()); - UErrorCode error_code = U_ZERO_ERROR; - icu::Locale::setDefault(locale, error_code); - EXPECT_TRUE(U_SUCCESS(error_code)); -} - -#if !defined(OS_MACOSX) -// We are disabling this test on MacOS because GetApplicationLocale() as an -// API isn't something that we'll easily be able to unit test in this manner. -// The meaning of that API, on the Mac, is "the locale used by Cocoa's main -// nib file", which clearly can't be stubbed by a test app that doesn't use -// Cocoa. - -void SetDefaultLocaleForTest(const std::string& tag, base::Environment* env) { -#if defined(OS_POSIX) && !defined(OS_CHROMEOS) - env->SetVar("LANGUAGE", tag); -#else - SetICUDefaultLocale(tag); -#endif -} - -TEST_F(L10nUtilTest, GetAppLocale) { - scoped_ptr<base::Environment> env; - // Use a temporary locale dir so we don't have to actually build the locale - // dlls for this test. - FilePath orig_locale_dir; - PathService::Get(ui::DIR_LOCALES, &orig_locale_dir); - FilePath new_locale_dir; - EXPECT_TRUE(file_util::CreateNewTempDirectory( - FILE_PATH_LITERAL("l10n_util_test"), - &new_locale_dir)); - PathService::Override(ui::DIR_LOCALES, new_locale_dir); - // Make fake locale files. - std::string filenames[] = { - "en-US", - "en-GB", - "fr", - "es-419", - "es", - "zh-TW", - "zh-CN", - "he", - "fil", - "nb", - "am", - }; - -#if defined(OS_WIN) - static const char kLocaleFileExtension[] = ".dll"; -#elif defined(OS_POSIX) - static const char kLocaleFileExtension[] = ".pak"; -#endif - for (size_t i = 0; i < arraysize(filenames); ++i) { - FilePath filename = new_locale_dir.AppendASCII( - filenames[i] + kLocaleFileExtension); - file_util::WriteFile(filename, "", 0); - } - - // Keep a copy of ICU's default locale before we overwrite it. - icu::Locale locale = icu::Locale::getDefault(); - -#if defined(OS_POSIX) && !defined(OS_CHROMEOS) - env.reset(base::Environment::Create()); - - // Test the support of LANGUAGE environment variable. - SetICUDefaultLocale("en-US"); - env->SetVar("LANGUAGE", "xx:fr_CA"); - EXPECT_EQ("fr", l10n_util::GetApplicationLocale("")); - - env->SetVar("LANGUAGE", "xx:yy:en_gb.utf-8@quot"); - EXPECT_EQ("en-GB", l10n_util::GetApplicationLocale("")); - - env->SetVar("LANGUAGE", "xx:zh-hk"); - EXPECT_EQ("zh-TW", l10n_util::GetApplicationLocale("")); - - // We emulate gettext's behavior here, which ignores LANG/LC_MESSAGES/LC_ALL - // when LANGUAGE is specified. If no language specified in LANGUAGE is valid, - // then just fallback to the default language, which is en-US for us. - SetICUDefaultLocale("fr-FR"); - env->SetVar("LANGUAGE", "xx:yy"); - EXPECT_EQ("en-US", l10n_util::GetApplicationLocale("")); - - env->SetVar("LANGUAGE", "/fr:zh_CN"); - EXPECT_EQ("zh-CN", l10n_util::GetApplicationLocale("")); - - // Test prioritization of the different environment variables. - env->SetVar("LANGUAGE", "fr"); - env->SetVar("LC_ALL", "es"); - env->SetVar("LC_MESSAGES", "he"); - env->SetVar("LANG", "nb"); - EXPECT_EQ("fr", l10n_util::GetApplicationLocale("")); - env->UnSetVar("LANGUAGE"); - EXPECT_EQ("es", l10n_util::GetApplicationLocale("")); - env->UnSetVar("LC_ALL"); - EXPECT_EQ("he", l10n_util::GetApplicationLocale("")); - env->UnSetVar("LC_MESSAGES"); - EXPECT_EQ("nb", l10n_util::GetApplicationLocale("")); - env->UnSetVar("LANG"); -#endif // defined(OS_POSIX) && !defined(OS_CHROMEOS) - - SetDefaultLocaleForTest("en-US", env.get()); - EXPECT_EQ("en-US", l10n_util::GetApplicationLocale("")); - - SetDefaultLocaleForTest("xx", env.get()); - EXPECT_EQ("en-US", l10n_util::GetApplicationLocale("")); - -#if defined(OS_CHROMEOS) - // ChromeOS honors preferred locale first in GetApplicationLocale(), - // defaulting to en-US, while other targets first honor other signals. - SetICUDefaultLocale("en-GB"); - EXPECT_EQ("en-US", l10n_util::GetApplicationLocale("")); - - SetICUDefaultLocale("en-US"); - EXPECT_EQ("en-GB", l10n_util::GetApplicationLocale("en-GB")); - -#else // defined(OS_CHROMEOS) - SetDefaultLocaleForTest("en-GB", env.get()); - EXPECT_EQ("en-GB", l10n_util::GetApplicationLocale("")); - - SetDefaultLocaleForTest("fr-CA", env.get()); - EXPECT_EQ("fr", l10n_util::GetApplicationLocale("")); - - SetDefaultLocaleForTest("es-MX", env.get()); - EXPECT_EQ("es-419", l10n_util::GetApplicationLocale("")); - - SetDefaultLocaleForTest("es-AR", env.get()); - EXPECT_EQ("es-419", l10n_util::GetApplicationLocale("")); - - SetDefaultLocaleForTest("es-ES", env.get()); - EXPECT_EQ("es", l10n_util::GetApplicationLocale("")); - - SetDefaultLocaleForTest("es", env.get()); - EXPECT_EQ("es", l10n_util::GetApplicationLocale("")); - - SetDefaultLocaleForTest("zh-HK", env.get()); - EXPECT_EQ("zh-TW", l10n_util::GetApplicationLocale("")); - - SetDefaultLocaleForTest("zh-MK", env.get()); - EXPECT_EQ("zh-TW", l10n_util::GetApplicationLocale("")); - - SetDefaultLocaleForTest("zh-SG", env.get()); - EXPECT_EQ("zh-CN", l10n_util::GetApplicationLocale("")); -#endif // defined (OS_CHROMEOS) - -#if defined(OS_WIN) - // We don't allow user prefs for locale on linux/mac. - SetICUDefaultLocale("en-US"); - EXPECT_EQ("fr", l10n_util::GetApplicationLocale("fr")); - EXPECT_EQ("fr", l10n_util::GetApplicationLocale("fr-CA")); - - SetICUDefaultLocale("en-US"); - // Aliases iw, no, tl to he, nb, fil. - EXPECT_EQ("he", l10n_util::GetApplicationLocale("iw")); - EXPECT_EQ("nb", l10n_util::GetApplicationLocale("no")); - EXPECT_EQ("fil", l10n_util::GetApplicationLocale("tl")); - // es-419 and es-XX (where XX is not Spain) should be - // mapped to es-419 (Latin American Spanish). - EXPECT_EQ("es-419", l10n_util::GetApplicationLocale("es-419")); - EXPECT_EQ("es", l10n_util::GetApplicationLocale("es-ES")); - EXPECT_EQ("es-419", l10n_util::GetApplicationLocale("es-AR")); - - SetICUDefaultLocale("es-AR"); - EXPECT_EQ("es", l10n_util::GetApplicationLocale("es")); - - SetICUDefaultLocale("zh-HK"); - EXPECT_EQ("zh-CN", l10n_util::GetApplicationLocale("zh-CN")); - - SetICUDefaultLocale("he"); - EXPECT_EQ("en-US", l10n_util::GetApplicationLocale("en")); - - // Amharic should be blocked unless OS is Vista or newer. - if (base::win::GetVersion() < base::win::VERSION_VISTA) { - SetICUDefaultLocale("am"); - EXPECT_EQ("en-US", l10n_util::GetApplicationLocale("")); - SetICUDefaultLocale("en-GB"); - EXPECT_EQ("en-GB", l10n_util::GetApplicationLocale("am")); - } else { - SetICUDefaultLocale("am"); - EXPECT_EQ("am", l10n_util::GetApplicationLocale("")); - SetICUDefaultLocale("en-GB"); - EXPECT_EQ("am", l10n_util::GetApplicationLocale("am")); - } -#endif // defined(OS_WIN) - - // Clean up. - PathService::Override(ui::DIR_LOCALES, orig_locale_dir); - file_util::Delete(new_locale_dir, true); - UErrorCode error_code = U_ZERO_ERROR; - icu::Locale::setDefault(locale, error_code); -} -#endif // !defined(OS_MACOSX) - -TEST_F(L10nUtilTest, SortStringsUsingFunction) { - std::vector<StringWrapper*> strings; - strings.push_back(new StringWrapper(UTF8ToUTF16("C"))); - strings.push_back(new StringWrapper(UTF8ToUTF16("d"))); - strings.push_back(new StringWrapper(UTF8ToUTF16("b"))); - strings.push_back(new StringWrapper(UTF8ToUTF16("a"))); - l10n_util::SortStringsUsingMethod("en-US", - &strings, - &StringWrapper::string); - ASSERT_TRUE(UTF8ToUTF16("a") == strings[0]->string()); - ASSERT_TRUE(UTF8ToUTF16("b") == strings[1]->string()); - ASSERT_TRUE(UTF8ToUTF16("C") == strings[2]->string()); - ASSERT_TRUE(UTF8ToUTF16("d") == strings[3]->string()); - STLDeleteElements(&strings); -} - -// Test upper and lower case string conversion. -TEST_F(L10nUtilTest, UpperLower) { - string16 mixed(ASCIIToUTF16("Text with UPPer & lowER casE.")); - const string16 expected_lower(ASCIIToUTF16("text with upper & lower case.")); - const string16 expected_upper(ASCIIToUTF16("TEXT WITH UPPER & LOWER CASE.")); - - string16 result = l10n_util::ToLower(mixed); - EXPECT_EQ(result, expected_lower); - - result = l10n_util::ToUpper(mixed); - EXPECT_EQ(result, expected_upper); -} - -TEST_F(L10nUtilTest, LocaleDisplayName) { - // TODO(jungshik): Make this test more extensive. - // Test zh-CN and zh-TW are treated as zh-Hans and zh-Hant. - string16 result = l10n_util::GetDisplayNameForLocale("zh-CN", "en", false); - EXPECT_EQ(result, ASCIIToUTF16("Chinese (Simplified Han)")); - - result = l10n_util::GetDisplayNameForLocale("zh-TW", "en", false); - EXPECT_EQ(result, ASCIIToUTF16("Chinese (Traditional Han)")); - - result = l10n_util::GetDisplayNameForLocale("pt-BR", "en", false); - EXPECT_EQ(result, ASCIIToUTF16("Portuguese (Brazil)")); - - result = l10n_util::GetDisplayNameForLocale("es-419", "en", false); - EXPECT_EQ(result, ASCIIToUTF16("Spanish (Latin America and the Caribbean)")); -} - -TEST_F(L10nUtilTest, GetParentLocales) { - std::vector<std::string> locales; - const std::string top_locale("sr_Cyrl_RS"); - l10n_util::GetParentLocales(top_locale, &locales); - - ASSERT_EQ(3U, locales.size()); - EXPECT_EQ("sr_Cyrl_RS", locales[0]); - EXPECT_EQ("sr_Cyrl", locales[1]); - EXPECT_EQ("sr", locales[2]); -} - -TEST_F(L10nUtilTest, IsValidLocaleSyntax) { - // Test valid locales. - EXPECT_TRUE(l10n_util::IsValidLocaleSyntax("en")); - EXPECT_TRUE(l10n_util::IsValidLocaleSyntax("fr")); - EXPECT_TRUE(l10n_util::IsValidLocaleSyntax("de")); - EXPECT_TRUE(l10n_util::IsValidLocaleSyntax("pt")); - EXPECT_TRUE(l10n_util::IsValidLocaleSyntax("zh")); - EXPECT_TRUE(l10n_util::IsValidLocaleSyntax("fil")); - EXPECT_TRUE(l10n_util::IsValidLocaleSyntax("haw")); - EXPECT_TRUE(l10n_util::IsValidLocaleSyntax("en-US")); - EXPECT_TRUE(l10n_util::IsValidLocaleSyntax("en_US")); - EXPECT_TRUE(l10n_util::IsValidLocaleSyntax("en_GB")); - EXPECT_TRUE(l10n_util::IsValidLocaleSyntax("pt-BR")); - EXPECT_TRUE(l10n_util::IsValidLocaleSyntax("zh_CN")); - EXPECT_TRUE(l10n_util::IsValidLocaleSyntax("zh_Hans")); - EXPECT_TRUE(l10n_util::IsValidLocaleSyntax("zh_Hans_CN")); - EXPECT_TRUE(l10n_util::IsValidLocaleSyntax("zh_Hant")); - EXPECT_TRUE(l10n_util::IsValidLocaleSyntax("zh_Hant_TW")); - EXPECT_TRUE(l10n_util::IsValidLocaleSyntax("fr_CA")); - EXPECT_TRUE(l10n_util::IsValidLocaleSyntax("i-klingon")); - EXPECT_TRUE(l10n_util::IsValidLocaleSyntax("es-419")); - EXPECT_TRUE(l10n_util::IsValidLocaleSyntax("en_IE_PREEURO")); - EXPECT_TRUE(l10n_util::IsValidLocaleSyntax("en_IE_u_cu_IEP")); - EXPECT_TRUE(l10n_util::IsValidLocaleSyntax("en_IE@currency=IEP")); - EXPECT_TRUE(l10n_util::IsValidLocaleSyntax("fr@x=y")); - EXPECT_TRUE(l10n_util::IsValidLocaleSyntax("zn_CN@foo=bar")); - EXPECT_TRUE(l10n_util::IsValidLocaleSyntax( - "fr@collation=phonebook;calendar=islamic-civil")); - EXPECT_TRUE(l10n_util::IsValidLocaleSyntax( - "sr_Latn_RS_REVISED@currency=USD")); - - // Test invalid locales. - EXPECT_FALSE(l10n_util::IsValidLocaleSyntax("")); - EXPECT_FALSE(l10n_util::IsValidLocaleSyntax("x")); - EXPECT_FALSE(l10n_util::IsValidLocaleSyntax("12")); - EXPECT_FALSE(l10n_util::IsValidLocaleSyntax("456")); - EXPECT_FALSE(l10n_util::IsValidLocaleSyntax("a1")); - EXPECT_FALSE(l10n_util::IsValidLocaleSyntax("enUS")); - EXPECT_FALSE(l10n_util::IsValidLocaleSyntax("zhcn")); - EXPECT_FALSE(l10n_util::IsValidLocaleSyntax("en.US")); - EXPECT_FALSE(l10n_util::IsValidLocaleSyntax("en#US")); - EXPECT_FALSE(l10n_util::IsValidLocaleSyntax("-en-US")); - EXPECT_FALSE(l10n_util::IsValidLocaleSyntax("en-US-")); - EXPECT_FALSE(l10n_util::IsValidLocaleSyntax("123-en-US")); - EXPECT_FALSE(l10n_util::IsValidLocaleSyntax("Latin")); - EXPECT_FALSE(l10n_util::IsValidLocaleSyntax("German")); - EXPECT_FALSE(l10n_util::IsValidLocaleSyntax("pt--BR")); - EXPECT_FALSE(l10n_util::IsValidLocaleSyntax("sl-macedonia")); - EXPECT_FALSE(l10n_util::IsValidLocaleSyntax("@")); - EXPECT_FALSE(l10n_util::IsValidLocaleSyntax("en-US@")); - EXPECT_FALSE(l10n_util::IsValidLocaleSyntax("en-US@x")); - EXPECT_FALSE(l10n_util::IsValidLocaleSyntax("en-US@x=")); - EXPECT_FALSE(l10n_util::IsValidLocaleSyntax("en-US@=y")); -} diff --git a/app/l10n_util_win.cc b/app/l10n_util_win.cc deleted file mode 100644 index d1e9392..0000000 --- a/app/l10n_util_win.cc +++ /dev/null @@ -1,185 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "app/l10n_util_win.h" - -#include <windowsx.h> -#include <algorithm> -#include <iterator> - -#include "app/l10n_util.h" -#include "base/i18n/rtl.h" -#include "base/lazy_instance.h" -#include "base/string_number_conversions.h" -#include "base/win/i18n.h" -#include "base/win/windows_version.h" -#include "grit/app_locale_settings.h" - -namespace { - -void AdjustLogFont(const std::wstring& font_family, - double font_size_scaler, - LOGFONT* logfont) { - DCHECK(font_size_scaler > 0); - font_size_scaler = std::max(std::min(font_size_scaler, 2.0), 0.7); - logfont->lfHeight = static_cast<long>(font_size_scaler * - static_cast<double>(abs(logfont->lfHeight)) + 0.5) * - (logfont->lfHeight > 0 ? 1 : -1); - - // TODO(jungshik): We may want to check the existence of the font. - // If it's not installed, we shouldn't adjust the font. - if (font_family != L"default") { - int name_len = std::min(static_cast<int>(font_family.size()), - LF_FACESIZE -1); - memcpy(logfont->lfFaceName, font_family.data(), name_len * sizeof(WORD)); - logfont->lfFaceName[name_len] = 0; - } -} - -bool IsFontPresent(const wchar_t* font_name) { - HFONT hfont = CreateFont(12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - font_name); - if (hfont == NULL) - return false; - HDC dc = GetDC(0); - HGDIOBJ oldFont = static_cast<HFONT>(SelectObject(dc, hfont)); - WCHAR actual_font_name[LF_FACESIZE]; - DWORD size_ret = GetTextFace(dc, LF_FACESIZE, actual_font_name); - actual_font_name[LF_FACESIZE - 1] = 0; - SelectObject(dc, oldFont); - DeleteObject(hfont); - ReleaseDC(0, dc); - // We don't have to worry about East Asian fonts with locale-dependent - // names here. - return wcscmp(font_name, actual_font_name) == 0; -} - -class OverrideLocaleHolder { - public: - OverrideLocaleHolder() {} - const std::vector<std::string>& value() const { return value_; } - void swap_value(std::vector<std::string>* override_value) { - value_.swap(*override_value); - } - private: - std::vector<std::string> value_; - DISALLOW_COPY_AND_ASSIGN(OverrideLocaleHolder); -}; - -base::LazyInstance<OverrideLocaleHolder> - override_locale_holder(base::LINKER_INITIALIZED); - -} // namespace - -namespace l10n_util { - -int GetExtendedStyles() { - return !base::i18n::IsRTL() ? 0 : WS_EX_LAYOUTRTL | WS_EX_RTLREADING; -} - -int GetExtendedTooltipStyles() { - return !base::i18n::IsRTL() ? 0 : WS_EX_LAYOUTRTL; -} - -void HWNDSetRTLLayout(HWND hwnd) { - DWORD ex_style = ::GetWindowLong(hwnd, GWL_EXSTYLE); - - // We don't have to do anything if the style is already set for the HWND. - if (!(ex_style & WS_EX_LAYOUTRTL)) { - ex_style |= WS_EX_LAYOUTRTL; - ::SetWindowLong(hwnd, GWL_EXSTYLE, ex_style); - - // Right-to-left layout changes are not applied to the window immediately - // so we should make sure a WM_PAINT is sent to the window by invalidating - // the entire window rect. - ::InvalidateRect(hwnd, NULL, true); - } -} - -bool IsLocaleSupportedByOS(const std::string& locale) { - // Block Amharic on Windows XP unless 'Abyssinica SIL' font is present. - // On Win XP, no Ethiopic/Amahric font is availabel out of box. We hard-coded - // 'Abyssinica SIL' in the resource bundle to use in the UI. Check - // for its presence to determine whether or not to support Amharic UI on XP. - return (base::win::GetVersion() >= base::win::VERSION_VISTA || - !LowerCaseEqualsASCII(locale, "am") || IsFontPresent(L"Abyssinica SIL")); -} - -bool NeedOverrideDefaultUIFont(std::wstring* override_font_family, - double* font_size_scaler) { - // This is rather simple-minded to deal with the UI font size - // issue for some Indian locales (ml, bn, hi) for which - // the default Windows fonts are too small to be legible. For those - // locales, IDS_UI_FONT_FAMILY is set to an actual font family to - // use while for other locales, it's set to 'default'. - - // XP and Vista or later have different font size issues and - // we need separate ui font specifications. - int ui_font_family_id = IDS_UI_FONT_FAMILY; - int ui_font_size_scaler_id = IDS_UI_FONT_SIZE_SCALER; - if (base::win::GetVersion() < base::win::VERSION_VISTA) { - ui_font_family_id = IDS_UI_FONT_FAMILY_XP; - ui_font_size_scaler_id = IDS_UI_FONT_SIZE_SCALER_XP; - } - - std::wstring ui_font_family = GetStringUTF16(ui_font_family_id); - int scaler100; - if (!base::StringToInt(l10n_util::GetStringUTF16(ui_font_size_scaler_id), - &scaler100)) - return false; - - // We use the OS default in two cases: - // 1) The resource bundle has 'default' and '100' for font family and - // font scaler. - // 2) The resource bundle is not available for some reason and - // ui_font_family is empty. - if (ui_font_family == L"default" && scaler100 == 100 || - ui_font_family.empty()) - return false; - if (override_font_family && font_size_scaler) { - override_font_family->swap(ui_font_family); - *font_size_scaler = scaler100 / 100.0; - } - return true; -} - -void AdjustUIFont(LOGFONT* logfont) { - std::wstring ui_font_family; - double ui_font_size_scaler; - if (NeedOverrideDefaultUIFont(&ui_font_family, &ui_font_size_scaler)) - AdjustLogFont(ui_font_family, ui_font_size_scaler, logfont); -} - -void AdjustUIFontForWindow(HWND hwnd) { - std::wstring ui_font_family; - double ui_font_size_scaler; - if (NeedOverrideDefaultUIFont(&ui_font_family, &ui_font_size_scaler)) { - LOGFONT logfont; - if (GetObject(GetWindowFont(hwnd), sizeof(logfont), &logfont)) { - AdjustLogFont(ui_font_family, ui_font_size_scaler, &logfont); - HFONT hfont = CreateFontIndirect(&logfont); - if (hfont) - SetWindowFont(hwnd, hfont, FALSE); - } - } -} - -void OverrideLocaleWithUILanguageList() { - std::vector<std::wstring> ui_languages; - if (base::win::i18n::GetThreadPreferredUILanguageList(&ui_languages)) { - std::vector<std::string> ascii_languages; - ascii_languages.reserve(ui_languages.size()); - std::transform(ui_languages.begin(), ui_languages.end(), - std::back_inserter(ascii_languages), &WideToASCII); - override_locale_holder.Get().swap_value(&ascii_languages); - } else { - NOTREACHED() << "Failed to determine the UI language for locale override."; - } -} - -const std::vector<std::string>& GetLocaleOverrides() { - return override_locale_holder.Get().value(); -} - -} // namespace l10n_util diff --git a/app/l10n_util_win.h b/app/l10n_util_win.h deleted file mode 100644 index 7a1dda5..0000000 --- a/app/l10n_util_win.h +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef APP_L10N_UTIL_WIN_H_ -#define APP_L10N_UTIL_WIN_H_ -#pragma once - -#include <windows.h> -#include <string> -#include <vector> - -namespace l10n_util { - -// Returns the locale-dependent extended window styles. -// This function is used for adding locale-dependent extended window styles -// (e.g. WS_EX_LAYOUTRTL, WS_EX_RTLREADING, etc.) when creating a window. -// Callers should OR this value into their extended style value when creating -// a window. -int GetExtendedStyles(); - -// TODO(xji): -// This is a temporary name, it will eventually replace GetExtendedStyles -int GetExtendedTooltipStyles(); - -// Give an HWND, this function sets the WS_EX_LAYOUTRTL extended style for the -// underlying window. When this style is set, the UI for the window is going to -// be mirrored. This is generally done for the UI of right-to-left languages -// such as Hebrew. -void HWNDSetRTLLayout(HWND hwnd); - -// See http://blogs.msdn.com/oldnewthing/archive/2005/09/15/467598.aspx -// and http://blogs.msdn.com/oldnewthing/archive/2006/06/26/647365.aspx -// as to why we need these three functions. - -// Return true if the default font (we get from Windows) is not suitable -// to use in the UI of the current UI (e.g. Malayalam, Bengali). If -// override_font_family and font_size_scaler are not null, they'll be -// filled with the font family name and the size scaler. -bool NeedOverrideDefaultUIFont(std::wstring* override_font_family, - double* font_size_scaler); - -// If the default UI font stored in |logfont| is not suitable, its family -// and size are replaced with those stored in the per-locale resource. -void AdjustUIFont(LOGFONT* logfont); - -// If the font for a given window (pointed to by HWND) is not suitable for the -// UI in the current UI langauge, its family and size are replaced with those -// stored in the per-locale resource. -void AdjustUIFontForWindow(HWND hwnd); - -// Allow processes to override the configured locale with the user's Windows UI -// languages. This function should generally be called once early in -// Application startup. -void OverrideLocaleWithUILanguageList(); - -// Retrieve the locale override, or an empty vector if the locale has not been -// or failed to be overridden. -const std::vector<std::string>& GetLocaleOverrides(); - -} // namespace l10n_util - -#endif // APP_L10N_UTIL_WIN_H_ diff --git a/app/win/win_util.cc b/app/win/win_util.cc index 7076a5f..f372ae5 100644 --- a/app/win/win_util.cc +++ b/app/win/win_util.cc @@ -9,8 +9,6 @@ #include <algorithm> -#include "app/l10n_util.h" -#include "app/l10n_util_win.h" #include "base/base_switches.h" #include "base/command_line.h" #include "base/file_util.h" @@ -24,6 +22,8 @@ #include "gfx/codec/png_codec.h" #include "gfx/font.h" #include "gfx/gdi_util.h" +#include "ui/base/l10n/l10n_util.h" +#include "ui/base/l10n/l10n_util_win.h" namespace app { namespace win { |