1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #import <Foundation/Foundation.h>
7 #include "base/lazy_instance.h"
8 #include "base/logging.h"
9 #include "base/mac/bundle_locations.h"
10 #include "base/strings/sys_string_conversions.h"
11 #include "ui/base/l10n/l10n_util.h"
12 #include "ui/base/l10n/l10n_util_mac.h"
16 base::LazyInstance<std::string> g_overridden_locale = LAZY_INSTANCE_INITIALIZER;
22 const std::string& GetLocaleOverride() {
23 return g_overridden_locale.Get();
26 void OverrideLocaleWithCocoaLocale() {
27 // NSBundle really should only be called on the main thread.
28 DCHECK([NSThread isMainThread]);
30 // Chrome really only has one concept of locale, but Mac OS X has locale and
31 // language that can be set independently. After talking with Chrome UX folks
32 // (Cole), the best path from an experience point of view is to map the Mac OS
33 // X language into the Chrome locale. This way strings like "Yesterday" and
34 // "Today" are in the same language as raw dates like "March 20, 1999" (Chrome
35 // strings resources vs ICU generated strings). This also makes the Mac acts
36 // like other Chrome platforms.
37 NSArray* languageList = [base::mac::OuterBundle() preferredLocalizations];
38 NSString* firstLocale = [languageList objectAtIndex:0];
39 // Mac OS X uses "_" instead of "-", so swap to get a real locale value.
40 std::string locale_value =
41 [[firstLocale stringByReplacingOccurrencesOfString:@"_"
42 withString:@"-"] UTF8String];
44 // On disk the "en-US" resources are just "en" (http://crbug.com/25578), so
45 // the reverse mapping is done here to continue to feed Chrome the same values
46 // in all cases on all platforms. (l10n_util maps en to en-US if it gets
47 // passed this on the command line)
48 if (locale_value == "en")
49 locale_value = "en-US";
51 g_overridden_locale.Get() = locale_value;
54 // Remove the Windows-style accelerator marker and change "..." into an
55 // ellipsis. Returns the result in an autoreleased NSString.
56 NSString* FixUpWindowsStyleLabel(const base::string16& label) {
57 const base::char16 kEllipsisUTF16 = 0x2026;
59 size_t label_len = label.length();
60 ret.reserve(label_len);
61 for (size_t i = 0; i < label_len; ++i) {
62 base::char16 c = label[i];
63 if (c == '(' && i + 3 < label_len && label[i + 1] == '&'
64 && label[i + 3] == ')') {
65 // Strip '(&?)' patterns which means Windows-style accelerator in some
66 // non-English locales such as Japanese.
68 } else if (c == '&') {
69 if (i + 1 < label_len && label[i + 1] == '&') {
73 } else if (c == '.' && i + 2 < label_len && label[i + 1] == '.'
74 && label[i + 2] == '.') {
75 ret.push_back(kEllipsisUTF16);
82 return base::SysUTF16ToNSString(ret);
85 NSString* GetNSString(int message_id) {
86 return base::SysUTF16ToNSString(l10n_util::GetStringUTF16(message_id));
89 NSString* GetNSStringF(int message_id,
90 const base::string16& a) {
91 return base::SysUTF16ToNSString(l10n_util::GetStringFUTF16(message_id,
95 NSString* GetNSStringF(int message_id,
96 const base::string16& a,
97 const base::string16& b) {
98 return base::SysUTF16ToNSString(l10n_util::GetStringFUTF16(message_id,
102 NSString* GetNSStringF(int message_id,
103 const base::string16& a,
104 const base::string16& b,
105 const base::string16& c) {
106 return base::SysUTF16ToNSString(l10n_util::GetStringFUTF16(message_id,
110 NSString* GetNSStringF(int message_id,
111 const base::string16& a,
112 const base::string16& b,
113 const base::string16& c,
114 const base::string16& d) {
115 return base::SysUTF16ToNSString(l10n_util::GetStringFUTF16(message_id,
119 NSString* GetNSStringF(int message_id,
120 const base::string16& a,
121 const base::string16& b,
122 std::vector<size_t>* offsets) {
123 return base::SysUTF16ToNSString(l10n_util::GetStringFUTF16(message_id,
127 NSString* GetNSStringWithFixup(int message_id) {
128 return FixUpWindowsStyleLabel(l10n_util::GetStringUTF16(message_id));
131 NSString* GetNSStringFWithFixup(int message_id,
132 const base::string16& a) {
133 return FixUpWindowsStyleLabel(l10n_util::GetStringFUTF16(message_id,
137 NSString* GetNSStringFWithFixup(int message_id,
138 const base::string16& a,
139 const base::string16& b) {
140 return FixUpWindowsStyleLabel(l10n_util::GetStringFUTF16(message_id,
144 NSString* GetNSStringFWithFixup(int message_id,
145 const base::string16& a,
146 const base::string16& b,
147 const base::string16& c) {
148 return FixUpWindowsStyleLabel(l10n_util::GetStringFUTF16(message_id,
152 NSString* GetNSStringFWithFixup(int message_id,
153 const base::string16& a,
154 const base::string16& b,
155 const base::string16& c,
156 const base::string16& d) {
157 return FixUpWindowsStyleLabel(l10n_util::GetStringFUTF16(message_id,
161 NSString* GetPluralNSStringF(int message_id, int number) {
162 return base::SysUTF16ToNSString(l10n_util::GetPluralStringFUTF16(message_id,
166 } // namespace l10n_util