Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(229)

Side by Side Diff: chrome_frame/simple_resource_loader.cc

Issue 4139010: The UI language rather than the locale is now used to pick Chrome's language ... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 10 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome_frame/simple_resource_loader.h ('k') | chrome_frame/test/simple_resource_loader_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome_frame/simple_resource_loader.h" 5 #include "chrome_frame/simple_resource_loader.h"
6 6
7 #include <atlbase.h>
8
7 #include <algorithm> 9 #include <algorithm>
8 10
9 #include <atlbase.h>
10
11 #include "base/base_paths.h" 11 #include "base/base_paths.h"
12 #include "base/file_path.h" 12 #include "base/file_path.h"
13 #include "base/file_util.h" 13 #include "base/file_util.h"
14 #include "base/path_service.h" 14 #include "base/path_service.h"
15 #include "base/i18n/file_util_icu.h"
16 #include "base/i18n/rtl.h" 15 #include "base/i18n/rtl.h"
17 #include "base/singleton.h" 16 #include "base/singleton.h"
18 #include "base/string_util.h" 17 #include "base/string_util.h"
19 #include "base/utf_string_conversions.h" 18 #include "base/utf_string_conversions.h"
19 #include "base/win/i18n.h"
20 #include "base/win/windows_version.h" 20 #include "base/win/windows_version.h"
21 21
22 #include "chrome_frame/policy_settings.h" 22 #include "chrome_frame/policy_settings.h"
23 23
24 namespace { 24 namespace {
25 25
26 const wchar_t kLocalesDirName[] = L"Locales"; 26 const wchar_t kLocalesDirName[] = L"Locales";
27 27
28 bool IsInvalidTagCharacter(wchar_t tag_character) { 28 bool IsInvalidTagCharacter(wchar_t tag_character) {
29 return !(L'-' == tag_character || 29 return !(L'-' == tag_character ||
(...skipping 24 matching lines...) Expand all
54 std::vector<std::wstring>* collection) { 54 std::vector<std::wstring>* collection) {
55 if (collection->end() == 55 if (collection->end() ==
56 std::find_if(collection->begin(), collection->end(), 56 std::find_if(collection->begin(), collection->end(),
57 CompareInsensitiveASCII(value))) { 57 CompareInsensitiveASCII(value))) {
58 collection->push_back(value); 58 collection->push_back(value);
59 return true; 59 return true;
60 } 60 }
61 return false; 61 return false;
62 } 62 }
63 63
64 // Returns true if the collection is modified.
65 bool PushBackWithFallbackIfAbsent(
66 const std::wstring& language,
67 std::vector<std::wstring>* collection) {
68 bool modified = false;
69
70 if (!language.empty()) {
71 // Try adding the language itself.
72 modified = PushBackIfAbsent(language, collection);
73
74 // Now try adding its fallback, if it has one.
75 std::wstring::size_type dash_pos = language.find(L'-');
76 if (0 < dash_pos && language.size() - 1 > dash_pos)
77 modified |= PushBackIfAbsent(language.substr(0, dash_pos), collection);
78 }
79
80 return modified;
81 }
82
64 } // namespace 83 } // namespace
65 84
66 SimpleResourceLoader::SimpleResourceLoader() 85 SimpleResourceLoader::SimpleResourceLoader()
67 : locale_dll_handle_(NULL) { 86 : locale_dll_handle_(NULL) {
68 // Find and load the resource DLL. 87 // Find and load the resource DLL.
69 std::vector<std::wstring> language_tags; 88 std::vector<std::wstring> language_tags;
70 89
71 // First, try the locale dictated by policy and its fallback. 90 // First, try the locale dictated by policy and its fallback.
72 std::wstring application_locale = 91 PushBackWithFallbackIfAbsent(Singleton<PolicySettings>()->ApplicationLocale(),
73 Singleton<PolicySettings>()->ApplicationLocale(); 92 &language_tags);
74 if (!application_locale.empty()) {
75 language_tags.push_back(application_locale);
76 std::wstring::size_type dash = application_locale.find(L'-');
77 if (std::wstring::npos != dash) {
78 if (0 != dash) {
79 language_tags.push_back(application_locale.substr(0, dash));
80 } else {
81 NOTREACHED() << "Group Policy application locale begins with a dash.";
82 }
83 }
84 }
85 93
86 // Next, try the thread, process, user, system languages. 94 // Next, try the thread, process, user, system languages.
87 GetPreferredLanguages(&language_tags); 95 GetPreferredLanguages(&language_tags);
88 96
89 // Finally, fall-back on "en-US" (which may already be present in the vector, 97 // Finally, fall-back on "en-US" (which may already be present in the vector,
90 // but that's okay since we'll exit with success when the first is tried). 98 // but that's okay since we'll exit with success when the first is tried).
91 language_tags.push_back(L"en-US"); 99 language_tags.push_back(L"en-US");
92 100
93 FilePath locales_path; 101 FilePath locales_path;
94 FilePath locale_dll_path; 102 FilePath locale_dll_path;
95 103
96 DetermineLocalesDirectory(&locales_path); 104 DetermineLocalesDirectory(&locales_path);
97 if (LoadLocaleDll(language_tags, locales_path, &locale_dll_handle_, 105 if (LoadLocaleDll(language_tags, locales_path, &locale_dll_handle_,
98 &locale_dll_path)) { 106 &locale_dll_path)) {
99 language_ = locale_dll_path.BaseName().RemoveExtension().value(); 107 language_ = locale_dll_path.BaseName().RemoveExtension().value();
100 } else { 108 } else {
101 NOTREACHED() << "Failed loading any resource dll (even \"en-US\")."; 109 NOTREACHED() << "Failed loading any resource dll (even \"en-US\").";
102 } 110 }
103 } 111 }
104 112
105 SimpleResourceLoader::~SimpleResourceLoader() { 113 SimpleResourceLoader::~SimpleResourceLoader() {
106 locale_dll_handle_ = NULL; 114 locale_dll_handle_ = NULL;
107 } 115 }
108 116
109 // static 117 // static
110 void SimpleResourceLoader::GetPreferredLanguages( 118 void SimpleResourceLoader::GetPreferredLanguages(
111 std::vector<std::wstring>* language_tags) { 119 std::vector<std::wstring>* language_tags) {
120 DCHECK(language_tags);
112 // The full set of preferred languages and their fallbacks are given priority. 121 // The full set of preferred languages and their fallbacks are given priority.
113 GetThreadPreferredUILanguages(language_tags); 122 std::vector<std::wstring> languages;
123 if (base::win::i18n::GetThreadPreferredUILanguageList(&languages)) {
124 for (std::vector<std::wstring>::const_iterator scan = languages.begin(),
125 end = languages.end(); scan != end; ++scan) {
126 PushBackIfAbsent(*scan, language_tags);
127 }
128 }
114 129
115 // The above gives us nothing pre-Vista, so use ICU to get the system 130 // Use the base i18n routines (i.e., ICU) as a last, best hope for something
116 // language and add it and its fallback to the end of the list if not present. 131 // meaningful for the user.
117 std::wstring language; 132 PushBackWithFallbackIfAbsent(ASCIIToWide(base::i18n::GetConfiguredLocale()),
118 std::wstring region; 133 language_tags);
119
120 GetICUSystemLanguage(&language, &region);
121 if (!region.empty()) {
122 std::wstring combined;
123 combined.reserve(language.size() + 1 + region.size());
124 combined.assign(language).append(L"-").append(region);
125 PushBackIfAbsent(combined, language_tags);
126 }
127 PushBackIfAbsent(language, language_tags);
128 } 134 }
129 135
130 // static 136 // static
131 bool SimpleResourceLoader::GetThreadPreferredUILanguages(
132 std::vector<std::wstring>* language_tags) {
133 typedef BOOL (WINAPI* GetThreadPreferredUILanguages_Fn)(
134 DWORD, PULONG, PZZWSTR, PULONG);
135 HMODULE kernel32 = GetModuleHandle(L"kernel32.dll");
136 DCHECK(kernel32) << "Failed finding kernel32.dll!";
137 GetThreadPreferredUILanguages_Fn get_thread_preferred_ui_languages =
138 reinterpret_cast<GetThreadPreferredUILanguages_Fn>(
139 GetProcAddress(kernel32, "GetThreadPreferredUILanguages"));
140 bool have_mui = (NULL != get_thread_preferred_ui_languages);
141 if (have_mui) {
142 const DWORD kNameAndFallbackFlags =
143 MUI_LANGUAGE_NAME | MUI_MERGE_SYSTEM_FALLBACK | MUI_MERGE_USER_FALLBACK;
144 ULONG language_count = 0;
145 ULONG buffer_length = 0;
146
147 if (get_thread_preferred_ui_languages(
148 kNameAndFallbackFlags,
149 &language_count,
150 NULL,
151 &buffer_length) && 0 != buffer_length) {
152 std::vector<wchar_t> language_names(buffer_length);
153
154 if (get_thread_preferred_ui_languages(
155 kNameAndFallbackFlags,
156 &language_count,
157 &language_names[0],
158 &buffer_length)) {
159 std::vector<wchar_t>::const_iterator scan = language_names.begin();
160 std::wstring language(&*scan);
161 while (!language.empty()) {
162 language_tags->push_back(language);
163 scan += language.size() + 1;
164 language.assign(&*scan);
165 }
166 }
167 }
168 }
169 return have_mui;
170 }
171
172 // static
173 void SimpleResourceLoader::GetICUSystemLanguage(std::wstring* language,
174 std::wstring* region) {
175 DCHECK(language);
176 DCHECK(region);
177
178 std::string icu_language, icu_region;
179 base::i18n::GetLanguageAndRegionFromOS(&icu_language, &icu_region);
180 if (!icu_language.empty()) {
181 *language = ASCIIToWide(icu_language);
182 } else {
183 language->clear();
184 }
185 if (!icu_region.empty()) {
186 *region = ASCIIToWide(icu_region);
187 } else {
188 region->clear();
189 }
190 }
191
192 // static
193 void SimpleResourceLoader::DetermineLocalesDirectory(FilePath* locales_path) { 137 void SimpleResourceLoader::DetermineLocalesDirectory(FilePath* locales_path) {
194 DCHECK(locales_path); 138 DCHECK(locales_path);
195 139
196 FilePath module_path; 140 FilePath module_path;
197 PathService::Get(base::DIR_MODULE, &module_path); 141 PathService::Get(base::DIR_MODULE, &module_path);
198 *locales_path = module_path.Append(kLocalesDirName); 142 *locales_path = module_path.Append(kLocalesDirName);
199 143
200 // We may be residing in the "locales" directory's parent, or we might be 144 // We may be residing in the "locales" directory's parent, or we might be
201 // in a sibling directory. Move up one and look for Locales again in the 145 // in a sibling directory. Move up one and look for Locales again in the
202 // latter case. 146 // latter case.
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
295 239
296 // static 240 // static
297 std::wstring SimpleResourceLoader::Get(int message_id) { 241 std::wstring SimpleResourceLoader::Get(int message_id) {
298 SimpleResourceLoader* loader = SimpleResourceLoader::instance(); 242 SimpleResourceLoader* loader = SimpleResourceLoader::instance();
299 return loader->GetLocalizedResource(message_id); 243 return loader->GetLocalizedResource(message_id);
300 } 244 }
301 245
302 HMODULE SimpleResourceLoader::GetResourceModuleHandle() { 246 HMODULE SimpleResourceLoader::GetResourceModuleHandle() {
303 return locale_dll_handle_; 247 return locale_dll_handle_;
304 } 248 }
OLDNEW
« no previous file with comments | « chrome_frame/simple_resource_loader.h ('k') | chrome_frame/test/simple_resource_loader_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698