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

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

Issue 372075: Use renderer spellchecker for windows. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: inline 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/chrome.gyp » ('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"
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
114 if (language == special_version_string[i].language) { 114 if (language == special_version_string[i].language) {
115 versioned_bdict_file_name = 115 versioned_bdict_file_name =
116 language + special_version_string[i].version + ".bdic"; 116 language + special_version_string[i].version + ".bdic";
117 break; 117 break;
118 } 118 }
119 } 119 }
120 120
121 return dict_dir.AppendASCII(versioned_bdict_file_name); 121 return dict_dir.AppendASCII(versioned_bdict_file_name);
122 } 122 }
123 123
124 FilePath GetFirstChoiceFilePath(const std::string& language) {
125 FilePath dict_dir;
126 PathService::Get(chrome::DIR_APP_DICTIONARIES, &dict_dir);
127 return GetVersionedFileName(language, dict_dir);
128 }
129
130 FilePath GetFallbackFilePath(const FilePath& first_choice) {
131 FilePath dict_dir;
132 PathService::Get(chrome::DIR_USER_DATA, &dict_dir);
133 return dict_dir.Append(first_choice.BaseName());
134 }
135
124 } // namespace 136 } // namespace
125 137
126 // Constructed on UI thread. 138 // Constructed on UI thread.
127 SpellCheckHost::SpellCheckHost(Observer* observer, 139 SpellCheckHost::SpellCheckHost(Observer* observer,
128 const std::string& language, 140 const std::string& language,
129 URLRequestContextGetter* request_context_getter) 141 URLRequestContextGetter* request_context_getter)
130 : observer_(observer), 142 : observer_(observer),
131 language_(language), 143 language_(language),
144 file_(base::kInvalidPlatformFileValue),
132 tried_to_download_(false), 145 tried_to_download_(false),
133 request_context_getter_(request_context_getter) { 146 request_context_getter_(request_context_getter) {
134 DCHECK(observer_); 147 DCHECK(observer_);
135 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); 148 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
136 149
137 // TODO(estade): for Windows, we need to fall back to DIR_USER_DATA if
138 // DIR_APP_DICTIONARIES is not writeable.
139 FilePath dict_dir;
140 PathService::Get(chrome::DIR_APP_DICTIONARIES, &dict_dir);
141 bdict_file_ = GetVersionedFileName(language, dict_dir);
142
143 FilePath personal_file_directory; 150 FilePath personal_file_directory;
144 PathService::Get(chrome::DIR_USER_DATA, &personal_file_directory); 151 PathService::Get(chrome::DIR_USER_DATA, &personal_file_directory);
145 custom_dictionary_file_ = 152 custom_dictionary_file_ =
146 personal_file_directory.Append(chrome::kCustomDictionaryFileName); 153 personal_file_directory.Append(chrome::kCustomDictionaryFileName);
147 154
155 bdict_file_path_ = GetFirstChoiceFilePath(language);
156
148 ChromeThread::PostTask(ChromeThread::FILE, FROM_HERE, 157 ChromeThread::PostTask(ChromeThread::FILE, FROM_HERE,
149 NewRunnableMethod(this, &SpellCheckHost::Initialize)); 158 NewRunnableMethod(this, &SpellCheckHost::InitializeDictionaryLocation));
150 } 159 }
151 160
152 SpellCheckHost::~SpellCheckHost() { 161 SpellCheckHost::~SpellCheckHost() {
153 if (fd_.fd != -1) 162 if (file_ != base::kInvalidPlatformFileValue)
154 close(fd_.fd); 163 base::ClosePlatformFile(file_);
155 } 164 }
156 165
157 void SpellCheckHost::UnsetObserver() { 166 void SpellCheckHost::UnsetObserver() {
158 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); 167 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
159 168
160 observer_ = NULL; 169 observer_ = NULL;
161 } 170 }
162 171
163 void SpellCheckHost::AddWord(const std::string& word) { 172 void SpellCheckHost::AddWord(const std::string& word) {
164 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); 173 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
165 174
166 custom_words_.push_back(word); 175 custom_words_.push_back(word);
167 ChromeThread::PostTask(ChromeThread::FILE, FROM_HERE, 176 ChromeThread::PostTask(ChromeThread::FILE, FROM_HERE,
168 NewRunnableMethod(this, 177 NewRunnableMethod(this,
169 &SpellCheckHost::WriteWordToCustomDictionary, word)); 178 &SpellCheckHost::WriteWordToCustomDictionary, word));
170 NotificationService::current()->Notify( 179 NotificationService::current()->Notify(
171 NotificationType::SPELLCHECK_WORD_ADDED, 180 NotificationType::SPELLCHECK_WORD_ADDED,
172 Source<SpellCheckHost>(this), NotificationService::NoDetails()); 181 Source<SpellCheckHost>(this), NotificationService::NoDetails());
173 } 182 }
174 183
184 void SpellCheckHost::InitializeDictionaryLocation() {
185 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE));
186
187 #if defined(OS_WIN)
188 // Check if the dictionary exists in the fallback location. If so, use it
189 // rather than downloading anew.
190 FilePath fallback = GetFallbackFilePath(bdict_file_path_);
191 if (!file_util::PathExists(bdict_file_path_) &&
192 file_util::PathExists(fallback)) {
193 bdict_file_path_ = fallback;
194 }
195 #endif
196
197 Initialize();
198 }
199
175 void SpellCheckHost::Initialize() { 200 void SpellCheckHost::Initialize() {
176 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE)); 201 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE));
177 202
178 if (!observer_) 203 if (!observer_)
179 return; 204 return;
180 205
181 // We set |auto_close| to false because we don't want IPC to close the fd. 206 file_ = base::CreatePlatformFile(bdict_file_path_,
182 // We will close it manually in the destructor. 207 base::PLATFORM_FILE_READ | base::PLATFORM_FILE_OPEN,
183 fd_ = base::FileDescriptor(open(bdict_file_.value().c_str(), O_RDONLY), 208 NULL);
184 false);
185 209
186 // File didn't exist. Download it. 210 // File didn't exist. Download it.
187 if (fd_.fd == -1 && !tried_to_download_) { 211 if (file_ == base::kInvalidPlatformFileValue && !tried_to_download_) {
188 DownloadDictionary(); 212 DownloadDictionary();
189 return; 213 return;
190 } 214 }
191 215
192 if (fd_.fd != -1) { 216 if (file_ != base::kInvalidPlatformFileValue) {
193 // Load custom dictionary. 217 // Load custom dictionary.
194 std::string contents; 218 std::string contents;
195 file_util::ReadFileToString(custom_dictionary_file_, &contents); 219 file_util::ReadFileToString(custom_dictionary_file_, &contents);
196 std::vector<std::string> list_of_words; 220 std::vector<std::string> list_of_words;
197 SplitString(contents, '\n', &list_of_words); 221 SplitString(contents, '\n', &list_of_words);
198 for (size_t i = 0; i < list_of_words.size(); ++i) 222 for (size_t i = 0; i < list_of_words.size(); ++i)
199 custom_words_.push_back(list_of_words[i]); 223 custom_words_.push_back(list_of_words[i]);
200 } 224 }
201 225
202 ChromeThread::PostTask(ChromeThread::UI, FROM_HERE, 226 ChromeThread::PostTask(ChromeThread::UI, FROM_HERE,
203 NewRunnableMethod(this, 227 NewRunnableMethod(this,
204 &SpellCheckHost::InformObserverOfInitialization)); 228 &SpellCheckHost::InformObserverOfInitialization));
205 } 229 }
206 230
207 void SpellCheckHost::InformObserverOfInitialization() { 231 void SpellCheckHost::InformObserverOfInitialization() {
208 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); 232 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
209 233
210 if (observer_) 234 if (observer_)
211 observer_->SpellCheckHostInitialized(); 235 observer_->SpellCheckHostInitialized();
212 } 236 }
213 237
214 void SpellCheckHost::DownloadDictionary() { 238 void SpellCheckHost::DownloadDictionary() {
215 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE)); 239 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE));
216 240
217 // Determine URL of file to download. 241 // Determine URL of file to download.
218 static const char kDownloadServerUrl[] = 242 static const char kDownloadServerUrl[] =
219 "http://cache.pack.google.com/edgedl/chrome/dict/"; 243 "http://cache.pack.google.com/edgedl/chrome/dict/";
220 GURL url = GURL(std::string(kDownloadServerUrl) + WideToUTF8( 244 GURL url = GURL(std::string(kDownloadServerUrl) + WideToUTF8(
221 l10n_util::ToLower(bdict_file_.BaseName().ToWStringHack()))); 245 l10n_util::ToLower(bdict_file_path_.BaseName().ToWStringHack())));
222 fetcher_.reset(new URLFetcher(url, URLFetcher::GET, this)); 246 fetcher_.reset(new URLFetcher(url, URLFetcher::GET, this));
223 fetcher_->set_request_context(request_context_getter_.get()); 247 fetcher_->set_request_context(request_context_getter_.get());
224 tried_to_download_ = true; 248 tried_to_download_ = true;
225 fetcher_->Start(); 249 fetcher_->Start();
226 } 250 }
227 251
228 void SpellCheckHost::WriteWordToCustomDictionary(const std::string& word) { 252 void SpellCheckHost::WriteWordToCustomDictionary(const std::string& word) {
229 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE)); 253 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE));
230 254
231 // Stored in UTF-8. 255 // Stored in UTF-8.
(...skipping 24 matching lines...) Expand all
256 // There's the small chance that we might see a 200 status code for a body 280 // There's the small chance that we might see a 200 status code for a body
257 // that represents some form of failure. 281 // that represents some form of failure.
258 if (data.size() < 4 || data[0] != 'B' || data[1] != 'D' || data[2] != 'i' || 282 if (data.size() < 4 || data[0] != 'B' || data[1] != 'D' || data[2] != 'i' ||
259 data[3] != 'c') { 283 data[3] != 'c') {
260 LOG(ERROR) << "Failure to download dictionary."; 284 LOG(ERROR) << "Failure to download dictionary.";
261 Initialize(); 285 Initialize();
262 return; 286 return;
263 } 287 }
264 288
265 size_t bytes_written = 289 size_t bytes_written =
266 file_util::WriteFile(bdict_file_, data.data(), data.length()); 290 file_util::WriteFile(bdict_file_path_, data.data(), data.length());
267 if (bytes_written != data.length()) { 291 if (bytes_written != data.length()) {
268 LOG(ERROR) << "Failure to save dictionary."; 292 bool success = false;
269 // To avoid trying to load a partially saved dictionary, shortcut the 293 #if defined(OS_WIN)
270 // Initialize() call. 294 bdict_file_path_ = GetFallbackFilePath(bdict_file_path_);
271 ChromeThread::PostTask(ChromeThread::UI, FROM_HERE, 295 bytes_written =
272 NewRunnableMethod(this, 296 file_util::WriteFile(GetFallbackFilePath(bdict_file_path_),
273 &SpellCheckHost::InformObserverOfInitialization)); 297 data.data(), data.length());
274 return; 298 if (bytes_written == data.length())
299 success = true;
300 #endif
301
302 if (!success) {
303 LOG(ERROR) << "Failure to save dictionary.";
304 // To avoid trying to load a partially saved dictionary, shortcut the
305 // Initialize() call.
306 ChromeThread::PostTask(ChromeThread::UI, FROM_HERE,
307 NewRunnableMethod(this,
308 &SpellCheckHost::InformObserverOfInitialization));
309 return;
310 }
275 } 311 }
276 312
277 Initialize(); 313 Initialize();
278 } 314 }
OLDNEW
« no previous file with comments | « chrome/browser/spellcheck_host.h ('k') | chrome/chrome.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698