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 |