| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2006-2009 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_H_ | |
| 6 #define CHROME_BROWSER_SPELLCHECKER_H_ | |
| 7 | |
| 8 #include <queue> | |
| 9 #include <string> | |
| 10 #include <vector> | |
| 11 | |
| 12 #include "app/l10n_util.h" | |
| 13 #include "base/string16.h" | |
| 14 #include "base/task.h" | |
| 15 #include "base/time.h" | |
| 16 #include "chrome/browser/chrome_thread.h" | |
| 17 #include "chrome/browser/net/url_fetcher.h" | |
| 18 #include "chrome/browser/profile.h" | |
| 19 #include "chrome/browser/spellcheck_worditerator.h" | |
| 20 #include "chrome/common/pref_names.h" | |
| 21 #include "chrome/common/pref_member.h" | |
| 22 #include "unicode/uscript.h" | |
| 23 | |
| 24 class FilePath; | |
| 25 class Hunspell; | |
| 26 class PrefService; | |
| 27 class Profile; | |
| 28 class URLFetcher; | |
| 29 class URLRequestContextGetter; | |
| 30 | |
| 31 namespace file_util { | |
| 32 class MemoryMappedFile; | |
| 33 } | |
| 34 | |
| 35 // The Browser's Spell Checker. It checks and suggests corrections. | |
| 36 // | |
| 37 // This object is not threadsafe. In normal usage (not unit tests) it lives on | |
| 38 // the I/O thread of the browser. It is threadsafe refcounted so that I/O thread | |
| 39 // and the profile on the main thread (which gives out references to it) can | |
| 40 // keep it. However, all usage of this must be on the I/O thread. | |
| 41 // | |
| 42 // This object should also be deleted on the I/O thread only. It owns a | |
| 43 // reference to URLRequestContext which in turn owns the cache, etc. and must be | |
| 44 // deleted on the I/O thread itself. | |
| 45 class SpellChecker | |
| 46 : public base::RefCountedThreadSafe< | |
| 47 SpellChecker, ChromeThread::DeleteOnIOThread>, | |
| 48 public URLFetcher::Delegate { | |
| 49 public: | |
| 50 // Creates the spellchecker by reading dictionaries from the given directory, | |
| 51 // and defaulting to the given language. Both strings must be provided. | |
| 52 // | |
| 53 // The request context is used to download dictionaries if they do not exist. | |
| 54 // This can be NULL if you don't want this (like in tests). | |
| 55 // The |custom_dictionary_file_name| should be left blank so that Spellchecker | |
| 56 // can figure out the custom dictionary file. It is non empty only for unit | |
| 57 // testing. | |
| 58 SpellChecker(const FilePath& dict_dir, | |
| 59 const std::string& language, | |
| 60 URLRequestContextGetter* request_context_getter, | |
| 61 const FilePath& custom_dictionary_file_name); | |
| 62 | |
| 63 // SpellCheck a word. | |
| 64 // Returns true if spelled correctly, false otherwise. | |
| 65 // If the spellchecker failed to initialize, always returns true. | |
| 66 // The |tag| parameter should either be a unique identifier for the document | |
| 67 // that the word came from (if the current platform requires it), or 0. | |
| 68 // In addition, finds the suggested words for a given word | |
| 69 // and puts them into |*optional_suggestions|. | |
| 70 // If the word is spelled correctly, the vector is empty. | |
| 71 // If optional_suggestions is NULL, suggested words will not be looked up. | |
| 72 // Note that Doing suggest lookups can be slow. | |
| 73 bool SpellCheckWord(const char16* in_word, | |
| 74 int in_word_len, | |
| 75 int tag, | |
| 76 int* misspelling_start, | |
| 77 int* misspelling_len, | |
| 78 std::vector<string16>* optional_suggestions); | |
| 79 | |
| 80 // Find a possible correctly spelled word for a misspelled word. Computes an | |
| 81 // empty string if input misspelled word is too long, there is ambiguity, or | |
| 82 // the correct spelling cannot be determined. | |
| 83 string16 GetAutoCorrectionWord(const string16& word, int tag); | |
| 84 | |
| 85 // Turn auto spell correct support ON or OFF. | |
| 86 // |turn_on| = true means turn ON; false means turn OFF. | |
| 87 void EnableAutoSpellCorrect(bool turn_on); | |
| 88 | |
| 89 // Add custom word to the dictionary, which means: | |
| 90 // a) Add it to the current hunspell object for immediate use, | |
| 91 // b) Add the word to a file in disk for custom dictionary. | |
| 92 void AddWord(const string16& word); | |
| 93 | |
| 94 // Get SpellChecker supported languages. | |
| 95 static void SpellCheckLanguages(std::vector<std::string>* languages); | |
| 96 | |
| 97 // This function computes a vector of strings which are to be displayed in | |
| 98 // the context menu over a text area for changing spell check languages. It | |
| 99 // returns the index of the current spell check language in the vector. | |
| 100 // TODO(port): this should take a vector of string16, but the implementation | |
| 101 // has some dependencies in l10n util that need porting first. | |
| 102 static int GetSpellCheckLanguages( | |
| 103 Profile* profile, | |
| 104 std::vector<std::string>* languages); | |
| 105 | |
| 106 // This function returns the corresponding language-region code for the | |
| 107 // spell check language. For example, for hi, it returns hi-IN. | |
| 108 static std::string GetSpellCheckLanguageRegion(std::string input_language); | |
| 109 | |
| 110 // This function returns ll (language code) from ll-RR where 'RR' (region | |
| 111 // code) is redundant. However, if the region code matters, it's preserved. | |
| 112 // That is, it returns 'hi' and 'en-GB' for 'hi-IN' and 'en-GB' respectively. | |
| 113 static std::string GetLanguageFromLanguageRegion(std::string input_language); | |
| 114 | |
| 115 private: | |
| 116 friend class ChromeThread; | |
| 117 friend class DeleteTask<SpellChecker>; | |
| 118 friend class ReadDictionaryTask; | |
| 119 FRIEND_TEST(SpellCheckTest, SpellCheckStrings_EN_US); | |
| 120 FRIEND_TEST(SpellCheckTest, SpellCheckSuggestions_EN_US); | |
| 121 FRIEND_TEST(SpellCheckTest, SpellCheckText); | |
| 122 FRIEND_TEST(SpellCheckTest, DISABLED_SpellCheckAddToDictionary_EN_US); | |
| 123 FRIEND_TEST(SpellCheckTest, | |
| 124 DISABLED_SpellCheckSuggestionsAddToDictionary_EN_US); | |
| 125 FRIEND_TEST(SpellCheckTest, GetAutoCorrectionWord_EN_US); | |
| 126 FRIEND_TEST(SpellCheckTest, IgnoreWords_EN_US); | |
| 127 | |
| 128 // Only delete on the I/O thread (see above). | |
| 129 ~SpellChecker(); | |
| 130 | |
| 131 // URLFetcher::Delegate implementation. Called when we finish downloading the | |
| 132 // spellcheck dictionary; saves the dictionary to disk. | |
| 133 virtual void OnURLFetchComplete(const URLFetcher* source, | |
| 134 const GURL& url, | |
| 135 const URLRequestStatus& status, | |
| 136 int response_code, | |
| 137 const ResponseCookies& cookies, | |
| 138 const std::string& data); | |
| 139 | |
| 140 // When called, relays the request to check the spelling to the proper | |
| 141 // backend, either hunspell or a platform-specific backend. | |
| 142 bool CheckSpelling(const string16& word_to_check, int tag); | |
| 143 | |
| 144 // When called, relays the request to fill the list with suggestions to | |
| 145 // the proper backend, either hunspell or a platform-specific backend. | |
| 146 void FillSuggestionList(const string16& wrong_word, | |
| 147 std::vector<string16>* optional_suggestions); | |
| 148 | |
| 149 // Initializes the Hunspell Dictionary. | |
| 150 bool Initialize(); | |
| 151 | |
| 152 // Called when |hunspell| is done loading, succesfully or not. If |hunspell| | |
| 153 // and |bdict_file| are non-NULL, assume ownership. | |
| 154 void HunspellInited(Hunspell* hunspell, | |
| 155 file_util::MemoryMappedFile* bdict_file, | |
| 156 bool file_existed); | |
| 157 | |
| 158 // Either start downloading a dictionary if we have not already, or do nothing | |
| 159 // if we have already tried to download one. | |
| 160 void DoDictionaryDownload(); | |
| 161 | |
| 162 // Returns whether or not the given word is a contraction of valid words | |
| 163 // (e.g. "word:word"). | |
| 164 bool IsValidContraction(const string16& word, int tag); | |
| 165 | |
| 166 // Return the file name of the dictionary, including the path and the version | |
| 167 // numbers. | |
| 168 FilePath GetVersionedFileName(const std::string& language, | |
| 169 const FilePath& dict_dir); | |
| 170 | |
| 171 static std::string GetCorrespondingSpellCheckLanguage( | |
| 172 const std::string& language); | |
| 173 | |
| 174 // Start downloading a dictionary from the server. On completion, the | |
| 175 // OnURLFetchComplete() function is invoked. | |
| 176 void StartDictionaryDownload(const FilePath& file_name); | |
| 177 | |
| 178 // This method is called in the IO thread after dictionary download has | |
| 179 // completed in FILE thread. | |
| 180 void OnDictionarySaveComplete(); | |
| 181 | |
| 182 // The given path to the directory whether SpellChecker first tries to | |
| 183 // download the spellcheck bdic dictionary file. | |
| 184 FilePath given_dictionary_directory_; | |
| 185 | |
| 186 // Path to the custom dictionary file. | |
| 187 FilePath custom_dictionary_file_name_; | |
| 188 | |
| 189 // BDIC file name (e.g. en-US_1_1.bdic). | |
| 190 FilePath bdic_file_name_; | |
| 191 | |
| 192 // We memory-map the BDict file. | |
| 193 scoped_ptr<file_util::MemoryMappedFile> bdict_file_; | |
| 194 | |
| 195 // The hunspell dictionary in use. | |
| 196 scoped_ptr<Hunspell> hunspell_; | |
| 197 | |
| 198 // Represents character attributes used for filtering out characters which | |
| 199 // are not supported by this SpellChecker object. | |
| 200 SpellcheckCharAttribute character_attributes_; | |
| 201 | |
| 202 // Flag indicating whether we've tried to initialize. If we've already | |
| 203 // attempted initialiation, we won't retry to avoid failure loops. | |
| 204 bool tried_to_init_; | |
| 205 | |
| 206 // The language that this spellchecker works in. | |
| 207 std::string language_; | |
| 208 | |
| 209 // This object must only be used on the same thread. However, it is normally | |
| 210 // created on the UI thread. This checks calls to SpellCheckWord and the | |
| 211 // destructor to make sure we're only ever running on the same thread. | |
| 212 // | |
| 213 // This will be NULL if it is not initialized yet (not initialized in the | |
| 214 // constructor since that's on a different thread). | |
| 215 MessageLoop* worker_loop_; | |
| 216 | |
| 217 // Flag indicating whether we tried to download the dictionary file. | |
| 218 bool tried_to_download_dictionary_file_; | |
| 219 | |
| 220 // Used for requests. MAY BE NULL which means don't try to download. | |
| 221 URLRequestContextGetter* request_context_getter_; | |
| 222 | |
| 223 // True when we're downloading or saving a dictionary. | |
| 224 bool obtaining_dictionary_; | |
| 225 | |
| 226 // Remember state for auto spell correct. | |
| 227 bool auto_spell_correct_turned_on_; | |
| 228 | |
| 229 // True if a platform-specific spellchecking engine is being used, | |
| 230 // and False if hunspell is being used. | |
| 231 bool is_using_platform_spelling_engine_; | |
| 232 | |
| 233 // URLFetcher to download a file in memory. | |
| 234 scoped_ptr<URLFetcher> fetcher_; | |
| 235 | |
| 236 // While Hunspell is loading, we add any new custom words to this queue. | |
| 237 // We will add them to |hunspell_| when it is done loading. | |
| 238 std::queue<std::string> custom_words_; | |
| 239 | |
| 240 // Used for generating callbacks to spellchecker, since spellchecker is a | |
| 241 // non-reference counted object. | |
| 242 ScopedRunnableMethodFactory<SpellChecker> method_factory_; | |
| 243 | |
| 244 DISALLOW_COPY_AND_ASSIGN(SpellChecker); | |
| 245 }; | |
| 246 | |
| 247 #endif // CHROME_BROWSER_SPELLCHECKER_H_ | |
| OLD | NEW |