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