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
3 // found in the LICENSE file.
5 #ifndef CHROME_BROWSER_SPELLCHECKER_SPELLCHECK_CUSTOM_DICTIONARY_H_
6 #define CHROME_BROWSER_SPELLCHECKER_SPELLCHECK_CUSTOM_DICTIONARY_H_
11 #include "base/files/file_path.h"
12 #include "base/macros.h"
13 #include "base/memory/scoped_ptr.h"
14 #include "base/memory/weak_ptr.h"
15 #include "base/observer_list.h"
16 #include "chrome/browser/spellchecker/spellcheck_dictionary.h"
17 #include "sync/api/sync_data.h"
18 #include "sync/api/sync_error.h"
19 #include "sync/api/sync_merge_result.h"
20 #include "sync/api/syncable_service.h"
23 class SyncErrorFactory
;
24 class SyncChangeProcessor
;
27 namespace tracked_objects
{
31 // Defines a custom dictionary where users can add their own words. All words
32 // must be UTF8, between 1 and 99 bytes long, and without leading or trailing
33 // ASCII whitespace. The dictionary contains its own checksum when saved on
34 // disk. Example dictionary file contents:
38 // checksum_v1 = ec3df4034567e59e119fcf87f2d9bad4
40 class SpellcheckCustomDictionary
: public SpellcheckDictionary
,
41 public syncer::SyncableService
{
43 // A change to the dictionary.
49 // Adds |word| in this change.
50 void AddWord(const std::string
& word
);
52 // Adds |words| in this change.
53 void AddWords(const std::set
<std::string
>& words
);
55 // Removes |word| in this change.
56 void RemoveWord(const std::string
& word
);
58 // Prepares this change to be applied to |words| by removing duplicate and
59 // invalid words from words to be added and removing missing words from
60 // words to be removed. Returns a bitmap of |ChangeSanitationResult| values.
61 int Sanitize(const std::set
<std::string
>& words
);
63 // Returns the words to be added in this change.
64 const std::set
<std::string
>& to_add() const { return to_add_
; }
66 // Returns the words to be removed in this change.
67 const std::set
<std::string
>& to_remove() const {
71 // Returns true if there are no changes to be made. Otherwise returns false.
72 bool empty() const { return to_add_
.empty() && to_remove_
.empty(); }
75 // The words to be added.
76 std::set
<std::string
> to_add_
;
78 // The words to be removed.
79 std::set
<std::string
> to_remove_
;
81 DISALLOW_COPY_AND_ASSIGN(Change
);
84 // Interface to implement for dictionary load and change observers.
87 // Called when the custom dictionary has been loaded.
88 virtual void OnCustomDictionaryLoaded() = 0;
90 // Called when the custom dictionary has been changed.
91 virtual void OnCustomDictionaryChanged(const Change
& dictionary_change
) = 0;
94 // The dictionary will be saved in |dictionary_directory_name|.
95 explicit SpellcheckCustomDictionary(
96 const base::FilePath
& dictionary_directory_name
);
97 ~SpellcheckCustomDictionary() override
;
99 // Returns the in-memory cache of words in the custom dictionary.
100 const std::set
<std::string
>& GetWords() const;
102 // Adds |word| to the dictionary, schedules a write to disk, and notifies
103 // observers of the change. Returns true if |word| is valid and not a
104 // duplicate. Otherwise returns false.
105 bool AddWord(const std::string
& word
);
107 // Removes |word| from the dictionary, schedules a write to disk, and notifies
108 // observers of the change. Returns true if |word| was found. Otherwise
110 bool RemoveWord(const std::string
& word
);
112 // Returns true if the dictionary contains |word|. Otherwise returns false.
113 bool HasWord(const std::string
& word
) const;
115 // Adds |observer| to be notified of dictionary events and changes.
116 void AddObserver(Observer
* observer
);
118 // Removes |observer| to stop notifications of dictionary events and changes.
119 void RemoveObserver(Observer
* observer
);
121 // Returns true if the dictionary has been loaded. Otherwise returns false.
124 // Returns true if the dictionary is being synced. Otherwise returns false.
127 // Overridden from SpellcheckDictionary:
128 void Load() override
;
130 // Overridden from syncer::SyncableService:
131 syncer::SyncMergeResult
MergeDataAndStartSyncing(
132 syncer::ModelType type
,
133 const syncer::SyncDataList
& initial_sync_data
,
134 scoped_ptr
<syncer::SyncChangeProcessor
> sync_processor
,
135 scoped_ptr
<syncer::SyncErrorFactory
> sync_error_handler
) override
;
136 void StopSyncing(syncer::ModelType type
) override
;
137 syncer::SyncDataList
GetAllSyncData(syncer::ModelType type
) const override
;
138 syncer::SyncError
ProcessSyncChanges(
139 const tracked_objects::Location
& from_here
,
140 const syncer::SyncChangeList
& change_list
) override
;
143 friend class DictionarySyncIntegrationTestHelper
;
144 friend class SpellcheckCustomDictionaryTest
;
146 // Returns the list of words in the custom spellcheck dictionary at |path|.
147 // Makes sure that the custom dictionary file does not have duplicates and
148 // contains only valid words. Must be called on the FILE thread. The caller
150 static scoped_ptr
<std::set
<std::string
>> LoadDictionaryFile(
151 const base::FilePath
& path
);
153 // Applies the change in |dictionary_change| to the custom spellcheck
154 // dictionary. Assumes that |dictionary_change| has been sanitized. Must be
155 // called on the FILE thread. Takes ownership of |dictionary_change|.
156 static void UpdateDictionaryFile(scoped_ptr
<Change
> dictionary_change
,
157 const base::FilePath
& path
);
159 // The reply point for PostTaskAndReplyWithResult, called when
160 // LoadDictionaryFile finishes reading the dictionary file. Takes ownership of
162 void OnLoaded(scoped_ptr
<std::set
<std::string
>> custom_words
);
164 // Applies the |dictionary_change| to the in-memory copy of the dictionary.
165 void Apply(const Change
& dictionary_change
);
167 // Schedules a write of |dictionary_change| to disk. Takes ownership of
168 // |dictionary_change| to pass it to the FILE thread.
169 void Save(scoped_ptr
<Change
> dictionary_change
);
171 // Notifies the sync service of the |dictionary_change|. Syncs up to the
172 // maximum syncable words on the server. Disables syncing of this dictionary
173 // if the server contains the maximum number of syncable words.
174 syncer::SyncError
Sync(const Change
& dictionary_change
);
176 // Notifies observers of the dictionary change if the dictionary has been
178 void Notify(const Change
& dictionary_change
);
180 // In-memory cache of the custom words file.
181 std::set
<std::string
> words_
;
183 // The path to the custom dictionary file.
184 base::FilePath custom_dictionary_path_
;
186 // Observers for dictionary load and content changes.
187 base::ObserverList
<Observer
> observers_
;
189 // Used to send local changes to the sync infrastructure.
190 scoped_ptr
<syncer::SyncChangeProcessor
> sync_processor_
;
192 // Used to send sync-related errors to the sync infrastructure.
193 scoped_ptr
<syncer::SyncErrorFactory
> sync_error_handler_
;
195 // True if the dictionary has been loaded. Otherwise false.
198 // Used to create weak pointers for an instance of this class.
199 base::WeakPtrFactory
<SpellcheckCustomDictionary
> weak_ptr_factory_
;
201 DISALLOW_COPY_AND_ASSIGN(SpellcheckCustomDictionary
);
204 #endif // CHROME_BROWSER_SPELLCHECKER_SPELLCHECK_CUSTOM_DICTIONARY_H_