2010-07-07 17:40:50 +00:00
|
|
|
/**
|
|
|
|
* \file AppleSpeller.m
|
|
|
|
* This file is part of LyX, the document processor.
|
|
|
|
* Licence details can be found in the file COPYING.
|
|
|
|
*
|
|
|
|
* \author Stephan Witt
|
|
|
|
*
|
|
|
|
* Full author contact details are available in file CREDITS.
|
|
|
|
*/
|
|
|
|
|
2010-07-11 21:30:47 +00:00
|
|
|
#import <Carbon/Carbon.h>
|
|
|
|
#import <Cocoa/Cocoa.h>
|
|
|
|
|
|
|
|
#import <AvailabilityMacros.h>
|
2010-07-07 17:40:50 +00:00
|
|
|
|
|
|
|
#include "support/AppleSpeller.h"
|
|
|
|
|
|
|
|
typedef struct AppleSpellerRec {
|
|
|
|
NSSpellChecker * checker;
|
2010-07-11 21:30:47 +00:00
|
|
|
#if defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && (__MAC_OS_X_VERSION_MAX_ALLOWED >= 1050)
|
2010-07-07 17:40:50 +00:00
|
|
|
NSInteger doctag;
|
|
|
|
#else
|
|
|
|
int doctag;
|
|
|
|
#endif
|
|
|
|
char ** suggestions;
|
|
|
|
size_t numsug;
|
|
|
|
} AppleSpellerRec ;
|
|
|
|
|
|
|
|
|
|
|
|
static void freeSuggestionsAppleSpeller(AppleSpeller speller)
|
|
|
|
{
|
|
|
|
if (speller->suggestions) {
|
|
|
|
while (speller->numsug--) {
|
|
|
|
free(speller->suggestions[speller->numsug]);
|
|
|
|
}
|
|
|
|
free(speller->suggestions);
|
|
|
|
speller->suggestions = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
AppleSpeller newAppleSpeller(void)
|
|
|
|
{
|
|
|
|
AppleSpeller speller = calloc(1, sizeof(AppleSpellerRec));
|
|
|
|
speller->checker = [NSSpellChecker sharedSpellChecker];
|
|
|
|
speller->suggestions = 0;
|
|
|
|
speller->doctag = [NSSpellChecker uniqueSpellDocumentTag];
|
|
|
|
return speller;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void freeAppleSpeller(AppleSpeller speller)
|
|
|
|
{
|
|
|
|
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
|
|
|
|
|
|
|
|
freeSuggestionsAppleSpeller(speller);
|
|
|
|
[speller->checker closeSpellDocumentWithTag:speller->doctag];
|
|
|
|
|
|
|
|
[pool release];
|
|
|
|
|
|
|
|
free(speller);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-08-05 19:00:57 +00:00
|
|
|
static NSString * toString(const char * word)
|
2010-07-07 17:40:50 +00:00
|
|
|
{
|
|
|
|
return [[NSString alloc] initWithBytes:word length:strlen(word) encoding:NSUTF8StringEncoding];
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int checkAppleSpeller(AppleSpeller speller, const char * word, const char * lang)
|
|
|
|
{
|
|
|
|
if (!speller->checker || !lang || !word)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
|
2010-08-05 19:00:57 +00:00
|
|
|
NSString * word_ = toString(word);
|
|
|
|
NSString * lang_ = toString(lang);
|
2010-07-07 17:40:50 +00:00
|
|
|
|
|
|
|
NSRange result = [speller->checker
|
|
|
|
checkSpellingOfString:word_
|
|
|
|
startingAt:0
|
|
|
|
language:lang_
|
2010-08-03 22:31:16 +00:00
|
|
|
wrap:NO
|
2010-07-07 17:40:50 +00:00
|
|
|
inSpellDocumentWithTag:speller->doctag
|
2010-08-03 22:31:16 +00:00
|
|
|
wordCount:NULL];
|
2010-07-07 17:40:50 +00:00
|
|
|
|
|
|
|
[word_ release];
|
|
|
|
[lang_ release];
|
|
|
|
[pool release];
|
|
|
|
|
|
|
|
return (result.length ? 0 : 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-08-05 19:00:57 +00:00
|
|
|
void ignoreAppleSpeller(AppleSpeller speller, const char * word)
|
2010-07-07 17:40:50 +00:00
|
|
|
{
|
|
|
|
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
|
2010-08-05 19:00:57 +00:00
|
|
|
NSString * word_ = toString(word);
|
2010-07-07 17:40:50 +00:00
|
|
|
|
|
|
|
[speller->checker ignoreWord:word_ inSpellDocumentWithTag:(speller->doctag)];
|
|
|
|
|
|
|
|
[word_ release];
|
|
|
|
[pool release];
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
size_t makeSuggestionAppleSpeller(AppleSpeller speller, const char * word, const char * lang)
|
|
|
|
{
|
|
|
|
if (!speller->checker || !word || !lang)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
|
2010-08-05 19:00:57 +00:00
|
|
|
NSString * word_ = toString(word);
|
|
|
|
NSString * lang_ = toString(lang);
|
2010-07-11 22:04:29 +00:00
|
|
|
NSArray * result ;
|
2010-07-07 17:40:50 +00:00
|
|
|
|
2010-07-11 21:30:47 +00:00
|
|
|
#if defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && (__MAC_OS_X_VERSION_MAX_ALLOWED >= 1060)
|
2010-07-07 17:40:50 +00:00
|
|
|
// Mac OS X 10.6 only
|
|
|
|
NSInteger slen = [word_ length];
|
|
|
|
NSRange range = { 0, slen };
|
2010-07-11 21:30:47 +00:00
|
|
|
|
|
|
|
if ([NSSpellChecker instancesRespondToSelector:@selector(guessesForWordRange:)]) {
|
|
|
|
result = [speller->checker guessesForWordRange:range
|
|
|
|
inString:word_
|
|
|
|
language:lang_
|
|
|
|
inSpellDocumentWithTag:speller->doctag];
|
|
|
|
} else {
|
|
|
|
[speller->checker setLanguage:lang_];
|
2010-07-11 22:04:29 +00:00
|
|
|
result = [speller->checker guessesForWord:word_];
|
2010-07-11 21:30:47 +00:00
|
|
|
}
|
2010-07-07 17:40:50 +00:00
|
|
|
#else
|
|
|
|
[speller->checker setLanguage:lang_];
|
2010-07-11 22:04:29 +00:00
|
|
|
result = [speller->checker guessesForWord:word_];
|
2010-07-07 17:40:50 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
[word_ release];
|
|
|
|
[lang_ release];
|
|
|
|
|
|
|
|
freeSuggestionsAppleSpeller(speller);
|
|
|
|
|
|
|
|
speller->numsug = [result count];
|
|
|
|
if (speller->numsug) {
|
|
|
|
speller->suggestions = calloc(speller->numsug + 1, sizeof(char *));
|
|
|
|
if (speller->suggestions) {
|
|
|
|
size_t i;
|
|
|
|
for (i = 0; i < speller->numsug; i++) {
|
|
|
|
NSString * str = [result objectAtIndex:i];
|
|
|
|
speller->suggestions[i] = strdup([str UTF8String]);
|
|
|
|
}
|
|
|
|
speller->suggestions[speller->numsug] = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
[pool release];
|
|
|
|
return speller->numsug;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const char * getSuggestionAppleSpeller(AppleSpeller speller, size_t pos)
|
|
|
|
{
|
|
|
|
const char * result = 0;
|
|
|
|
if (pos < speller->numsug && speller->suggestions) {
|
|
|
|
result = speller->suggestions[pos] ;
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-08-05 19:00:57 +00:00
|
|
|
void learnAppleSpeller(AppleSpeller speller, const char * word)
|
2010-07-07 17:40:50 +00:00
|
|
|
{
|
2010-07-11 21:30:47 +00:00
|
|
|
#if defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && (__MAC_OS_X_VERSION_MAX_ALLOWED >= 1050)
|
2010-07-07 17:40:50 +00:00
|
|
|
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
|
2010-08-05 19:00:57 +00:00
|
|
|
NSString * word_ = toString(word);
|
2010-07-07 17:40:50 +00:00
|
|
|
|
2010-07-11 21:30:47 +00:00
|
|
|
if ([NSSpellChecker instancesRespondToSelector:@selector(learnWord)])
|
|
|
|
[speller->checker learnWord:word_];
|
2010-07-07 17:40:50 +00:00
|
|
|
|
|
|
|
[word_ release];
|
|
|
|
[pool release];
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int hasLanguageAppleSpeller(AppleSpeller speller, const char * lang)
|
|
|
|
{
|
|
|
|
BOOL result = NO;
|
2010-07-11 21:30:47 +00:00
|
|
|
#if defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && (__MAC_OS_X_VERSION_MAX_ALLOWED >= 1050)
|
2010-07-07 17:40:50 +00:00
|
|
|
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
|
2010-08-05 19:00:57 +00:00
|
|
|
NSString * lang_ = toString(lang);
|
2010-07-11 21:30:47 +00:00
|
|
|
if ([NSSpellChecker instancesRespondToSelector:@selector(availableLanguages)]) {
|
|
|
|
NSArray * languages = [speller->checker availableLanguages];
|
2010-07-07 17:40:50 +00:00
|
|
|
|
2010-07-11 21:30:47 +00:00
|
|
|
for (NSString *element in languages) {
|
|
|
|
result = [element isEqualToString:lang_] || [lang_ hasPrefix:element];
|
|
|
|
if (result) break;
|
|
|
|
}
|
2010-07-07 17:40:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
[lang_ release];
|
|
|
|
[pool release];
|
|
|
|
#endif
|
|
|
|
|
|
|
|
return result ? 1 : 0;
|
|
|
|
}
|