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

Side by Side Diff: chrome/browser/spellcheck_host.cc

Issue 395007: Move Mac to using renderer spellchecker. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: ui test fix Created 11 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/browser/spellcheck_host.h ('k') | chrome/browser/spellcheck_unittest.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) 2009 The Chromium Authors. All rights reserved. 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 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/browser/spellcheck_host.h" 5 #include "chrome/browser/spellcheck_host.h"
6 6
7 #include <fcntl.h> 7 #include <fcntl.h>
8 8
9 #include "app/l10n_util.h" 9 #include "app/l10n_util.h"
10 #include "base/file_util.h" 10 #include "base/file_util.h"
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/path_service.h" 12 #include "base/path_service.h"
13 #include "base/string_util.h" 13 #include "base/string_util.h"
14 #include "chrome/browser/profile.h"
15 #include "chrome/browser/spellchecker_platform_engine.h"
14 #include "chrome/common/chrome_constants.h" 16 #include "chrome/common/chrome_constants.h"
15 #include "chrome/common/chrome_paths.h" 17 #include "chrome/common/chrome_paths.h"
16 #include "chrome/common/notification_service.h" 18 #include "chrome/common/notification_service.h"
19 #include "chrome/common/pref_member.h"
20 #include "chrome/common/pref_names.h"
21 #include "chrome/common/spellcheck_common.h"
17 #include "googleurl/src/gurl.h" 22 #include "googleurl/src/gurl.h"
18 23
19 namespace { 24 namespace {
20 25
21 static const struct {
22 // The language.
23 const char* language;
24
25 // The corresponding language and region, used by the dictionaries.
26 const char* language_region;
27 } g_supported_spellchecker_languages[] = {
28 // Several languages are not to be included in the spellchecker list:
29 // th-TH, hu-HU, bg-BG, uk-UA
30 {"ca", "ca-ES"},
31 {"cs", "cs-CZ"},
32 {"da", "da-DK"},
33 {"de", "de-DE"},
34 {"el", "el-GR"},
35 {"en-AU", "en-AU"},
36 {"en-GB", "en-GB"},
37 {"en-US", "en-US"},
38 {"es", "es-ES"},
39 {"et", "et-EE"},
40 {"fr", "fr-FR"},
41 {"he", "he-IL"},
42 {"hi", "hi-IN"},
43 {"hr", "hr-HR"},
44 {"id", "id-ID"},
45 {"it", "it-IT"},
46 {"lt", "lt-LT"},
47 {"lv", "lv-LV"},
48 {"nb", "nb-NO"},
49 {"nl", "nl-NL"},
50 {"pl", "pl-PL"},
51 {"pt-BR", "pt-BR"},
52 {"pt-PT", "pt-PT"},
53 {"ro", "ro-RO"},
54 {"ru", "ru-RU"},
55 {"sk", "sk-SK"},
56 {"sl", "sl-SI"},
57 {"sv", "sv-SE"},
58 {"tr", "tr-TR"},
59 {"vi", "vi-VN"},
60 };
61
62 // This function returns the language-region version of language name.
63 // e.g. returns hi-IN for hi.
64 std::string GetSpellCheckLanguageRegion(const std::string& input_language) {
65 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(g_supported_spellchecker_languages);
66 ++i) {
67 if (g_supported_spellchecker_languages[i].language == input_language) {
68 return std::string(
69 g_supported_spellchecker_languages[i].language_region);
70 }
71 }
72
73 return input_language;
74 }
75
76 FilePath GetVersionedFileName(const std::string& input_language,
77 const FilePath& dict_dir) {
78 // The default dictionary version is 1-2. These versions have been augmented
79 // with additional words found by the translation team.
80 static const char kDefaultVersionString[] = "-1-2";
81
82 // The following dictionaries have either not been augmented with additional
83 // words (version 1-1) or have new words, as well as an upgraded dictionary
84 // as of Feb 2009 (version 1-3).
85 static const struct {
86 // The language input.
87 const char* language;
88
89 // The corresponding version.
90 const char* version;
91 } special_version_string[] = {
92 {"en-AU", "-1-1"},
93 {"en-GB", "-1-1"},
94 {"es-ES", "-1-1"},
95 {"nl-NL", "-1-1"},
96 {"ru-RU", "-1-1"},
97 {"sv-SE", "-1-1"},
98 {"he-IL", "-1-1"},
99 {"el-GR", "-1-1"},
100 {"hi-IN", "-1-1"},
101 {"tr-TR", "-1-1"},
102 {"et-EE", "-1-1"},
103 {"fr-FR", "-1-4"}, // To fix a crash, fr dictionary was updated to 1.4.
104 {"lt-LT", "-1-3"},
105 {"pl-PL", "-1-3"}
106 };
107
108 // Generate the bdict file name using default version string or special
109 // version string, depending on the language.
110 std::string language = GetSpellCheckLanguageRegion(input_language);
111 std::string versioned_bdict_file_name(language + kDefaultVersionString +
112 ".bdic");
113 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(special_version_string); ++i) {
114 if (language == special_version_string[i].language) {
115 versioned_bdict_file_name =
116 language + special_version_string[i].version + ".bdic";
117 break;
118 }
119 }
120
121 return dict_dir.AppendASCII(versioned_bdict_file_name);
122 }
123
124 FilePath GetFirstChoiceFilePath(const std::string& language) { 26 FilePath GetFirstChoiceFilePath(const std::string& language) {
125 FilePath dict_dir; 27 FilePath dict_dir;
126 PathService::Get(chrome::DIR_APP_DICTIONARIES, &dict_dir); 28 PathService::Get(chrome::DIR_APP_DICTIONARIES, &dict_dir);
127 return GetVersionedFileName(language, dict_dir); 29 return SpellCheckCommon::GetVersionedFileName(language, dict_dir);
128 } 30 }
129 31
130 FilePath GetFallbackFilePath(const FilePath& first_choice) { 32 FilePath GetFallbackFilePath(const FilePath& first_choice) {
131 FilePath dict_dir; 33 FilePath dict_dir;
132 PathService::Get(chrome::DIR_USER_DATA, &dict_dir); 34 PathService::Get(chrome::DIR_USER_DATA, &dict_dir);
133 return dict_dir.Append(first_choice.BaseName()); 35 return dict_dir.Append(first_choice.BaseName());
134 } 36 }
135 37
136 } // namespace 38 } // namespace
137 39
138 // Constructed on UI thread. 40 // Constructed on UI thread.
139 SpellCheckHost::SpellCheckHost(Observer* observer, 41 SpellCheckHost::SpellCheckHost(Observer* observer,
140 const std::string& language, 42 const std::string& language,
141 URLRequestContextGetter* request_context_getter) 43 URLRequestContextGetter* request_context_getter)
142 : observer_(observer), 44 : observer_(observer),
143 language_(language), 45 language_(language),
144 file_(base::kInvalidPlatformFileValue), 46 file_(base::kInvalidPlatformFileValue),
145 tried_to_download_(false), 47 tried_to_download_(false),
48 use_platform_spellchecker_(false),
146 request_context_getter_(request_context_getter) { 49 request_context_getter_(request_context_getter) {
147 DCHECK(observer_); 50 DCHECK(observer_);
148 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); 51 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
149 52
150 FilePath personal_file_directory; 53 FilePath personal_file_directory;
151 PathService::Get(chrome::DIR_USER_DATA, &personal_file_directory); 54 PathService::Get(chrome::DIR_USER_DATA, &personal_file_directory);
152 custom_dictionary_file_ = 55 custom_dictionary_file_ =
153 personal_file_directory.Append(chrome::kCustomDictionaryFileName); 56 personal_file_directory.Append(chrome::kCustomDictionaryFileName);
154 57
155 bdict_file_path_ = GetFirstChoiceFilePath(language); 58 bdict_file_path_ = GetFirstChoiceFilePath(language);
156 } 59 }
157 60
158 SpellCheckHost::~SpellCheckHost() { 61 SpellCheckHost::~SpellCheckHost() {
159 if (file_ != base::kInvalidPlatformFileValue) 62 if (file_ != base::kInvalidPlatformFileValue)
160 base::ClosePlatformFile(file_); 63 base::ClosePlatformFile(file_);
161 } 64 }
162 65
163 void SpellCheckHost::Initialize() { 66 void SpellCheckHost::Initialize() {
67 if (SpellCheckerPlatform::SpellCheckerAvailable() &&
68 SpellCheckerPlatform::PlatformSupportsLanguage(language_)) {
69 use_platform_spellchecker_ = true;
70 SpellCheckerPlatform::SetLanguage(language_);
71 MessageLoop::current()->PostTask(FROM_HERE,
72 NewRunnableMethod(this,
73 &SpellCheckHost::InformObserverOfInitialization));
74 return;
75 }
76
164 ChromeThread::PostTask(ChromeThread::FILE, FROM_HERE, 77 ChromeThread::PostTask(ChromeThread::FILE, FROM_HERE,
165 NewRunnableMethod(this, &SpellCheckHost::InitializeDictionaryLocation)); 78 NewRunnableMethod(this, &SpellCheckHost::InitializeDictionaryLocation));
166 } 79 }
167 80
168 void SpellCheckHost::UnsetObserver() { 81 void SpellCheckHost::UnsetObserver() {
169 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); 82 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
170 83
171 observer_ = NULL; 84 observer_ = NULL;
172 request_context_getter_ = NULL; 85 request_context_getter_ = NULL;
173 fetcher_.reset(); 86 fetcher_.reset();
174 } 87 }
175 88
176 void SpellCheckHost::AddWord(const std::string& word) { 89 void SpellCheckHost::AddWord(const std::string& word) {
177 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); 90 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
178 91
179 custom_words_.push_back(word); 92 custom_words_.push_back(word);
180 ChromeThread::PostTask(ChromeThread::FILE, FROM_HERE, 93 ChromeThread::PostTask(ChromeThread::FILE, FROM_HERE,
181 NewRunnableMethod(this, 94 NewRunnableMethod(this,
182 &SpellCheckHost::WriteWordToCustomDictionary, word)); 95 &SpellCheckHost::WriteWordToCustomDictionary, word));
183 NotificationService::current()->Notify( 96 NotificationService::current()->Notify(
184 NotificationType::SPELLCHECK_WORD_ADDED, 97 NotificationType::SPELLCHECK_WORD_ADDED,
185 Source<SpellCheckHost>(this), NotificationService::NoDetails()); 98 Source<SpellCheckHost>(this), NotificationService::NoDetails());
186 } 99 }
187 100
101 // static
102 int SpellCheckHost::GetSpellCheckLanguages(
103 Profile* profile,
104 std::vector<std::string>* languages) {
105 StringPrefMember accept_languages_pref;
106 StringPrefMember dictionary_language_pref;
107 accept_languages_pref.Init(prefs::kAcceptLanguages, profile->GetPrefs(),
108 NULL);
109 dictionary_language_pref.Init(prefs::kSpellCheckDictionary,
110 profile->GetPrefs(), NULL);
111 std::string dictionary_language =
112 WideToASCII(dictionary_language_pref.GetValue());
113
114 // The current dictionary language should be there.
115 languages->push_back(dictionary_language);
116
117 // Now scan through the list of accept languages, and find possible mappings
118 // from this list to the existing list of spell check languages.
119 std::vector<std::string> accept_languages;
120
121 if (SpellCheckerPlatform::SpellCheckerAvailable()) {
122 SpellCheckerPlatform::GetAvailableLanguages(&accept_languages);
123 } else {
124 SplitString(WideToASCII(accept_languages_pref.GetValue()), ',',
125 &accept_languages);
126 }
127 for (std::vector<std::string>::const_iterator i = accept_languages.begin();
128 i != accept_languages.end(); ++i) {
129 std::string language =
130 SpellCheckCommon::GetCorrespondingSpellCheckLanguage(*i);
131 if (!language.empty() &&
132 std::find(languages->begin(), languages->end(), language) ==
133 languages->end()) {
134 languages->push_back(language);
135 }
136 }
137
138 for (size_t i = 0; i < languages->size(); ++i) {
139 if ((*languages)[i] == dictionary_language)
140 return i;
141 }
142 return -1;
143 }
144
188 void SpellCheckHost::InitializeDictionaryLocation() { 145 void SpellCheckHost::InitializeDictionaryLocation() {
189 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE)); 146 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE));
190 147
191 #if defined(OS_WIN) 148 #if defined(OS_WIN)
192 // Check if the dictionary exists in the fallback location. If so, use it 149 // Check if the dictionary exists in the fallback location. If so, use it
193 // rather than downloading anew. 150 // rather than downloading anew.
194 FilePath fallback = GetFallbackFilePath(bdict_file_path_); 151 FilePath fallback = GetFallbackFilePath(bdict_file_path_);
195 if (!file_util::PathExists(bdict_file_path_) && 152 if (!file_util::PathExists(bdict_file_path_) &&
196 file_util::PathExists(fallback)) { 153 file_util::PathExists(fallback)) {
197 bdict_file_path_ = fallback; 154 bdict_file_path_ = fallback;
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
340 ChromeThread::PostTask(ChromeThread::UI, FROM_HERE, 297 ChromeThread::PostTask(ChromeThread::UI, FROM_HERE,
341 NewRunnableMethod(this, 298 NewRunnableMethod(this,
342 &SpellCheckHost::InformObserverOfInitialization)); 299 &SpellCheckHost::InformObserverOfInitialization));
343 return; 300 return;
344 } 301 }
345 } 302 }
346 303
347 data_.clear(); 304 data_.clear();
348 Initialize(); 305 Initialize();
349 } 306 }
OLDNEW
« no previous file with comments | « chrome/browser/spellcheck_host.h ('k') | chrome/browser/spellcheck_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698