Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(201)

Side by Side Diff: chrome/browser/spellchecker/spellchecker_mac.mm

Issue 8883040: [Mac] Ignore spell-checker exceptions. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: s/Calls/Executes/. Created 9 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « base/mac/scoped_nsexception_enabler.mm ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 // This file implements the interface defined in spellchecker_platform_engine.h 5 // This file implements the interface defined in spellchecker_platform_engine.h
6 // for the OS X platform. 6 // for the OS X platform.
7 7
8 #include "chrome/browser/spellchecker/spellchecker_platform_engine.h" 8 #include "chrome/browser/spellchecker/spellchecker_platform_engine.h"
9 9
10 #import <Cocoa/Cocoa.h> 10 #import <Cocoa/Cocoa.h>
11 11
12 #include "base/logging.h" 12 #include "base/logging.h"
13 #include "base/mac/foundation_util.h"
14 #include "base/mac/scoped_nsexception_enabler.h"
13 #include "base/metrics/histogram.h" 15 #include "base/metrics/histogram.h"
14 #include "base/sys_string_conversions.h" 16 #include "base/sys_string_conversions.h"
15 #include "base/task.h" 17 #include "base/task.h"
16 #include "base/time.h" 18 #include "base/time.h"
17 #include "chrome/common/spellcheck_common.h" 19 #include "chrome/common/spellcheck_common.h"
18 #include "chrome/common/spellcheck_messages.h" 20 #include "chrome/common/spellcheck_messages.h"
19 #include "content/browser/browser_message_filter.h" 21 #include "content/browser/browser_message_filter.h"
20 #include "content/public/browser/browser_thread.h" 22 #include "content/public/browser/browser_thread.h"
21 #include "third_party/WebKit/Source/WebKit/chromium/public/WebTextCheckingResult .h" 23 #include "third_party/WebKit/Source/WebKit/chromium/public/WebTextCheckingResult .h"
22 24
23 using base::TimeTicks; 25 using base::TimeTicks;
24 using content::BrowserThread; 26 using content::BrowserThread;
25 27
26 namespace { 28 namespace {
27 // The number of characters in the first part of the language code. 29 // The number of characters in the first part of the language code.
28 const unsigned int kShortLanguageCodeSize = 2; 30 const unsigned int kShortLanguageCodeSize = 2;
29 31
32 // +[NSSpellChecker sharedSpellChecker] can throw exceptions depending
33 // on the state of the pasteboard, or possibly as a result of
34 // third-party code (when setting up services entries). The following
35 // receives nil if an exception is thrown, in which case
36 // spell-checking will not work, but it also will not crash the
37 // browser.
38 NSSpellChecker* SharedSpellChecker() {
39 return base::mac::ObjCCastStrict<NSSpellChecker>(
40 base::mac::PerformSelectorIgnoringExceptions(
41 [NSSpellChecker class],
42 @selector(sharedSpellChecker)));
43 }
44
30 // TextCheckingTask is reserved for spell checking against large size 45 // TextCheckingTask is reserved for spell checking against large size
31 // of text, which possible contains multiple paragrpahs. Checking 46 // of text, which possible contains multiple paragrpahs. Checking
32 // that size of text might take time, and should be done as a task on 47 // that size of text might take time, and should be done as a task on
33 // the FILE thread. 48 // the FILE thread.
34 // 49 //
35 // The result of the check is returned back as a 50 // The result of the check is returned back as a
36 // SpellCheckMsg_RespondTextCheck message. 51 // SpellCheckMsg_RespondTextCheck message.
37 class TextCheckingTask : public Task { 52 class TextCheckingTask : public Task {
38 public: 53 public:
39 TextCheckingTask(BrowserMessageFilter* destination, 54 TextCheckingTask(BrowserMessageFilter* destination,
40 int route_id, 55 int route_id,
41 int identifier, 56 int identifier,
42 const string16& text, 57 const string16& text,
43 int document_tag) 58 int document_tag)
44 : destination_(destination), 59 : destination_(destination),
45 route_id_(route_id), 60 route_id_(route_id),
46 identifier_(identifier), 61 identifier_(identifier),
47 text_(text), 62 text_(text),
48 document_tag_(document_tag) { 63 document_tag_(document_tag) {
49 } 64 }
50 65
51 virtual void Run() { 66 virtual void Run() {
52 // TODO(morrita): Use [NSSpellChecker requestCheckingOfString] 67 // TODO(morrita): Use [NSSpellChecker requestCheckingOfString]
53 // when the build target goes up to 10.6 68 // when the build target goes up to 10.6
54 std::vector<WebKit::WebTextCheckingResult> check_results; 69 std::vector<WebKit::WebTextCheckingResult> check_results;
55 NSString* text_to_check = base::SysUTF16ToNSString(text_); 70 NSString* text_to_check = base::SysUTF16ToNSString(text_);
56 size_t starting_at = 0; 71 size_t starting_at = 0;
57 while (starting_at < text_.size()) { 72 while (starting_at < text_.size()) {
58 NSRange range = [[NSSpellChecker sharedSpellChecker] 73 NSRange range = [SharedSpellChecker()
59 checkSpellingOfString:text_to_check 74 checkSpellingOfString:text_to_check
60 startingAt:starting_at 75 startingAt:starting_at
61 language:nil 76 language:nil
62 wrap:NO 77 wrap:NO
63 inSpellDocumentWithTag:document_tag_ 78 inSpellDocumentWithTag:document_tag_
64 wordCount:NULL]; 79 wordCount:NULL];
65 if (range.length == 0) 80 if (range.length == 0)
66 break; 81 break;
67 check_results.push_back(WebKit::WebTextCheckingResult( 82 check_results.push_back(WebKit::WebTextCheckingResult(
68 WebKit::WebTextCheckingResult::ErrorSpelling, 83 WebKit::WebTextCheckingResult::ErrorSpelling,
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
145 [lang_code substringFromIndex:(kShortLanguageCodeSize + 1)]]); 160 [lang_code substringFromIndex:(kShortLanguageCodeSize + 1)]]);
146 } 161 }
147 return base::SysNSStringToUTF8(lang_code); 162 return base::SysNSStringToUTF8(lang_code);
148 } 163 }
149 164
150 } // namespace 165 } // namespace
151 166
152 namespace SpellCheckerPlatform { 167 namespace SpellCheckerPlatform {
153 168
154 void GetAvailableLanguages(std::vector<std::string>* spellcheck_languages) { 169 void GetAvailableLanguages(std::vector<std::string>* spellcheck_languages) {
155 NSArray* availableLanguages = [[NSSpellChecker sharedSpellChecker] 170 NSArray* availableLanguages = [SharedSpellChecker() availableLanguages];
156 availableLanguages];
157 for (NSString* lang_code in availableLanguages) { 171 for (NSString* lang_code in availableLanguages) {
158 spellcheck_languages->push_back( 172 spellcheck_languages->push_back(
159 ConvertLanguageCodeFromMac(lang_code)); 173 ConvertLanguageCodeFromMac(lang_code));
160 } 174 }
161 } 175 }
162 176
163 bool SpellCheckerAvailable() { 177 bool SpellCheckerAvailable() {
164 // If this file was compiled, then we know that we are on OS X 10.5 at least 178 // If this file was compiled, then we know that we are on OS X 10.5 at least
165 // and can safely return true here. 179 // and can safely return true here.
166 return true; 180 return true;
167 } 181 }
168 182
169 bool SpellCheckerProvidesPanel() { 183 bool SpellCheckerProvidesPanel() {
170 // OS X has a Spelling Panel, so we can return true here. 184 // OS X has a Spelling Panel, so we can return true here.
171 return true; 185 return true;
172 } 186 }
173 187
174 bool SpellingPanelVisible() { 188 bool SpellingPanelVisible() {
175 // This should only be called from the main thread. 189 // This should only be called from the main thread.
176 DCHECK([NSThread currentThread] == [NSThread mainThread]); 190 DCHECK([NSThread currentThread] == [NSThread mainThread]);
177 return [[[NSSpellChecker sharedSpellChecker] spellingPanel] isVisible]; 191 return [[SharedSpellChecker() spellingPanel] isVisible];
178 } 192 }
179 193
180 void ShowSpellingPanel(bool show) { 194 void ShowSpellingPanel(bool show) {
181 if (show) { 195 if (show) {
182 [[[NSSpellChecker sharedSpellChecker] spellingPanel] 196 [[SharedSpellChecker() spellingPanel]
183 performSelectorOnMainThread:@selector(makeKeyAndOrderFront:) 197 performSelectorOnMainThread:@selector(makeKeyAndOrderFront:)
184 withObject:nil 198 withObject:nil
185 waitUntilDone:YES]; 199 waitUntilDone:YES];
186 } else { 200 } else {
187 [[[NSSpellChecker sharedSpellChecker] spellingPanel] 201 [[SharedSpellChecker() spellingPanel]
188 performSelectorOnMainThread:@selector(close) 202 performSelectorOnMainThread:@selector(close)
189 withObject:nil 203 withObject:nil
190 waitUntilDone:YES]; 204 waitUntilDone:YES];
191 } 205 }
192 } 206 }
193 207
194 void UpdateSpellingPanelWithMisspelledWord(const string16& word) { 208 void UpdateSpellingPanelWithMisspelledWord(const string16& word) {
195 NSString * word_to_display = base::SysUTF16ToNSString(word); 209 NSString * word_to_display = base::SysUTF16ToNSString(word);
196 [[NSSpellChecker sharedSpellChecker] 210 [SharedSpellChecker()
197 performSelectorOnMainThread: 211 performSelectorOnMainThread:
198 @selector(updateSpellingPanelWithMisspelledWord:) 212 @selector(updateSpellingPanelWithMisspelledWord:)
199 withObject:word_to_display 213 withObject:word_to_display
200 waitUntilDone:YES]; 214 waitUntilDone:YES];
201 } 215 }
202 216
203 void Init() { 217 void Init() {
204 } 218 }
205 219
206 bool PlatformSupportsLanguage(const std::string& current_language) { 220 bool PlatformSupportsLanguage(const std::string& current_language) {
207 // First, convert the language to an OS X language code. 221 // First, convert the language to an OS X language code.
208 NSString* mac_lang_code = ConvertLanguageCodeToMac(current_language); 222 NSString* mac_lang_code = ConvertLanguageCodeToMac(current_language);
209 223
210 // Then grab the languages available. 224 // Then grab the languages available.
211 NSArray* availableLanguages; 225 NSArray* availableLanguages = [SharedSpellChecker() availableLanguages];
212 availableLanguages = [[NSSpellChecker sharedSpellChecker]
213 availableLanguages];
214 226
215 // Return true if the given language is supported by OS X. 227 // Return true if the given language is supported by OS X.
216 return [availableLanguages containsObject:mac_lang_code]; 228 return [availableLanguages containsObject:mac_lang_code];
217 } 229 }
218 230
219 void SetLanguage(const std::string& lang_to_set) { 231 void SetLanguage(const std::string& lang_to_set) {
220 NSString* NS_lang_to_set = ConvertLanguageCodeToMac(lang_to_set); 232 NSString* NS_lang_to_set = ConvertLanguageCodeToMac(lang_to_set);
221 [[NSSpellChecker sharedSpellChecker] setLanguage:NS_lang_to_set]; 233 [SharedSpellChecker() setLanguage:NS_lang_to_set];
222 } 234 }
223 235
224 static int last_seen_tag_; 236 static int last_seen_tag_;
225 237
226 bool CheckSpelling(const string16& word_to_check, int tag) { 238 bool CheckSpelling(const string16& word_to_check, int tag) {
227 last_seen_tag_ = tag; 239 last_seen_tag_ = tag;
228 240
229 // [[NSSpellChecker sharedSpellChecker] checkSpellingOfString] returns an 241 // -[NSSpellChecker checkSpellingOfString] returns an NSRange that
230 // NSRange that we can look at to determine if a word is misspelled. 242 // we can look at to determine if a word is misspelled.
231 NSRange spell_range = {0,0}; 243 NSRange spell_range = {0,0};
232 244
233 // Convert the word to an NSString. 245 // Convert the word to an NSString.
234 NSString* NS_word_to_check = base::SysUTF16ToNSString(word_to_check); 246 NSString* NS_word_to_check = base::SysUTF16ToNSString(word_to_check);
235 // Check the spelling, starting at the beginning of the word. 247 // Check the spelling, starting at the beginning of the word.
236 spell_range = [[NSSpellChecker sharedSpellChecker] 248 spell_range = [SharedSpellChecker()
237 checkSpellingOfString:NS_word_to_check startingAt:0 249 checkSpellingOfString:NS_word_to_check startingAt:0
238 language:nil wrap:NO inSpellDocumentWithTag:tag 250 language:nil wrap:NO inSpellDocumentWithTag:tag
239 wordCount:NULL]; 251 wordCount:NULL];
240 252
241 // If the length of the misspelled word == 0, 253 // If the length of the misspelled word == 0,
242 // then there is no misspelled word. 254 // then there is no misspelled word.
243 bool word_correct = (spell_range.length == 0); 255 bool word_correct = (spell_range.length == 0);
244 return word_correct; 256 return word_correct;
245 } 257 }
246 258
247 void FillSuggestionList(const string16& wrong_word, 259 void FillSuggestionList(const string16& wrong_word,
248 std::vector<string16>* optional_suggestions) { 260 std::vector<string16>* optional_suggestions) {
249 NSString* NS_wrong_word = base::SysUTF16ToNSString(wrong_word); 261 NSString* NS_wrong_word = base::SysUTF16ToNSString(wrong_word);
250 TimeTicks debug_begin_time = base::Histogram::DebugNow(); 262 TimeTicks debug_begin_time = base::Histogram::DebugNow();
251 // The suggested words for |wrong_word|. 263 // The suggested words for |wrong_word|.
252 NSArray* guesses = 264 NSArray* guesses = [SharedSpellChecker() guessesForWord:NS_wrong_word];
253 [[NSSpellChecker sharedSpellChecker] guessesForWord:NS_wrong_word];
254 DHISTOGRAM_TIMES("Spellcheck.SuggestTime", 265 DHISTOGRAM_TIMES("Spellcheck.SuggestTime",
255 base::Histogram::DebugNow() - debug_begin_time); 266 base::Histogram::DebugNow() - debug_begin_time);
256 267
257 for (int i = 0; i < static_cast<int>([guesses count]); i++) { 268 for (int i = 0; i < static_cast<int>([guesses count]); i++) {
258 if (i < SpellCheckCommon::kMaxSuggestions) { 269 if (i < SpellCheckCommon::kMaxSuggestions) {
259 optional_suggestions->push_back(base::SysNSStringToUTF16( 270 optional_suggestions->push_back(base::SysNSStringToUTF16(
260 [guesses objectAtIndex:i])); 271 [guesses objectAtIndex:i]));
261 } 272 }
262 } 273 }
263 } 274 }
264 275
265 void AddWord(const string16& word) { 276 void AddWord(const string16& word) {
266 NSString* word_to_add = base::SysUTF16ToNSString(word); 277 NSString* word_to_add = base::SysUTF16ToNSString(word);
267 [[NSSpellChecker sharedSpellChecker] learnWord:word_to_add]; 278 [SharedSpellChecker() learnWord:word_to_add];
268 } 279 }
269 280
270 void RemoveWord(const string16& word) { 281 void RemoveWord(const string16& word) {
271 NSString *word_to_remove = base::SysUTF16ToNSString(word); 282 NSString *word_to_remove = base::SysUTF16ToNSString(word);
272 [[NSSpellChecker sharedSpellChecker] unlearnWord:word_to_remove]; 283 [SharedSpellChecker() unlearnWord:word_to_remove];
273 } 284 }
274 285
275 int GetDocumentTag() { 286 int GetDocumentTag() {
276 NSInteger doc_tag = [NSSpellChecker uniqueSpellDocumentTag]; 287 NSInteger doc_tag = [NSSpellChecker uniqueSpellDocumentTag];
277 return static_cast<int>(doc_tag); 288 return static_cast<int>(doc_tag);
278 } 289 }
279 290
280 void IgnoreWord(const string16& word) { 291 void IgnoreWord(const string16& word) {
281 [[NSSpellChecker sharedSpellChecker] ignoreWord:base::SysUTF16ToNSString(word) 292 [SharedSpellChecker() ignoreWord:base::SysUTF16ToNSString(word)
282 inSpellDocumentWithTag:last_seen_tag_]; 293 inSpellDocumentWithTag:last_seen_tag_];
283 } 294 }
284 295
285 void CloseDocumentWithTag(int tag) { 296 void CloseDocumentWithTag(int tag) {
286 [[NSSpellChecker sharedSpellChecker] 297 [SharedSpellChecker() closeSpellDocumentWithTag:static_cast<NSInteger>(tag)];
287 closeSpellDocumentWithTag:static_cast<NSInteger>(tag)];
288 } 298 }
289 299
290 void RequestTextCheck(int route_id, 300 void RequestTextCheck(int route_id,
291 int identifier, 301 int identifier,
292 int document_tag, 302 int document_tag,
293 const string16& text, BrowserMessageFilter* destination) { 303 const string16& text, BrowserMessageFilter* destination) {
294 BrowserThread::PostTask( 304 BrowserThread::PostTask(
295 BrowserThread::FILE, FROM_HERE, 305 BrowserThread::FILE, FROM_HERE,
296 new TextCheckingTask( 306 new TextCheckingTask(
297 destination, route_id, identifier, text, document_tag)); 307 destination, route_id, identifier, text, document_tag));
298 } 308 }
299 309
300 } // namespace SpellCheckerPlatform 310 } // namespace SpellCheckerPlatform
OLDNEW
« no previous file with comments | « base/mac/scoped_nsexception_enabler.mm ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698