]> git.lyx.org Git - lyx.git/blobdiff - src/support/AppleSpeller.m
Get rid of regex_constants::match_partial
[lyx.git] / src / support / AppleSpeller.m
index 560d014fb85368eb816b006c04665ef210bee10f..08e3f5972214e38218ec72e1a37ec5529aba1e4d 100644 (file)
@@ -8,7 +8,6 @@
  * Full author contact details are available in file CREDITS.
  */
 
-#import <Carbon/Carbon.h>
 #import <Cocoa/Cocoa.h>
 
 #import <AvailabilityMacros.h>
@@ -22,29 +21,18 @@ typedef struct AppleSpellerRec {
 #else
        int doctag;
 #endif
-       char ** suggestions;
-       size_t numsug;
+       NSArray * suggestions;
+       NSArray * misspelled;
 } 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];
+       speller->suggestions = nil;
+       speller->misspelled = nil;
        return speller;
 }
 
@@ -53,50 +41,105 @@ void freeAppleSpeller(AppleSpeller speller)
 {
        NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
 
-       freeSuggestionsAppleSpeller(speller);
        [speller->checker closeSpellDocumentWithTag:speller->doctag];
 
+       [speller->suggestions release];
+       [speller->misspelled release];
+
        [pool release];
 
        free(speller);
 }
 
 
-static NSString * toString(AppleSpeller speller, const char * word)
+static NSString * toString(const char * word)
 {
        return [[NSString alloc] initWithBytes:word length:strlen(word) encoding:NSUTF8StringEncoding];
 }
 
 
-int checkAppleSpeller(AppleSpeller speller, const char * word, const char * lang)
+static NSString * toLanguage(AppleSpeller speller, const char * lang)
+{
+       NSString * result = nil;
+#if defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && (__MAC_OS_X_VERSION_MAX_ALLOWED >= 1050)
+       NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
+       NSString * lang_ = toString(lang);
+       if ([NSSpellChecker instancesRespondToSelector:@selector(availableLanguages)]) {
+               NSArray * languages = [speller->checker availableLanguages];
+               
+               for (NSString *element in languages) {
+                       if (0 == [element caseInsensitiveCompare:lang_]) {
+                               result = element;
+                               break;
+                       } else if ([lang_ hasPrefix:element]) {
+                               result = element;
+                       }
+               }
+       }
+       [lang_ release];
+       [pool release];
+#endif
+       return result;
+}
+
+
+SpellCheckResult AppleSpeller_check(AppleSpeller speller, const char * word, const char * lang)
 {
        if (!speller->checker || !lang || !word)
-               return 0;
+               return SPELL_CHECK_FAILED;
 
        NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
-       NSString * word_ = toString(speller, word);
-       NSString * lang_ = toString(speller, lang);
+       NSString * word_ = toString(word);
+       NSString * lang_ = toString(lang);
+       SpellCheckResult result = SPELL_CHECK_FAILED;
+       int start = 0;
+       int length = [word_ length];
+       
+       [speller->misspelled release];
+       speller->misspelled = nil;
 
-       NSRange result = [speller->checker
-               checkSpellingOfString:word_
-               startingAt:0
-               language:lang_
-               wrap:NO
-               inSpellDocumentWithTag:speller->doctag
-               wordCount:NULL];
+       while (result == SPELL_CHECK_FAILED && start < length) {
+               NSRange match = [speller->checker
+                       checkSpellingOfString:word_
+                       startingAt:start
+                       language:lang_
+                       wrap:(BOOL)NO
+                       inSpellDocumentWithTag:speller->doctag
+                       wordCount:NULL];
+
+               result = match.length == 0 ? SPELL_CHECK_OK : SPELL_CHECK_FAILED;
+               if (result == SPELL_CHECK_OK) {
+                       if ([NSSpellChecker instancesRespondToSelector:@selector(hasLearnedWord:)]) {
+                               if ([speller->checker hasLearnedWord:word_])
+                                       result = SPELL_CHECK_LEARNED;
+                       }
+               } else {
+#if defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && (__MAC_OS_X_VERSION_MAX_ALLOWED >= 1050)
+                       NSUInteger capacity = [speller->misspelled count] + 1;
+#else
+                       int capacity = [speller->misspelled count] + 1;
+#endif
+                       NSMutableArray * misspelled = [NSMutableArray arrayWithCapacity:capacity];
+                       [misspelled addObjectsFromArray:speller->misspelled];
+                       [misspelled addObject:[NSValue valueWithRange:match]];
+                       [speller->misspelled release];
+                       speller->misspelled = [[NSArray arrayWithArray:misspelled] retain];
+                       start = match.location + match.length + 1;
+               }
+       }
 
        [word_ release];
        [lang_ release];
        [pool release];
 
-       return (result.length ? 0 : 1);
+       return [speller->misspelled count] ? SPELL_CHECK_FAILED : result;
 }
 
 
