1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
|
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_SPELLCHECKER_SPELLCHECK_CUSTOM_DICTIONARY_H_
#define CHROME_BROWSER_SPELLCHECKER_SPELLCHECK_CUSTOM_DICTIONARY_H_
#include <string>
#include "base/files/file_path.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "chrome/browser/spellchecker/spellcheck_dictionary.h"
#include "chrome/common/spellcheck_common.h"
#include "sync/api/syncable_service.h"
// Defines a custom dictionary where users can add their own words. All words
// must be UTF8, between 1 and 99 bytes long, and without leading or trailing
// ASCII whitespace. The dictionary contains its own checksum when saved on
// disk. Example dictionary file contents:
//
// bar
// foo
// checksum_v1 = ec3df4034567e59e119fcf87f2d9bad4
//
class SpellcheckCustomDictionary : public SpellcheckDictionary,
public syncer::SyncableService {
public:
// A change to the dictionary.
class Change {
public:
Change();
Change(const Change& other);
explicit Change(const chrome::spellcheck_common::WordList& to_add);
~Change();
// Adds |word| in this change.
void AddWord(const std::string& word);
// Removes |word| in this change.
void RemoveWord(const std::string& word);
// Prepares this change to be applied to |words| by removing duplicate and
// invalid words from words to be added, removing missing words from words
// to be removed, and sorting both lists of words. Assumes that |words| is
// sorted. Returns a bitmap of |ChangeSanitationResult| values.
int Sanitize(const chrome::spellcheck_common::WordSet& words);
// Returns the words to be added in this change.
const chrome::spellcheck_common::WordList& to_add() const;
// Returns the words to be removed in this change.
const chrome::spellcheck_common::WordList& to_remove() const;
// Returns true if there are no changes to be made. Otherwise returns false.
bool empty() const;
private:
// The words to be added.
chrome::spellcheck_common::WordList to_add_;
// The words to be removed.
chrome::spellcheck_common::WordList to_remove_;
};
// Interface to implement for dictionary load and change observers.
class Observer {
public:
// Called when the custom dictionary has been loaded.
virtual void OnCustomDictionaryLoaded() = 0;
// Called when the custom dictionary has been changed.
virtual void OnCustomDictionaryChanged(const Change& dictionary_change) = 0;
};
explicit SpellcheckCustomDictionary(const base::FilePath& path);
virtual ~SpellcheckCustomDictionary();
// Returns the in-memory cache of words in the custom dictionary.
const chrome::spellcheck_common::WordSet& GetWords() const;
// Adds |word| to the dictionary, schedules a write to disk, and notifies
// observers of the change. Returns true if |word| is valid and not a
// duplicate. Otherwise returns false.
bool AddWord(const std::string& word);
// Removes |word| from the dictionary, schedules a write to disk, and notifies
// observers of the change. Returns true if |word| was found. Otherwise
// returns false.
bool RemoveWord(const std::string& word);
// Returns true if the dictionary contains |word|. Otherwise returns false.
bool HasWord(const std::string& word) const;
// Adds |observer| to be notified of dictionary events and changes.
void AddObserver(Observer* observer);
// Removes |observer| to stop notifications of dictionary events and changes.
void RemoveObserver(Observer* observer);
// Returns true if the dictionary has been loaded. Otherwise returns false.
bool IsLoaded();
// Returns true if the dictionary is being synced. Otherwise returns false.
bool IsSyncing();
// Overridden from SpellcheckDictionary:
virtual void Load() OVERRIDE;
// Overridden from syncer::SyncableService:
virtual syncer::SyncMergeResult MergeDataAndStartSyncing(
syncer::ModelType type,
const syncer::SyncDataList& initial_sync_data,
scoped_ptr<syncer::SyncChangeProcessor> sync_processor,
scoped_ptr<syncer::SyncErrorFactory> sync_error_handler) OVERRIDE;
virtual void StopSyncing(syncer::ModelType type) OVERRIDE;
virtual syncer::SyncDataList GetAllSyncData(
syncer::ModelType type) const OVERRIDE;
virtual syncer::SyncError ProcessSyncChanges(
const tracked_objects::Location& from_here,
const syncer::SyncChangeList& change_list) OVERRIDE;
private:
friend class DictionarySyncIntegrationTestHelper;
friend class SpellcheckCustomDictionaryTest;
// Returns the list of words in the custom spellcheck dictionary at |path|.
// Makes sure that the custom dictionary file does not have duplicates and
// contains only valid words.
static chrome::spellcheck_common::WordList LoadDictionaryFile(
const base::FilePath& path);
// Applies the change in |dictionary_change| to the custom spellcheck
// dictionary. Assumes that |dictionary_change| has been sanitized.
static void UpdateDictionaryFile(
const Change& dictionary_change,
const base::FilePath& path);
// The reply point for PostTaskAndReplyWithResult, called when
// LoadDictionaryFile finishes reading the dictionary file. Does not modify
// |custom_words|, but cannot be a const-ref due to the signature of
// PostTaskAndReplyWithResult.
void OnLoaded(chrome::spellcheck_common::WordList custom_words);
// Applies the |dictionary_change| to the in-memory copy of the dictionary.
// Assumes that words in |dictionary_change| are sorted.
void Apply(const Change& dictionary_change);
// Schedules a write of |dictionary_change| to disk. Assumes that words in
// |dictionary_change| are sorted.
void Save(const Change& dictionary_change);
// Notifies the sync service of the |dictionary_change|. Syncs up to the
// maximum syncable words on the server. Disables syncing of this dictionary
// if the server contains the maximum number of syncable words.
syncer::SyncError Sync(const Change& dictionary_change);
// Notifies observers of the dictionary change if the dictionary has been
// changed.
void Notify(const Change& dictionary_change);
// In-memory cache of the custom words file.
chrome::spellcheck_common::WordSet words_;
// A path for custom dictionary.
base::FilePath custom_dictionary_path_;
// Observers for changes in dictionary load status and content changes.
ObserverList<Observer> observers_;
// Used to send local changes to the sync infrastructure.
scoped_ptr<syncer::SyncChangeProcessor> sync_processor_;
// Used to send sync-related errors to the sync infrastructure.
scoped_ptr<syncer::SyncErrorFactory> sync_error_handler_;
// True if the dictionary has been loaded. Otherwise false.
bool is_loaded_;
// Used to create weak pointers for an instance of this class.
base::WeakPtrFactory<SpellcheckCustomDictionary> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(SpellcheckCustomDictionary);
};
#endif // CHROME_BROWSER_SPELLCHECKER_SPELLCHECK_CUSTOM_DICTIONARY_H_
|