]> git.lyx.org Git - lyx.git/blob - src/support/AppleSpeller.m
correct result array use in makeSuggestionAppleSpeller
[lyx.git] / src / support / AppleSpeller.m
1 /**
2  * \file AppleSpeller.m
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Stephan Witt
7  *
8  * Full author contact details are available in file CREDITS.
9  */
10
11 #import <Carbon/Carbon.h>
12 #import <Cocoa/Cocoa.h>
13
14 #import <AvailabilityMacros.h>
15
16 #include "support/AppleSpeller.h"
17
18 typedef struct AppleSpellerRec {
19         NSSpellChecker * checker;
20 #if defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && (__MAC_OS_X_VERSION_MAX_ALLOWED >= 1050)
21         NSInteger doctag;
22 #else
23         int doctag;
24 #endif
25         char ** suggestions;
26         size_t numsug;
27 } AppleSpellerRec ;
28
29
30 static void freeSuggestionsAppleSpeller(AppleSpeller speller)
31 {
32         if (speller->suggestions) {
33                 while (speller->numsug--) {
34                         free(speller->suggestions[speller->numsug]);
35                 }
36                 free(speller->suggestions);
37                 speller->suggestions = 0;
38         }
39 }
40
41
42 AppleSpeller newAppleSpeller(void)
43 {
44         AppleSpeller speller = calloc(1, sizeof(AppleSpellerRec));
45         speller->checker = [NSSpellChecker sharedSpellChecker];
46         speller->suggestions = 0;
47         speller->doctag = [NSSpellChecker uniqueSpellDocumentTag];
48         return speller;
49 }
50
51
52 void freeAppleSpeller(AppleSpeller speller)
53 {
54         NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
55
56         freeSuggestionsAppleSpeller(speller);
57         [speller->checker closeSpellDocumentWithTag:speller->doctag];
58
59         [pool release];
60
61         free(speller);
62 }
63
64
65 static NSString * toString(AppleSpeller speller, const char * word)
66 {
67         return [[NSString alloc] initWithBytes:word length:strlen(word) encoding:NSUTF8StringEncoding];
68 }
69
70
71 int checkAppleSpeller(AppleSpeller speller, const char * word, const char * lang)
72 {
73         if (!speller->checker || !lang || !word)
74                 return 0;
75
76         NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
77 #if defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && (__MAC_OS_X_VERSION_MAX_ALLOWED >= 1050)
78         NSInteger wordcount;
79 #else
80         int wordcount;
81 #endif
82         NSString * word_ = toString(speller, word);
83         NSString * lang_ = toString(speller, lang);
84
85         NSRange result = [speller->checker
86                 checkSpellingOfString:word_
87                 startingAt:0
88                 language:lang_
89                 wrap:(BOOL)NO
90                 inSpellDocumentWithTag:speller->doctag
91                 wordCount:&wordcount];
92
93         [word_ release];
94         [lang_ release];
95         [pool release];
96
97         return (result.length ? 0 : 1);
98 }
99
100
101 void ignoreAppleSpeller(AppleSpeller speller, const char * word, const char * lang)
102 {
103         NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
104         NSString * word_ = toString(speller, word);
105
106         [speller->checker ignoreWord:word_ inSpellDocumentWithTag:(speller->doctag)];
107
108         [word_ release];
109         [pool release];
110 }
111
112
113 size_t makeSuggestionAppleSpeller(AppleSpeller speller, const char * word, const char * lang)
114 {
115         if (!speller->checker || !word || !lang)
116                 return 0;
117
118         NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
119         NSString * word_ = toString(speller, word);
120         NSString * lang_ = toString(speller, lang);
121         NSArray * result ;
122
123 #if defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && (__MAC_OS_X_VERSION_MAX_ALLOWED >= 1060)
124         // Mac OS X 10.6 only
125         NSInteger slen = [word_ length];
126         NSRange range = { 0, slen };
127         
128         if ([NSSpellChecker instancesRespondToSelector:@selector(guessesForWordRange:)]) {
129                 result = [speller->checker guessesForWordRange:range
130                         inString:word_
131                         language:lang_
132                         inSpellDocumentWithTag:speller->doctag];
133         } else {
134                 [speller->checker setLanguage:lang_];
135                 result = [speller->checker guessesForWord:word_];
136         }
137 #else
138         [speller->checker setLanguage:lang_];
139         result = [speller->checker guessesForWord:word_];
140 #endif
141
142         [word_ release];
143         [lang_ release];
144
145         freeSuggestionsAppleSpeller(speller);
146
147         speller->numsug = [result count];
148         if (speller->numsug) {
149                 speller->suggestions = calloc(speller->numsug + 1, sizeof(char *));
150                 if (speller->suggestions) {
151                         size_t i;
152                         for (i = 0; i < speller->numsug; i++) {
153                                 NSString * str = [result objectAtIndex:i];
154                                 speller->suggestions[i] = strdup([str UTF8String]);
155                         }
156                         speller->suggestions[speller->numsug] = 0;
157                 }
158         }
159         [pool release];
160         return speller->numsug;
161 }
162
163
164 const char * getSuggestionAppleSpeller(AppleSpeller speller, size_t pos)
165 {
166         const char * result = 0;
167         if (pos < speller->numsug && speller->suggestions) {
168                 result = speller->suggestions[pos] ;
169         }
170         return result;
171 }
172
173
174 void learnAppleSpeller(AppleSpeller speller, const char * word, const char * lang)
175 {
176 #if defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && (__MAC_OS_X_VERSION_MAX_ALLOWED >= 1050)
177         NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
178         NSString * word_ = toString(speller, word);
179
180         if ([NSSpellChecker instancesRespondToSelector:@selector(learnWord)])
181                 [speller->checker learnWord:word_];
182         
183         [word_ release];
184         [pool release];
185 #endif
186 }
187
188
189 int hasLanguageAppleSpeller(AppleSpeller speller, const char * lang)
190 {
191         BOOL result = NO;
192 #if defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && (__MAC_OS_X_VERSION_MAX_ALLOWED >= 1050)
193         NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
194         NSString * lang_ = toString(speller, lang);
195         if ([NSSpellChecker instancesRespondToSelector:@selector(availableLanguages)]) {
196                 NSArray * languages = [speller->checker availableLanguages];
197
198                 for (NSString *element in languages) {
199                         result = [element isEqualToString:lang_] || [lang_ hasPrefix:element];
200                         if (result) break;
201                 }
202         }
203
204         [lang_ release];
205         [pool release];
206 #endif
207
208         return result ? 1 : 0;
209 }