Remove Oriya from the list of UI languages for now because we're not getting Oriya...
[chromium-blink-merge.git] / chrome / installer / util / l10n_string_util.cc
blobc90b656360e03d11cbec52f1dd139b80a60d333f
1 // Copyright (c) 2009 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 // This file defines specific implementation of BrowserDistribution class for
6 // Google Chrome.
8 #include <atlbase.h>
9 #include <shlwapi.h>
11 #include <map>
13 #include "base/logging.h"
14 #include "base/scoped_ptr.h"
15 #include "base/string_util.h"
17 #include "installer_util_strings.h"
19 namespace {
21 // Gets the language from the OS. If we're unable to get the system language,
22 // defaults to en-us.
23 std::wstring GetSystemLanguage() {
24 static std::wstring language;
25 if (!language.empty())
26 return language;
27 // We don't have ICU at this point, so we use win32 apis.
28 LCID id = GetThreadLocale();
29 int length = GetLocaleInfo(id, LOCALE_SISO639LANGNAME, 0, 0);
30 if (0 == length) {
31 language = L"en-us";
32 return language;
34 length = GetLocaleInfo(id, LOCALE_SISO639LANGNAME,
35 WriteInto(&language, length), length);
36 DCHECK(length == language.length() + 1);
37 StringToLowerASCII(&language);
39 // Add the country if we need it.
40 std::wstring country;
41 length = GetLocaleInfo(id, LOCALE_SISO3166CTRYNAME, 0, 0);
42 if (0 != length) {
43 length = GetLocaleInfo(id, LOCALE_SISO3166CTRYNAME,
44 WriteInto(&country, length), length);
45 DCHECK(length == country.length() + 1);
46 StringToLowerASCII(&country);
47 if (L"en" == language) {
48 if (L"gb" == country) {
49 language.append(L"-gb");
50 } else {
51 language.append(L"-us");
53 } else if (L"es" == language && L"es" != country) {
54 language.append(L"-419");
55 } else if (L"pt" == language) {
56 if (L"br" == country) {
57 language.append(L"-br");
58 } else {
59 language.append(L"-pt");
61 } else if (L"zh" == language) {
62 if (L"tw" == country || L"mk" == country || L"hk" == country) {
63 language.append(L"-tw");
64 } else {
65 language.append(L"-cn");
70 if (language.empty())
71 language = L"en-us";
73 return language;
76 // This method returns the appropriate language offset given the language as a
77 // string. Note: This method is not thread safe because of how we create
78 // |offset_map|.
79 int GetLanguageOffset(const std::wstring& language) {
80 static std::map<std::wstring, int> offset_map;
81 if (offset_map.empty()) {
82 #if defined(GOOGLE_CHROME_BUILD)
83 offset_map[L"ar"] = IDS_L10N_OFFSET_AR;
84 offset_map[L"bg"] = IDS_L10N_OFFSET_BG;
85 offset_map[L"bn"] = IDS_L10N_OFFSET_BN;
86 offset_map[L"ca"] = IDS_L10N_OFFSET_CA;
87 offset_map[L"cs"] = IDS_L10N_OFFSET_CS;
88 offset_map[L"da"] = IDS_L10N_OFFSET_DA;
89 offset_map[L"de"] = IDS_L10N_OFFSET_DE;
90 offset_map[L"el"] = IDS_L10N_OFFSET_EL;
91 offset_map[L"en-gb"] = IDS_L10N_OFFSET_EN_GB;
92 offset_map[L"en-us"] = IDS_L10N_OFFSET_EN_US;
93 offset_map[L"es"] = IDS_L10N_OFFSET_ES;
94 offset_map[L"es-419"] = IDS_L10N_OFFSET_ES_419;
95 offset_map[L"et"] = IDS_L10N_OFFSET_ET;
96 offset_map[L"fi"] = IDS_L10N_OFFSET_FI;
97 offset_map[L"fil"] = IDS_L10N_OFFSET_FIL;
98 offset_map[L"fr"] = IDS_L10N_OFFSET_FR;
99 offset_map[L"gu"] = IDS_L10N_OFFSET_GU;
100 offset_map[L"he"] = IDS_L10N_OFFSET_HE;
101 offset_map[L"hi"] = IDS_L10N_OFFSET_HI;
102 offset_map[L"hr"] = IDS_L10N_OFFSET_HR;
103 offset_map[L"hu"] = IDS_L10N_OFFSET_HU;
104 offset_map[L"id"] = IDS_L10N_OFFSET_ID;
105 offset_map[L"it"] = IDS_L10N_OFFSET_IT;
106 // Google web properties use iw for he. Handle both just to be safe.
107 offset_map[L"iw"] = IDS_L10N_OFFSET_HE;
108 offset_map[L"ja"] = IDS_L10N_OFFSET_JA;
109 offset_map[L"kn"] = IDS_L10N_OFFSET_KN;
110 offset_map[L"ko"] = IDS_L10N_OFFSET_KO;
111 offset_map[L"lt"] = IDS_L10N_OFFSET_LT;
112 offset_map[L"lv"] = IDS_L10N_OFFSET_LV;
113 offset_map[L"ml"] = IDS_L10N_OFFSET_ML;
114 offset_map[L"mr"] = IDS_L10N_OFFSET_MR;
115 // Google web properties use no for nb. Handle both just to be safe.
116 offset_map[L"nb"] = IDS_L10N_OFFSET_NO;
117 offset_map[L"nl"] = IDS_L10N_OFFSET_NL;
118 offset_map[L"no"] = IDS_L10N_OFFSET_NO;
119 offset_map[L"pl"] = IDS_L10N_OFFSET_PL;
120 offset_map[L"pt-br"] = IDS_L10N_OFFSET_PT_BR;
121 offset_map[L"pt-pt"] = IDS_L10N_OFFSET_PT_PT;
122 offset_map[L"ro"] = IDS_L10N_OFFSET_RO;
123 offset_map[L"ru"] = IDS_L10N_OFFSET_RU;
124 offset_map[L"sk"] = IDS_L10N_OFFSET_SK;
125 offset_map[L"sl"] = IDS_L10N_OFFSET_SL;
126 offset_map[L"sr"] = IDS_L10N_OFFSET_SR;
127 offset_map[L"sv"] = IDS_L10N_OFFSET_SV;
128 offset_map[L"ta"] = IDS_L10N_OFFSET_TA;
129 offset_map[L"te"] = IDS_L10N_OFFSET_TE;
130 offset_map[L"th"] = IDS_L10N_OFFSET_TH;
131 // Some Google web properties use tl for fil. Handle both just to be safe.
132 // They're not completely identical, but alias it here.
133 offset_map[L"tl"] = IDS_L10N_OFFSET_FIL;
134 offset_map[L"tr"] = IDS_L10N_OFFSET_TR;
135 offset_map[L"uk"] = IDS_L10N_OFFSET_UK;
136 offset_map[L"vi"] = IDS_L10N_OFFSET_VI;
137 offset_map[L"zh-cn"] = IDS_L10N_OFFSET_ZH_CN;
138 offset_map[L"zh-tw"] = IDS_L10N_OFFSET_ZH_TW;
139 #else // GOOGLE_CHROME_BUILD not defined
140 offset_map[L"en-us"] = IDS_L10N_OFFSET_EN_US;
141 #endif // if defined(GOOGLE_CHROME_BUILD)
144 std::map<std::wstring, int>::iterator it = offset_map.find(
145 StringToLowerASCII(language));
146 if (it != offset_map.end())
147 return it->second;
149 #if defined(GOOGLE_CHROME_BUILD)
150 NOTREACHED() << "unknown system language-country";
151 #endif // if defined(GOOGLE_CHROME_BUILD)
153 // Fallback on the en-US offset just in case.
154 return IDS_L10N_OFFSET_EN_US;
157 } // namespace
159 namespace installer_util {
161 std::wstring GetLocalizedString(int base_message_id) {
162 std::wstring language = GetSystemLanguage();
163 std::wstring localized_string;
165 int message_id = base_message_id + GetLanguageOffset(language);
166 const ATLSTRINGRESOURCEIMAGE* image = AtlGetStringResourceImage(
167 _AtlBaseModule.GetModuleInstance(), message_id);
168 if (image) {
169 localized_string = std::wstring(image->achString, image->nLength);
170 } else {
171 NOTREACHED() << "Unable to find resource id " << message_id;
174 return localized_string;
177 // Here we generate the url spec with the Microsoft res:// scheme which is
178 // explained here : http://support.microsoft.com/kb/220830
179 std::wstring GetLocalizedEulaResource() {
180 wchar_t full_exe_path[MAX_PATH];
181 int len = ::GetModuleFileName(NULL, full_exe_path, MAX_PATH);
182 if (len == 0 || len == MAX_PATH)
183 return L"";
184 std::wstring language = GetSystemLanguage();
185 const wchar_t* resource = L"IDR_OEMPG_EN.HTML";
187 static std::map<int, wchar_t*> html_map;
188 if (html_map.empty()) {
189 #if defined(GOOGLE_CHROME_BUILD)
190 html_map[IDS_L10N_OFFSET_AR] = L"IDR_OEMPG_AR.HTML";
191 html_map[IDS_L10N_OFFSET_BG] = L"IDR_OEMPG_BG.HTML";
192 html_map[IDS_L10N_OFFSET_CA] = L"IDR_OEMPG_CA.HTML";
193 html_map[IDS_L10N_OFFSET_CS] = L"IDR_OEMPG_CS.HTML";
194 html_map[IDS_L10N_OFFSET_DA] = L"IDR_OEMPG_DA.HTML";
195 html_map[IDS_L10N_OFFSET_DE] = L"IDR_OEMPG_DE.HTML";
196 html_map[IDS_L10N_OFFSET_EL] = L"IDR_OEMPG_EL.HTML";
197 html_map[IDS_L10N_OFFSET_EN_US] = L"IDR_OEMPG_EN.HTML";
198 html_map[IDS_L10N_OFFSET_EN_GB] = L"IDR_OEMPG_EN_GB.HTML";
199 html_map[IDS_L10N_OFFSET_ES] = L"IDR_OEMPG_ES.HTML";
200 html_map[IDS_L10N_OFFSET_ES_419] = L"IDR_OEMPG_ES_419.HTML";
201 html_map[IDS_L10N_OFFSET_ET] = L"IDR_OEMPG_ET.HTML";
202 html_map[IDS_L10N_OFFSET_FI] = L"IDR_OEMPG_FI.HTML";
203 html_map[IDS_L10N_OFFSET_FIL] = L"IDR_OEMPG_FIL.HTML";
204 html_map[IDS_L10N_OFFSET_FR] = L"IDR_OEMPG_FR.HTML";
205 html_map[IDS_L10N_OFFSET_HI] = L"IDR_OEMPG_HI.HTML";
206 html_map[IDS_L10N_OFFSET_HR] = L"IDR_OEMPG_HR.HTML";
207 html_map[IDS_L10N_OFFSET_HU] = L"IDR_OEMPG_HU.HTML";
208 html_map[IDS_L10N_OFFSET_ID] = L"IDR_OEMPG_ID.HTML";
209 html_map[IDS_L10N_OFFSET_IT] = L"IDR_OEMPG_IT.HTML";
210 html_map[IDS_L10N_OFFSET_JA] = L"IDR_OEMPG_JA.HTML";
211 html_map[IDS_L10N_OFFSET_KO] = L"IDR_OEMPG_KO.HTML";
212 html_map[IDS_L10N_OFFSET_LT] = L"IDR_OEMPG_LT.HTML";
213 html_map[IDS_L10N_OFFSET_LV] = L"IDR_OEMPG_LV.HTML";
214 html_map[IDS_L10N_OFFSET_NL] = L"IDR_OEMPG_NL.HTML";
215 html_map[IDS_L10N_OFFSET_NO] = L"IDR_OEMPG_NO.HTML";
216 html_map[IDS_L10N_OFFSET_PL] = L"IDR_OEMPG_PL.HTML";
217 html_map[IDS_L10N_OFFSET_PT_BR] = L"IDR_OEMPG_PT_BR.HTML";
218 html_map[IDS_L10N_OFFSET_PT_PT] = L"IDR_OEMPG_PT_PT.HTML";
219 html_map[IDS_L10N_OFFSET_RO] = L"IDR_OEMPG_RO.HTML";
220 html_map[IDS_L10N_OFFSET_RU] = L"IDR_OEMPG_RU.HTML";
221 html_map[IDS_L10N_OFFSET_SK] = L"IDR_OEMPG_SK.HTML";
222 html_map[IDS_L10N_OFFSET_SL] = L"IDR_OEMPG_SL.HTML";
223 html_map[IDS_L10N_OFFSET_SR] = L"IDR_OEMPG_SR.HTML";
224 html_map[IDS_L10N_OFFSET_SV] = L"IDR_OEMPG_SV.HTML";
225 html_map[IDS_L10N_OFFSET_TH] = L"IDR_OEMPG_TH.HTML";
226 html_map[IDS_L10N_OFFSET_TR] = L"IDR_OEMPG_TR.HTML";
227 html_map[IDS_L10N_OFFSET_UK] = L"IDR_OEMPG_UK.HTML";
228 html_map[IDS_L10N_OFFSET_VI] = L"IDR_OEMPG_VI.HTML";
229 html_map[IDS_L10N_OFFSET_ZH_CN] = L"IDR_OEMPG_ZH_CN.HTML";
230 html_map[IDS_L10N_OFFSET_ZH_TW] = L"IDR_OEMPG_ZH_TW.HTML";
231 #else // GOOGLE_CHROME_BUILD not defined
232 html_map[IDS_L10N_OFFSET_EN_US] = L"IDR_OEMPG_EN.HTML";
233 #endif // if defined(GOOGLE_CHROME_BUILD)
236 std::map<int, wchar_t*>::iterator it = html_map.find(
237 GetLanguageOffset(language));
238 if (it != html_map.end())
239 resource = it->second;
241 // Spaces and DOS paths must be url encoded.
242 std::wstring url_path =
243 StringPrintf(L"res://%ls/#23/%ls", full_exe_path, resource);
245 // The cast is safe because url_path has limited length
246 // (see the definition of full_exe_path and resource).
247 DCHECK(kuint32max > (url_path.size() * 3));
248 DWORD count = static_cast<DWORD>(url_path.size() * 3);
249 scoped_array<wchar_t> url_canon(new wchar_t[count]);
250 HRESULT hr = ::UrlCanonicalizeW(url_path.c_str(), url_canon.get(),
251 &count, URL_ESCAPE_UNSAFE);
252 if (SUCCEEDED(hr))
253 return std::wstring(url_canon.get());
254 return url_path;
257 } // namespace installer_util