• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
14namespace {
15
16base::LazyInstance<std::string> g_overridden_locale = LAZY_INSTANCE_INITIALIZER;
17
18}  // namespace
19
20namespace l10n_util {
21
22const std::string& GetLocaleOverride() {
23  return g_overridden_locale.Get();
24}
25
26void 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.
56NSString* FixUpWindowsStyleLabel(const string16& label) {
57  const char16 kEllipsisUTF16 = 0x2026;
58  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    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
85NSString* GetNSString(int message_id) {
86  return base::SysUTF16ToNSString(l10n_util::GetStringUTF16(message_id));
87}
88
89NSString* GetNSStringF(int message_id,
90                       const string16& a) {
91  return base::SysUTF16ToNSString(l10n_util::GetStringFUTF16(message_id,
92                                                             a));
93}
94
95NSString* GetNSStringF(int message_id,
96                       const string16& a,
97                       const string16& b) {
98  return base::SysUTF16ToNSString(l10n_util::GetStringFUTF16(message_id,
99                                                             a, b));
100}
101
102NSString* GetNSStringF(int message_id,
103                       const string16& a,
104                       const string16& b,
105                       const string16& c) {
106  return base::SysUTF16ToNSString(l10n_util::GetStringFUTF16(message_id,
107                                                             a, b, c));
108}
109
110NSString* GetNSStringF(int message_id,
111                       const string16& a,
112                       const string16& b,
113                       const string16& c,
114                       const string16& d) {
115  return base::SysUTF16ToNSString(l10n_util::GetStringFUTF16(message_id,
116                                                             a, b, c, d));
117}
118
119NSString* GetNSStringF(int message_id,
120                       const string16& a,
121                       const string16& b,
122                       std::vector<size_t>* offsets) {
123  return base::SysUTF16ToNSString(l10n_util::GetStringFUTF16(message_id,
124                                                             a, b, offsets));
125}
126
127NSString* GetNSStringWithFixup(int message_id) {
128  return FixUpWindowsStyleLabel(l10n_util::GetStringUTF16(message_id));
129}
130
131NSString* GetNSStringFWithFixup(int message_id,
132                                const string16& a) {
133  return FixUpWindowsStyleLabel(l10n_util::GetStringFUTF16(message_id,
134                                                           a));
135}
136
137NSString* GetNSStringFWithFixup(int message_id,
138                                const string16& a,
139                                const string16& b) {
140  return FixUpWindowsStyleLabel(l10n_util::GetStringFUTF16(message_id,
141                                                           a, b));
142}
143
144NSString* GetNSStringFWithFixup(int message_id,
145                                const string16& a,
146                                const string16& b,
147                                const string16& c) {
148  return FixUpWindowsStyleLabel(l10n_util::GetStringFUTF16(message_id,
149                                                           a, b, c));
150}
151
152NSString* GetNSStringFWithFixup(int message_id,
153                                const string16& a,
154                                const string16& b,
155                                const string16& c,
156                                const string16& d) {
157  return FixUpWindowsStyleLabel(l10n_util::GetStringFUTF16(message_id,
158                                                           a, b, c, d));
159}
160
161
162}  // namespace l10n_util
163