OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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/spellchecker/spellcheck_custom_dictionary.h" | 5 #include "chrome/browser/spellchecker/spellcheck_custom_dictionary.h" |
6 | 6 |
7 #include <functional> | 7 #include <functional> |
8 | 8 |
9 #include "base/files/file_util.h" | 9 #include "base/files/file_util.h" |
10 #include "base/files/important_file_writer.h" | 10 #include "base/files/important_file_writer.h" |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
50 DETECTED_DUPLICATE_WORDS = 2, | 50 DETECTED_DUPLICATE_WORDS = 2, |
51 | 51 |
52 // The change contained words to be removed that are not in the dictionary. | 52 // The change contained words to be removed that are not in the dictionary. |
53 DETECTED_MISSING_WORDS = 4, | 53 DETECTED_MISSING_WORDS = 4, |
54 }; | 54 }; |
55 | 55 |
56 // Loads the file at |file_path| into the |words| container. If the file has a | 56 // Loads the file at |file_path| into the |words| container. If the file has a |
57 // valid checksum, then returns ChecksumStatus::VALID. If the file has an | 57 // valid checksum, then returns ChecksumStatus::VALID. If the file has an |
58 // invalid checksum, then returns ChecksumStatus::INVALID and clears |words|. | 58 // invalid checksum, then returns ChecksumStatus::INVALID and clears |words|. |
59 ChecksumStatus LoadFile(const base::FilePath& file_path, WordList& words) { | 59 ChecksumStatus LoadFile(const base::FilePath& file_path, WordList& words) { |
60 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 60 DCHECK_CURRENTLY_ON(BrowserThread::FILE); |
61 words.clear(); | 61 words.clear(); |
62 std::string contents; | 62 std::string contents; |
63 base::ReadFileToString(file_path, &contents); | 63 base::ReadFileToString(file_path, &contents); |
64 size_t pos = contents.rfind(CHECKSUM_PREFIX); | 64 size_t pos = contents.rfind(CHECKSUM_PREFIX); |
65 if (pos != std::string::npos) { | 65 if (pos != std::string::npos) { |
66 std::string checksum = contents.substr(pos + strlen(CHECKSUM_PREFIX)); | 66 std::string checksum = contents.substr(pos + strlen(CHECKSUM_PREFIX)); |
67 contents = contents.substr(0, pos); | 67 contents = contents.substr(0, pos); |
68 if (checksum != base::MD5String(contents)) | 68 if (checksum != base::MD5String(contents)) |
69 return INVALID_CHECKSUM; | 69 return INVALID_CHECKSUM; |
70 } | 70 } |
(...skipping 12 matching lines...) Expand all Loading... |
83 base::TRIM_NONE != base::TrimWhitespaceASCII(word, base::TRIM_ALL, &tmp); | 83 base::TRIM_NONE != base::TrimWhitespaceASCII(word, base::TRIM_ALL, &tmp); |
84 } | 84 } |
85 | 85 |
86 // Loads the custom spellcheck dictionary from |path| into |custom_words|. If | 86 // Loads the custom spellcheck dictionary from |path| into |custom_words|. If |
87 // the dictionary checksum is not valid, but backup checksum is valid, then | 87 // the dictionary checksum is not valid, but backup checksum is valid, then |
88 // restores the backup and loads that into |custom_words| instead. If the backup | 88 // restores the backup and loads that into |custom_words| instead. If the backup |
89 // is invalid too, then clears |custom_words|. Must be called on the file | 89 // is invalid too, then clears |custom_words|. Must be called on the file |
90 // thread. | 90 // thread. |
91 void LoadDictionaryFileReliably(WordList& custom_words, | 91 void LoadDictionaryFileReliably(WordList& custom_words, |
92 const base::FilePath& path) { | 92 const base::FilePath& path) { |
93 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 93 DCHECK_CURRENTLY_ON(BrowserThread::FILE); |
94 // Load the contents and verify the checksum. | 94 // Load the contents and verify the checksum. |
95 if (LoadFile(path, custom_words) == VALID_CHECKSUM) | 95 if (LoadFile(path, custom_words) == VALID_CHECKSUM) |
96 return; | 96 return; |
97 // Checksum is not valid. See if there's a backup. | 97 // Checksum is not valid. See if there's a backup. |
98 base::FilePath backup = path.AddExtension(BACKUP_EXTENSION); | 98 base::FilePath backup = path.AddExtension(BACKUP_EXTENSION); |
99 if (!base::PathExists(backup)) | 99 if (!base::PathExists(backup)) |
100 return; | 100 return; |
101 // Load the backup and verify its checksum. | 101 // Load the backup and verify its checksum. |
102 if (LoadFile(backup, custom_words) != VALID_CHECKSUM) | 102 if (LoadFile(backup, custom_words) != VALID_CHECKSUM) |
103 return; | 103 return; |
104 // Backup checksum is valid. Restore the backup. | 104 // Backup checksum is valid. Restore the backup. |
105 base::CopyFile(backup, path); | 105 base::CopyFile(backup, path); |
106 } | 106 } |
107 | 107 |
108 // Backs up the original dictionary, saves |custom_words| and its checksum into | 108 // Backs up the original dictionary, saves |custom_words| and its checksum into |
109 // the custom spellcheck dictionary at |path|. | 109 // the custom spellcheck dictionary at |path|. |
110 void SaveDictionaryFileReliably( | 110 void SaveDictionaryFileReliably( |
111 const WordList& custom_words, | 111 const WordList& custom_words, |
112 const base::FilePath& path) { | 112 const base::FilePath& path) { |
113 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 113 DCHECK_CURRENTLY_ON(BrowserThread::FILE); |
114 std::stringstream content; | 114 std::stringstream content; |
115 for (WordList::const_iterator it = custom_words.begin(); | 115 for (WordList::const_iterator it = custom_words.begin(); |
116 it != custom_words.end(); | 116 it != custom_words.end(); |
117 ++it) { | 117 ++it) { |
118 content << *it << '\n'; | 118 content << *it << '\n'; |
119 } | 119 } |
120 std::string checksum = base::MD5String(content.str()); | 120 std::string checksum = base::MD5String(content.str()); |
121 content << CHECKSUM_PREFIX << checksum; | 121 content << CHECKSUM_PREFIX << checksum; |
122 base::CopyFile(path, path.AddExtension(BACKUP_EXTENSION)); | 122 base::CopyFile(path, path.AddExtension(BACKUP_EXTENSION)); |
123 base::ImportantFileWriter::WriteFileAtomically(path, content.str()); | 123 base::ImportantFileWriter::WriteFileAtomically(path, content.str()); |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
221 is_loaded_(false), | 221 is_loaded_(false), |
222 weak_ptr_factory_(this) { | 222 weak_ptr_factory_(this) { |
223 custom_dictionary_path_ = | 223 custom_dictionary_path_ = |
224 path.Append(chrome::kCustomDictionaryFileName); | 224 path.Append(chrome::kCustomDictionaryFileName); |
225 } | 225 } |
226 | 226 |
227 SpellcheckCustomDictionary::~SpellcheckCustomDictionary() { | 227 SpellcheckCustomDictionary::~SpellcheckCustomDictionary() { |
228 } | 228 } |
229 | 229 |
230 const WordSet& SpellcheckCustomDictionary::GetWords() const { | 230 const WordSet& SpellcheckCustomDictionary::GetWords() const { |
231 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 231 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
232 return words_; | 232 return words_; |
233 } | 233 } |
234 | 234 |
235 bool SpellcheckCustomDictionary::AddWord(const std::string& word) { | 235 bool SpellcheckCustomDictionary::AddWord(const std::string& word) { |
236 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 236 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
237 Change dictionary_change; | 237 Change dictionary_change; |
238 dictionary_change.AddWord(word); | 238 dictionary_change.AddWord(word); |
239 int result = dictionary_change.Sanitize(GetWords()); | 239 int result = dictionary_change.Sanitize(GetWords()); |
240 Apply(dictionary_change); | 240 Apply(dictionary_change); |
241 Notify(dictionary_change); | 241 Notify(dictionary_change); |
242 Sync(dictionary_change); | 242 Sync(dictionary_change); |
243 Save(dictionary_change); | 243 Save(dictionary_change); |
244 return result == VALID_CHANGE; | 244 return result == VALID_CHANGE; |
245 } | 245 } |
246 | 246 |
247 bool SpellcheckCustomDictionary::RemoveWord(const std::string& word) { | 247 bool SpellcheckCustomDictionary::RemoveWord(const std::string& word) { |
248 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 248 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
249 Change dictionary_change; | 249 Change dictionary_change; |
250 dictionary_change.RemoveWord(word); | 250 dictionary_change.RemoveWord(word); |
251 int result = dictionary_change.Sanitize(GetWords()); | 251 int result = dictionary_change.Sanitize(GetWords()); |
252 Apply(dictionary_change); | 252 Apply(dictionary_change); |
253 Notify(dictionary_change); | 253 Notify(dictionary_change); |
254 Sync(dictionary_change); | 254 Sync(dictionary_change); |
255 Save(dictionary_change); | 255 Save(dictionary_change); |
256 return result == VALID_CHANGE; | 256 return result == VALID_CHANGE; |
257 } | 257 } |
258 | 258 |
259 bool SpellcheckCustomDictionary::HasWord(const std::string& word) const { | 259 bool SpellcheckCustomDictionary::HasWord(const std::string& word) const { |
260 return !!words_.count(word); | 260 return !!words_.count(word); |
261 } | 261 } |
262 | 262 |
263 void SpellcheckCustomDictionary::AddObserver(Observer* observer) { | 263 void SpellcheckCustomDictionary::AddObserver(Observer* observer) { |
264 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 264 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
265 observers_.AddObserver(observer); | 265 observers_.AddObserver(observer); |
266 } | 266 } |
267 | 267 |
268 void SpellcheckCustomDictionary::RemoveObserver(Observer* observer) { | 268 void SpellcheckCustomDictionary::RemoveObserver(Observer* observer) { |
269 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 269 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
270 observers_.RemoveObserver(observer); | 270 observers_.RemoveObserver(observer); |
271 } | 271 } |
272 | 272 |
273 bool SpellcheckCustomDictionary::IsLoaded() { | 273 bool SpellcheckCustomDictionary::IsLoaded() { |
274 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 274 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
275 return is_loaded_; | 275 return is_loaded_; |
276 } | 276 } |
277 | 277 |
278 bool SpellcheckCustomDictionary::IsSyncing() { | 278 bool SpellcheckCustomDictionary::IsSyncing() { |
279 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 279 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
280 return !!sync_processor_.get(); | 280 return !!sync_processor_.get(); |
281 } | 281 } |
282 | 282 |
283 void SpellcheckCustomDictionary::Load() { | 283 void SpellcheckCustomDictionary::Load() { |
284 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 284 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
285 BrowserThread::PostTaskAndReplyWithResult( | 285 BrowserThread::PostTaskAndReplyWithResult( |
286 BrowserThread::FILE, | 286 BrowserThread::FILE, |
287 FROM_HERE, | 287 FROM_HERE, |
288 base::Bind(&SpellcheckCustomDictionary::LoadDictionaryFile, | 288 base::Bind(&SpellcheckCustomDictionary::LoadDictionaryFile, |
289 custom_dictionary_path_), | 289 custom_dictionary_path_), |
290 base::Bind(&SpellcheckCustomDictionary::OnLoaded, | 290 base::Bind(&SpellcheckCustomDictionary::OnLoaded, |
291 weak_ptr_factory_.GetWeakPtr())); | 291 weak_ptr_factory_.GetWeakPtr())); |
292 } | 292 } |
293 | 293 |
294 syncer::SyncMergeResult SpellcheckCustomDictionary::MergeDataAndStartSyncing( | 294 syncer::SyncMergeResult SpellcheckCustomDictionary::MergeDataAndStartSyncing( |
295 syncer::ModelType type, | 295 syncer::ModelType type, |
296 const syncer::SyncDataList& initial_sync_data, | 296 const syncer::SyncDataList& initial_sync_data, |
297 scoped_ptr<syncer::SyncChangeProcessor> sync_processor, | 297 scoped_ptr<syncer::SyncChangeProcessor> sync_processor, |
298 scoped_ptr<syncer::SyncErrorFactory> sync_error_handler) { | 298 scoped_ptr<syncer::SyncErrorFactory> sync_error_handler) { |
299 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 299 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
300 DCHECK(!sync_processor_.get()); | 300 DCHECK(!sync_processor_.get()); |
301 DCHECK(!sync_error_handler_.get()); | 301 DCHECK(!sync_error_handler_.get()); |
302 DCHECK(sync_processor.get()); | 302 DCHECK(sync_processor.get()); |
303 DCHECK(sync_error_handler.get()); | 303 DCHECK(sync_error_handler.get()); |
304 DCHECK_EQ(syncer::DICTIONARY, type); | 304 DCHECK_EQ(syncer::DICTIONARY, type); |
305 sync_processor_ = sync_processor.Pass(); | 305 sync_processor_ = sync_processor.Pass(); |
306 sync_error_handler_ = sync_error_handler.Pass(); | 306 sync_error_handler_ = sync_error_handler.Pass(); |
307 | 307 |
308 // Build a list of words to add locally. | 308 // Build a list of words to add locally. |
309 WordList to_add_locally; | 309 WordList to_add_locally; |
(...skipping 17 matching lines...) Expand all Loading... |
327 to_add_locally); | 327 to_add_locally); |
328 | 328 |
329 // Send local changes to the sync server. | 329 // Send local changes to the sync server. |
330 Change to_change_remotely(to_add_remotely); | 330 Change to_change_remotely(to_add_remotely); |
331 syncer::SyncMergeResult result(type); | 331 syncer::SyncMergeResult result(type); |
332 result.set_error(Sync(to_change_remotely)); | 332 result.set_error(Sync(to_change_remotely)); |
333 return result; | 333 return result; |
334 } | 334 } |
335 | 335 |
336 void SpellcheckCustomDictionary::StopSyncing(syncer::ModelType type) { | 336 void SpellcheckCustomDictionary::StopSyncing(syncer::ModelType type) { |
337 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 337 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
338 DCHECK_EQ(syncer::DICTIONARY, type); | 338 DCHECK_EQ(syncer::DICTIONARY, type); |
339 sync_processor_.reset(); | 339 sync_processor_.reset(); |
340 sync_error_handler_.reset(); | 340 sync_error_handler_.reset(); |
341 } | 341 } |
342 | 342 |
343 syncer::SyncDataList SpellcheckCustomDictionary::GetAllSyncData( | 343 syncer::SyncDataList SpellcheckCustomDictionary::GetAllSyncData( |
344 syncer::ModelType type) const { | 344 syncer::ModelType type) const { |
345 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 345 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
346 DCHECK_EQ(syncer::DICTIONARY, type); | 346 DCHECK_EQ(syncer::DICTIONARY, type); |
347 syncer::SyncDataList data; | 347 syncer::SyncDataList data; |
348 std::string word; | 348 std::string word; |
349 size_t i = 0; | 349 size_t i = 0; |
350 for (WordSet::const_iterator it = words_.begin(); | 350 for (WordSet::const_iterator it = words_.begin(); |
351 it != words_.end() && | 351 it != words_.end() && |
352 i < chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS; | 352 i < chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS; |
353 ++it, ++i) { | 353 ++it, ++i) { |
354 word = *it; | 354 word = *it; |
355 sync_pb::EntitySpecifics specifics; | 355 sync_pb::EntitySpecifics specifics; |
356 specifics.mutable_dictionary()->set_word(word); | 356 specifics.mutable_dictionary()->set_word(word); |
357 data.push_back(syncer::SyncData::CreateLocalData(word, word, specifics)); | 357 data.push_back(syncer::SyncData::CreateLocalData(word, word, specifics)); |
358 } | 358 } |
359 return data; | 359 return data; |
360 } | 360 } |
361 | 361 |
362 syncer::SyncError SpellcheckCustomDictionary::ProcessSyncChanges( | 362 syncer::SyncError SpellcheckCustomDictionary::ProcessSyncChanges( |
363 const tracked_objects::Location& from_here, | 363 const tracked_objects::Location& from_here, |
364 const syncer::SyncChangeList& change_list) { | 364 const syncer::SyncChangeList& change_list) { |
365 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 365 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
366 Change dictionary_change; | 366 Change dictionary_change; |
367 for (syncer::SyncChangeList::const_iterator it = change_list.begin(); | 367 for (syncer::SyncChangeList::const_iterator it = change_list.begin(); |
368 it != change_list.end(); | 368 it != change_list.end(); |
369 ++it) { | 369 ++it) { |
370 DCHECK(it->IsValid()); | 370 DCHECK(it->IsValid()); |
371 std::string word = it->sync_data().GetSpecifics().dictionary().word(); | 371 std::string word = it->sync_data().GetSpecifics().dictionary().word(); |
372 switch (it->change_type()) { | 372 switch (it->change_type()) { |
373 case syncer::SyncChange::ACTION_ADD: | 373 case syncer::SyncChange::ACTION_ADD: |
374 dictionary_change.AddWord(word); | 374 dictionary_change.AddWord(word); |
375 break; | 375 break; |
(...skipping 12 matching lines...) Expand all Loading... |
388 Apply(dictionary_change); | 388 Apply(dictionary_change); |
389 Notify(dictionary_change); | 389 Notify(dictionary_change); |
390 Save(dictionary_change); | 390 Save(dictionary_change); |
391 | 391 |
392 return syncer::SyncError(); | 392 return syncer::SyncError(); |
393 } | 393 } |
394 | 394 |
395 // static | 395 // static |
396 WordList SpellcheckCustomDictionary::LoadDictionaryFile( | 396 WordList SpellcheckCustomDictionary::LoadDictionaryFile( |
397 const base::FilePath& path) { | 397 const base::FilePath& path) { |
398 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 398 DCHECK_CURRENTLY_ON(BrowserThread::FILE); |
399 WordList words; | 399 WordList words; |
400 LoadDictionaryFileReliably(words, path); | 400 LoadDictionaryFileReliably(words, path); |
401 if (!words.empty() && VALID_CHANGE != SanitizeWordsToAdd(WordSet(), words)) | 401 if (!words.empty() && VALID_CHANGE != SanitizeWordsToAdd(WordSet(), words)) |
402 SaveDictionaryFileReliably(words, path); | 402 SaveDictionaryFileReliably(words, path); |
403 SpellCheckHostMetrics::RecordCustomWordCountStats(words.size()); | 403 SpellCheckHostMetrics::RecordCustomWordCountStats(words.size()); |
404 return words; | 404 return words; |
405 } | 405 } |
406 | 406 |
407 // static | 407 // static |
408 void SpellcheckCustomDictionary::UpdateDictionaryFile( | 408 void SpellcheckCustomDictionary::UpdateDictionaryFile( |
409 const SpellcheckCustomDictionary::Change& dictionary_change, | 409 const SpellcheckCustomDictionary::Change& dictionary_change, |
410 const base::FilePath& path) { | 410 const base::FilePath& path) { |
411 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 411 DCHECK_CURRENTLY_ON(BrowserThread::FILE); |
412 if (dictionary_change.empty()) | 412 if (dictionary_change.empty()) |
413 return; | 413 return; |
414 | 414 |
415 WordList custom_words; | 415 WordList custom_words; |
416 LoadDictionaryFileReliably(custom_words, path); | 416 LoadDictionaryFileReliably(custom_words, path); |
417 | 417 |
418 // Add words. | 418 // Add words. |
419 custom_words.insert(custom_words.end(), | 419 custom_words.insert(custom_words.end(), |
420 dictionary_change.to_add().begin(), | 420 dictionary_change.to_add().begin(), |
421 dictionary_change.to_add().end()); | 421 dictionary_change.to_add().end()); |
422 | 422 |
423 // Remove words. | 423 // Remove words. |
424 std::sort(custom_words.begin(), custom_words.end()); | 424 std::sort(custom_words.begin(), custom_words.end()); |
425 WordList remaining = | 425 WordList remaining = |
426 base::STLSetDifference<WordList>(custom_words, | 426 base::STLSetDifference<WordList>(custom_words, |
427 dictionary_change.to_remove()); | 427 dictionary_change.to_remove()); |
428 std::swap(custom_words, remaining); | 428 std::swap(custom_words, remaining); |
429 | 429 |
430 SaveDictionaryFileReliably(custom_words, path); | 430 SaveDictionaryFileReliably(custom_words, path); |
431 } | 431 } |
432 | 432 |
433 void SpellcheckCustomDictionary::OnLoaded(WordList custom_words) { | 433 void SpellcheckCustomDictionary::OnLoaded(WordList custom_words) { |
434 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 434 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
435 Change dictionary_change(custom_words); | 435 Change dictionary_change(custom_words); |
436 dictionary_change.Sanitize(GetWords()); | 436 dictionary_change.Sanitize(GetWords()); |
437 Apply(dictionary_change); | 437 Apply(dictionary_change); |
438 Sync(dictionary_change); | 438 Sync(dictionary_change); |
439 is_loaded_ = true; | 439 is_loaded_ = true; |
440 FOR_EACH_OBSERVER(Observer, observers_, OnCustomDictionaryLoaded()); | 440 FOR_EACH_OBSERVER(Observer, observers_, OnCustomDictionaryLoaded()); |
441 } | 441 } |
442 | 442 |
443 void SpellcheckCustomDictionary::Apply( | 443 void SpellcheckCustomDictionary::Apply( |
444 const SpellcheckCustomDictionary::Change& dictionary_change) { | 444 const SpellcheckCustomDictionary::Change& dictionary_change) { |
445 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 445 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
446 if (!dictionary_change.to_add().empty()) { | 446 if (!dictionary_change.to_add().empty()) { |
447 words_.insert(dictionary_change.to_add().begin(), | 447 words_.insert(dictionary_change.to_add().begin(), |
448 dictionary_change.to_add().end()); | 448 dictionary_change.to_add().end()); |
449 } | 449 } |
450 if (!dictionary_change.to_remove().empty()) { | 450 if (!dictionary_change.to_remove().empty()) { |
451 WordSet updated_words = | 451 WordSet updated_words = |
452 base::STLSetDifference<WordSet>(words_, | 452 base::STLSetDifference<WordSet>(words_, |
453 dictionary_change.to_remove()); | 453 dictionary_change.to_remove()); |
454 std::swap(words_, updated_words); | 454 std::swap(words_, updated_words); |
455 } | 455 } |
456 } | 456 } |
457 | 457 |
458 void SpellcheckCustomDictionary::Save( | 458 void SpellcheckCustomDictionary::Save( |
459 const SpellcheckCustomDictionary::Change& dictionary_change) { | 459 const SpellcheckCustomDictionary::Change& dictionary_change) { |
460 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 460 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
461 BrowserThread::PostTask( | 461 BrowserThread::PostTask( |
462 BrowserThread::FILE, | 462 BrowserThread::FILE, |
463 FROM_HERE, | 463 FROM_HERE, |
464 base::Bind(&SpellcheckCustomDictionary::UpdateDictionaryFile, | 464 base::Bind(&SpellcheckCustomDictionary::UpdateDictionaryFile, |
465 dictionary_change, | 465 dictionary_change, |
466 custom_dictionary_path_)); | 466 custom_dictionary_path_)); |
467 } | 467 } |
468 | 468 |
469 syncer::SyncError SpellcheckCustomDictionary::Sync( | 469 syncer::SyncError SpellcheckCustomDictionary::Sync( |
470 const SpellcheckCustomDictionary::Change& dictionary_change) { | 470 const SpellcheckCustomDictionary::Change& dictionary_change) { |
471 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 471 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
472 syncer::SyncError error; | 472 syncer::SyncError error; |
473 if (!IsSyncing() || dictionary_change.empty()) | 473 if (!IsSyncing() || dictionary_change.empty()) |
474 return error; | 474 return error; |
475 | 475 |
476 // The number of words on the sync server should not exceed the limits. | 476 // The number of words on the sync server should not exceed the limits. |
477 int server_size = static_cast<int>(words_.size()) - | 477 int server_size = static_cast<int>(words_.size()) - |
478 static_cast<int>(dictionary_change.to_add().size()); | 478 static_cast<int>(dictionary_change.to_add().size()); |
479 int max_upload_size = std::max( | 479 int max_upload_size = std::max( |
480 0, | 480 0, |
481 static_cast<int>( | 481 static_cast<int>( |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
520 // Turn off syncing of this dictionary if the server already has the maximum | 520 // Turn off syncing of this dictionary if the server already has the maximum |
521 // number of words. | 521 // number of words. |
522 if (words_.size() > chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS) | 522 if (words_.size() > chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS) |
523 StopSyncing(syncer::DICTIONARY); | 523 StopSyncing(syncer::DICTIONARY); |
524 | 524 |
525 return error; | 525 return error; |
526 } | 526 } |
527 | 527 |
528 void SpellcheckCustomDictionary::Notify( | 528 void SpellcheckCustomDictionary::Notify( |
529 const SpellcheckCustomDictionary::Change& dictionary_change) { | 529 const SpellcheckCustomDictionary::Change& dictionary_change) { |
530 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 530 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
531 if (!IsLoaded() || dictionary_change.empty()) | 531 if (!IsLoaded() || dictionary_change.empty()) |
532 return; | 532 return; |
533 FOR_EACH_OBSERVER(Observer, | 533 FOR_EACH_OBSERVER(Observer, |
534 observers_, | 534 observers_, |
535 OnCustomDictionaryChanged(dictionary_change)); | 535 OnCustomDictionaryChanged(dictionary_change)); |
536 } | 536 } |
OLD | NEW |