-void ignoreAppleSpeller(AppleSpeller speller, const char * word, const char * lang)
+void AppleSpeller_ignore(AppleSpeller speller, const char * word)
 {
        NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
-       NSString * word_ = toString(speller, word);
+       NSString * word_ = toString(word);
 
        [speller->checker ignoreWord:word_ inSpellDocumentWithTag:(speller->doctag)];
 
@@ -105,30 +148,25 @@ void ignoreAppleSpeller(AppleSpeller speller, const char * word, const char * la
 }
 
 
-size_t makeSuggestionAppleSpeller(AppleSpeller speller, const char * word, const char * lang)
+size_t AppleSpeller_makeSuggestion(AppleSpeller speller, const char * word, const char * lang)
 {
        if (!speller->checker || !word || !lang)
                return 0;
 
        NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
-       NSString * word_ = toString(speller, word);
-       NSString * lang_ = toString(speller, lang);
+       NSString * word_ = toString(word);
+       NSString * lang_ = toString(lang);
        NSArray * result ;
 
 #if defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && (__MAC_OS_X_VERSION_MAX_ALLOWED >= 1060)
        // Mac OS X 10.6 only
        NSInteger slen = [word_ length];
        NSRange range = { 0, slen };
-       
-       if ([NSSpellChecker instancesRespondToSelector:@selector(guessesForWordRange:)]) {
-               result = [speller->checker guessesForWordRange:range
-                       inString:word_
-                       language:lang_
-                       inSpellDocumentWithTag:speller->doctag];
-       } else {
-               [speller->checker setLanguage:lang_];
-               result = [speller->checker guessesForWord:word_];
-       }
+
+       result = [speller->checker guessesForWordRange:range
+               inString:word_
+               language:lang_
+               inSpellDocumentWithTag:speller->doctag];
 #else
        [speller->checker setLanguage:lang_];
        result = [speller->checker guessesForWord:word_];
@@ -137,42 +175,31 @@ size_t makeSuggestionAppleSpeller(AppleSpeller speller, const char * word, const
        [word_ release];
        [lang_ release];
 
-       freeSuggestionsAppleSpeller(speller);
+       [speller->suggestions release];
+       speller->suggestions = [[NSArray arrayWithArray:result] retain];
 
-       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;
+       return [speller->suggestions count];
 }
 
 
-const char * getSuggestionAppleSpeller(AppleSpeller speller, size_t pos)
+const char * AppleSpeller_getSuggestion(AppleSpeller speller, size_t pos)
 {
        const char * result = 0;
-       if (pos < speller->numsug && speller->suggestions) {
-               result = speller->suggestions[pos] ;
+       if (pos < [speller->suggestions count]) {
+               result = [[speller->suggestions objectAtIndex:pos] UTF8String] ;
        }
        return result;
 }
 
 
-void learnAppleSpeller(AppleSpeller speller, const char * word, const char * lang)
+void AppleSpeller_learn(AppleSpeller speller, const char * word)
 {
 #if defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && (__MAC_OS_X_VERSION_MAX_ALLOWED >= 1050)
        NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
-       NSString * word_ = toString(speller, word);
+       NSString * word_ = toString(word);
 
-       if ([NSSpellChecker instancesRespondToSelector:@selector(learnWord)])
+       if ([NSSpellChecker instancesRespondToSelector:@selector(learnWord:)])
                [speller->checker learnWord:word_];
        
        [word_ release];
@@ -181,24 +208,44 @@ void learnAppleSpeller(AppleSpeller speller, const char * word, const char * lan
 }
 
 
-int hasLanguageAppleSpeller(AppleSpeller speller, const char * lang)
+void AppleSpeller_unlearn(AppleSpeller speller, const char * word)
 {
-       BOOL result = NO;
 #if defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && (__MAC_OS_X_VERSION_MAX_ALLOWED >= 1050)
        NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
-       NSString * lang_ = toString(speller, lang);
-       if ([NSSpellChecker instancesRespondToSelector:@selector(availableLanguages)]) {
-               NSArray * languages = [speller->checker availableLanguages];
+       NSString * word_ = toString(word);
 
-               for (NSString *element in languages) {
-                       result = [element isEqualToString:lang_] || [lang_ hasPrefix:element];
-                       if (result) break;
-               }
-       }
-
-       [lang_ release];
+       if ([NSSpellChecker instancesRespondToSelector:@selector(unlearnWord:)])
+               [speller->checker unlearnWord:word_];
+       
+       [word_ release];
        [pool release];
 #endif
+}
 
-       return result ? 1 : 0;
+
+int AppleSpeller_numMisspelledWords(AppleSpeller speller)
+{
+       return [speller->misspelled count];
+}
+
+
+void AppleSpeller_misspelledWord(AppleSpeller speller, int index, int * start, int * length)
+{
+#if defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && (__MAC_OS_X_VERSION_MAX_ALLOWED >= 1050)
+       NSRange range = [[speller->misspelled objectAtIndex:(NSUInteger)index] rangeValue];
+#else
+       NSRange range = [[speller->misspelled objectAtIndex:index] rangeValue];
+#endif
+       *start = range.location;
+       *length = range.length;
+}
+
+
+int AppleSpeller_hasLanguage(AppleSpeller speller, const char * lang)
+{
+#if defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && (__MAC_OS_X_VERSION_MAX_ALLOWED >= 1050)
+       return toLanguage(speller, lang) != nil;
+#else
+       return true;
+#endif
 }