OLD | NEW |
| (Empty) |
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. | |
4 | |
5 #import <Foundation/Foundation.h> | |
6 | |
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" | |
13 | |
14 namespace { | |
15 | |
16 base::LazyInstance<std::string> g_overridden_locale = LAZY_INSTANCE_INITIALIZER; | |
17 | |
18 } // namespace | |
19 | |
20 namespace l10n_util { | |
21 | |
22 const std::string& GetLocaleOverride() { | |
23 return g_overridden_locale.Get(); | |
24 } | |
25 | |
26 void OverrideLocaleWithCocoaLocale() { | |
27 // NSBundle really should only be called on the main thread. | |
28 DCHECK([NSThread isMainThread]); | |
29 | |
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]; | |
43 | |
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"; | |
50 | |
51 g_overridden_locale.Get() = locale_value; | |
52 } | |
53 | |
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; | |
58 base::string16 ret; | |
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. | |
67 i += 3; | |
68 } else if (c == '&') { | |
69 if (i + 1 < label_len && label[i + 1] == '&') { | |
70 ret.push_back(c); | |
71 ++i; | |
72 } | |
73 } else if (c == '.' && i + 2 < label_len && label[i + 1] == '.' | |
74 && label[i + 2] == '.') { | |
75 ret.push_back(kEllipsisUTF16); | |
76 i += 2; | |
77 } else { | |
78 ret.push_back(c); | |
79 } | |
80 } | |
81 | |
82 return base::SysUTF16ToNSString(ret); | |
83 } | |
84 | |
85 NSString* GetNSString(int message_id) { | |
86 return base::SysUTF16ToNSString(l10n_util::GetStringUTF16(message_id)); | |
87 } | |
88 | |
89 NSString* GetNSStringF(int message_id, | |
90 const base::string16& a) { | |
91 return base::SysUTF16ToNSString(l10n_util::GetStringFUTF16(message_id, | |
92 a)); | |
93 } | |
94 | |
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, | |
99 a, b)); | |
100 } | |
101 | |
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, | |
107 a, b, c)); | |
108 } | |
109 | |
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, | |
116 a, b, c, d)); | |
117 } | |
118 | |
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, | |
124 a, b, offsets)); | |
125 } | |
126 | |
127 NSString* GetNSStringWithFixup(int message_id) { | |
128 return FixUpWindowsStyleLabel(l10n_util::GetStringUTF16(message_id)); | |
129 } | |
130 | |
131 NSString* GetNSStringFWithFixup(int message_id, | |
132 const base::string16& a) { | |
133 return FixUpWindowsStyleLabel(l10n_util::GetStringFUTF16(message_id, | |
134 a)); | |
135 } | |
136 | |
137 NSString* GetNSStringFWithFixup(int message_id, | |
138 const base::string16& a, | |
139 const base::string16& b) { | |
140 return FixUpWindowsStyleLabel(l10n_util::GetStringFUTF16(message_id, | |
141 a, b)); | |
142 } | |
143 | |
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, | |
149 a, b, c)); | |
150 } | |
151 | |
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, | |
158 a, b, c, d)); | |
159 } | |
160 | |
161 | |
162 } // namespace l10n_util | |
OLD | NEW |