Home | History | Annotate | Download | only in spellchecker
      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.
      4 
      5 #ifndef CHROME_BROWSER_SPELLCHECKER_SPELLCHECK_CUSTOM_DICTIONARY_H_
      6 #define CHROME_BROWSER_SPELLCHECKER_SPELLCHECK_CUSTOM_DICTIONARY_H_
      7 
      8 #include <string>
      9 
     10 #include "base/files/file_path.h"
     11 #include "base/memory/scoped_ptr.h"
     12 #include "base/memory/weak_ptr.h"
     13 #include "base/observer_list.h"
     14 #include "chrome/browser/spellchecker/spellcheck_dictionary.h"
     15 #include "chrome/common/spellcheck_common.h"
     16 #include "sync/api/syncable_service.h"
     17 
     18 // Defines a custom dictionary where users can add their own words. All words
     19 // must be UTF8, between 1 and 99 bytes long, and without leading or trailing
     20 // ASCII whitespace. The dictionary contains its own checksum when saved on
     21 // disk. Example dictionary file contents:
     22 //
     23 //   bar
     24 //   foo
     25 //   checksum_v1 = ec3df4034567e59e119fcf87f2d9bad4
     26 //
     27 class SpellcheckCustomDictionary : public SpellcheckDictionary,
     28                                    public syncer::SyncableService {
     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::WordSet& 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.
     68   class Observer {
     69    public:
     70     // Called when the custom dictionary has been loaded.
     71     virtual void OnCustomDictionaryLoaded() = 0;
     72 
     73     // Called when the custom dictionary has been changed.
     74     virtual void OnCustomDictionaryChanged(const Change& dictionary_change) = 0;
     75   };
     76 
     77   explicit SpellcheckCustomDictionary(const base::FilePath& path);
     78   virtual ~SpellcheckCustomDictionary();
     79 
     80   // Returns the in-memory cache of words in the custom dictionary.
     81   const chrome::spellcheck_common::WordSet& 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   // Returns true if the dictionary contains |word|. Otherwise returns false.
     94   bool HasWord(const std::string& word) const;
     95 
     96   // Adds |observer| to be notified of dictionary events and changes.
     97   void AddObserver(Observer* observer);
     98 
     99   // Removes |observer| to stop notifications of dictionary events and changes.
    100   void RemoveObserver(Observer* observer);
    101 
    102   // Returns true if the dictionary has been loaded. Otherwise returns false.
    103   bool IsLoaded();
    104 
    105   // Returns true if the dictionary is being synced. Otherwise returns false.
    106   bool IsSyncing();
    107 
    108   // Overridden from SpellcheckDictionary:
    109   virtual void Load() OVERRIDE;
    110 
    111   // Overridden from syncer::SyncableService:
    112   virtual syncer::SyncMergeResult MergeDataAndStartSyncing(
    113       syncer::ModelType type,
    114       const syncer::SyncDataList& initial_sync_data,
    115       scoped_ptr<syncer::SyncChangeProcessor> sync_processor,
    116       scoped_ptr<syncer::SyncErrorFactory> sync_error_handler) OVERRIDE;
    117   virtual void StopSyncing(syncer::ModelType type) OVERRIDE;
    118   virtual syncer::SyncDataList GetAllSyncData(
    119       syncer::ModelType type) const OVERRIDE;
    120   virtual syncer::SyncError ProcessSyncChanges(
    121       const tracked_objects::Location& from_here,
    122       const syncer::SyncChangeList& change_list) OVERRIDE;
    123 
    124  private:
    125   friend class DictionarySyncIntegrationTestHelper;
    126   friend class SpellcheckCustomDictionaryTest;
    127 
    128   // Returns the list of words in the custom spellcheck dictionary at |path|.
    129   // Makes sure that the custom dictionary file does not have duplicates and
    130   // contains only valid words.
    131   static chrome::spellcheck_common::WordList LoadDictionaryFile(
    132       const base::FilePath& path);
    133 
    134   // Applies the change in |dictionary_change| to the custom spellcheck
    135   // dictionary. Assumes that |dictionary_change| has been sanitized.
    136   static void UpdateDictionaryFile(
    137       const Change& dictionary_change,
    138       const base::FilePath& path);
    139 
    140   // The reply point for PostTaskAndReplyWithResult, called when
    141   // LoadDictionaryFile finishes reading the dictionary file. Does not modify
    142   // |custom_words|, but cannot be a const-ref due to the signature of
    143   // PostTaskAndReplyWithResult.
    144   void OnLoaded(chrome::spellcheck_common::WordList custom_words);
    145 
    146   // Applies the |dictionary_change| to the in-memory copy of the dictionary.
    147   // Assumes that words in |dictionary_change| are sorted.
    148   void Apply(const Change& dictionary_change);
    149 
    150   // Schedules a write of |dictionary_change| to disk. Assumes that words in
    151   // |dictionary_change| are sorted.
    152   void Save(const Change& dictionary_change);
    153 
    154   // Notifies the sync service of the |dictionary_change|. Syncs up to the
    155   // maximum syncable words on the server. Disables syncing of this dictionary
    156   // if the server contains the maximum number of syncable words.
    157   syncer::SyncError Sync(const Change& dictionary_change);
    158 
    159   // Notifies observers of the dictionary change if the dictionary has been
    160   // changed.
    161   void Notify(const Change& dictionary_change);
    162 
    163   // In-memory cache of the custom words file.
    164   chrome::spellcheck_common::WordSet words_;
    165 
    166   // A path for custom dictionary.
    167   base::FilePath custom_dictionary_path_;
    168 
    169   // Used to create weak pointers for an instance of this class.
    170   base::WeakPtrFactory<SpellcheckCustomDictionary> weak_ptr_factory_;
    171 
    172   // Observers for changes in dictionary load status and content changes.
    173   ObserverList<Observer> observers_;
    174 
    175   // Used to send local changes to the sync infrastructure.
    176   scoped_ptr<syncer::SyncChangeProcessor> sync_processor_;
    177 
    178   // Used to send sync-related errors to the sync infrastructure.
    179   scoped_ptr<syncer::SyncErrorFactory> sync_error_handler_;
    180 
    181   // True if the dictionary has been loaded. Otherwise false.
    182   bool is_loaded_;
    183 
    184   DISALLOW_COPY_AND_ASSIGN(SpellcheckCustomDictionary);
    185 };
    186 
    187 #endif  // CHROME_BROWSER_SPELLCHECKER_SPELLCHECK_CUSTOM_DICTIONARY_H_
    188