Implement LFUN_SPELLING_REMOVE (patch from switt)

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@35055 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Jean-Marc Lasgouttes 2010-08-05 20:10:40 +00:00
parent f5e2d78792
commit e4f2484cb5
19 changed files with 186 additions and 69 deletions

View File

@ -84,6 +84,8 @@ The following new LyX functions have been introduced:
- LFUN_SPELLING_IGNORE ("spelling-ignore"). - LFUN_SPELLING_IGNORE ("spelling-ignore").
- LFUN_SPELLING_REMOVE ("spelling-remove").
- LFUN_PREVIEW_INSERT ("preview-insert"). - LFUN_PREVIEW_INSERT ("preview-insert").
- LFUN_FORWARD_SEARCH ("forward-search"). - LFUN_FORWARD_SEARCH ("forward-search").

View File

@ -29,6 +29,9 @@ struct AppleSpellChecker::Private
~Private(); ~Private();
SpellChecker::Result toResult(SpellCheckResult status);
string toString(SpellCheckResult status);
/// the speller /// the speller
AppleSpeller speller; AppleSpeller speller;
}; };
@ -58,11 +61,26 @@ AppleSpellChecker::~AppleSpellChecker()
} }
SpellChecker::Result AppleSpellChecker::Private::toResult(SpellCheckResult status)
{
return status == SPELL_CHECK_FAILED ? UNKNOWN_WORD :
status == SPELL_CHECK_LEARNED ? LEARNED_WORD : WORD_OK ;
}
string AppleSpellChecker::Private::toString(SpellCheckResult status)
{
return status == SPELL_CHECK_FAILED ? "FAILED" :
status == SPELL_CHECK_LEARNED ? "LEARNED" : "OK";
}
SpellChecker::Result AppleSpellChecker::check(WordLangTuple const & word) SpellChecker::Result AppleSpellChecker::check(WordLangTuple const & word)
{ {
string const word_str = to_utf8(word.word()); string const word_str = to_utf8(word.word());
int const word_ok = checkAppleSpeller(d->speller, word_str.c_str(), word.lang()->code().c_str()); SpellCheckResult result = checkAppleSpeller(d->speller, word_str.c_str(), word.lang()->code().c_str());
return (word_ok) ? OK : UNKNOWN_WORD; LYXERR(Debug::GUI, "spellCheck: \"" << word.word() << "\" = " << d->toString(result)) ;
return d->toResult(result);
} }
@ -71,6 +89,16 @@ void AppleSpellChecker::insert(WordLangTuple const & word)
{ {
string const word_str = to_utf8(word.word()); string const word_str = to_utf8(word.word());
learnAppleSpeller(d->speller, word_str.c_str()); learnAppleSpeller(d->speller, word_str.c_str());
LYXERR(Debug::GUI, "learn word: \"" << word.word() << "\"") ;
}
// remove from personal dictionary
void AppleSpellChecker::remove(WordLangTuple const & word)
{
string const word_str = to_utf8(word.word());
unlearnAppleSpeller(d->speller, word_str.c_str());
LYXERR(Debug::GUI, "unlearn word: \"" << word.word() << "\"") ;
} }

View File

@ -27,6 +27,7 @@ public:
enum Result check(WordLangTuple const &); enum Result check(WordLangTuple const &);
void suggest(WordLangTuple const &, docstring_list &); void suggest(WordLangTuple const &, docstring_list &);
void insert(WordLangTuple const &); void insert(WordLangTuple const &);
void remove(WordLangTuple const &);
void accept(WordLangTuple const &); void accept(WordLangTuple const &);
bool hasDictionary(Language const * lang) const; bool hasDictionary(Language const * lang) const;
docstring const error(); docstring const error();

View File

@ -266,17 +266,17 @@ SpellChecker::Result AspellChecker::check(WordLangTuple const & word)
d->speller(word.lang()->code(), word.lang()->variety()); d->speller(word.lang()->code(), word.lang()->variety());
if (!m) if (!m)
return OK; return WORD_OK;
if (word.word().empty()) if (word.word().empty())
// MSVC compiled Aspell doesn't like it. // MSVC compiled Aspell doesn't like it.
return OK; return WORD_OK;
string const word_str = to_utf8(word.word()); string const word_str = to_utf8(word.word());
int const word_ok = aspell_speller_check(m, word_str.c_str(), -1); int const word_ok = aspell_speller_check(m, word_str.c_str(), -1);
LASSERT(word_ok != -1, /**/); LASSERT(word_ok != -1, /**/);
return (word_ok) ? OK : UNKNOWN_WORD; return (word_ok) ? WORD_OK : UNKNOWN_WORD;
} }

View File

@ -28,6 +28,7 @@ public:
enum Result check(WordLangTuple const &); enum Result check(WordLangTuple const &);
void suggest(WordLangTuple const &, docstring_list &); void suggest(WordLangTuple const &, docstring_list &);
void insert(WordLangTuple const &); void insert(WordLangTuple const &);
void remove(WordLangTuple const &) {};
void accept(WordLangTuple const &); void accept(WordLangTuple const &);
bool hasDictionary(Language const * lang) const; bool hasDictionary(Language const * lang) const;
docstring const error(); docstring const error();

View File

@ -3995,7 +3995,8 @@ int Buffer::spellCheck(DocIterator & from, DocIterator & to,
if (from == end) if (from == end)
break; break;
to = from; to = from;
if (from.paragraph().spellCheck(from.pos(), to.pos(), wl, suggestions)) { SpellChecker::Result res = from.paragraph().spellCheck(from.pos(), to.pos(), wl, suggestions);
if (SpellChecker::misspelled(res)) {
word_lang = wl; word_lang = wl;
break; break;
} }

View File

@ -113,12 +113,12 @@ SpellChecker::Result EnchantChecker::check(WordLangTuple const & word)
enchant::Dict * m = d->speller(word.lang()->code()); enchant::Dict * m = d->speller(word.lang()->code());
if (!m) if (!m)
return OK; return WORD_OK;
string utf8word = to_utf8(word.word()); string utf8word = to_utf8(word.word());
if (m->check(utf8word)) if (m->check(utf8word))
return OK; return WORD_OK;
return UNKNOWN_WORD; return UNKNOWN_WORD;
} }

View File

@ -34,6 +34,7 @@ public:
enum Result check(WordLangTuple const &); enum Result check(WordLangTuple const &);
void suggest(WordLangTuple const &, docstring_list &); void suggest(WordLangTuple const &, docstring_list &);
void insert(WordLangTuple const &); void insert(WordLangTuple const &);
void remove(WordLangTuple const &) {};
void accept(WordLangTuple const &); void accept(WordLangTuple const &);
bool hasDictionary(Language const * lang) const; bool hasDictionary(Language const * lang) const;
docstring const error(); docstring const error();

View File

@ -444,6 +444,7 @@ enum FuncCode
LFUN_SPELLING_ADD, // spitz 20100118 LFUN_SPELLING_ADD, // spitz 20100118
LFUN_SPELLING_IGNORE, // spitz 20100118 LFUN_SPELLING_IGNORE, // spitz 20100118
// 345 // 345
LFUN_SPELLING_REMOVE, // switt 20100728
LFUN_PREVIEW_INSERT, // vfr, 20100328 LFUN_PREVIEW_INSERT, // vfr, 20100328
LFUN_FORWARD_SEARCH, LFUN_FORWARD_SEARCH,
LFUN_INSET_COPY_AS, // vfr, 20100419 LFUN_INSET_COPY_AS, // vfr, 20100419

View File

@ -207,18 +207,18 @@ HunspellChecker::~HunspellChecker()
SpellChecker::Result HunspellChecker::check(WordLangTuple const & wl) SpellChecker::Result HunspellChecker::check(WordLangTuple const & wl)
{ {
if (d->isIgnored(wl)) if (d->isIgnored(wl))
return OK; return WORD_OK;
Hunspell * h = d->speller(wl.lang()->code()); Hunspell * h = d->speller(wl.lang()->code());
if (!h) if (!h)
return OK; return WORD_OK;
int info; int info;
string const encoding = h->get_dic_encoding(); string const encoding = h->get_dic_encoding();
string const word_to_check = to_iconv_encoding(wl.word(), encoding); string const word_to_check = to_iconv_encoding(wl.word(), encoding);
if (h->spell(word_to_check.c_str(), &info)) if (h->spell(word_to_check.c_str(), &info))
return OK; return WORD_OK;
if (info & SPELL_COMPOUND) { if (info & SPELL_COMPOUND) {
// FIXME: What to do with that? // FIXME: What to do with that?

View File

@ -28,6 +28,7 @@ public:
enum Result check(WordLangTuple const &); enum Result check(WordLangTuple const &);
void suggest(WordLangTuple const &, docstring_list &); void suggest(WordLangTuple const &, docstring_list &);
void insert(WordLangTuple const &); void insert(WordLangTuple const &);
void remove(WordLangTuple const &) {};
void accept(WordLangTuple const &); void accept(WordLangTuple const &);
bool hasDictionary(Language const * lang) const; bool hasDictionary(Language const * lang) const;
docstring const error(); docstring const error();

View File

@ -1015,6 +1015,17 @@ void LyXAction::init()
* \endvar * \endvar
*/ */
{ LFUN_SPELLING_IGNORE, "spelling-ignore", ReadOnly, Edit }, { LFUN_SPELLING_IGNORE, "spelling-ignore", ReadOnly, Edit },
/*!
* \var lyx::FuncCode lyx::LFUN_SPELLING_REMOVE
* \li Action: Remove the word under the cursor from the respective
* spell checker dictionary.
* \li Syntax: spelling-remove [<STRING>] [<LANG>]
* \li Params: <WORD>: word to remove
<LANG>: language name (see file languages)
* \li Origin: SWitt, 28 July 2010
* \endvar
*/
{ LFUN_SPELLING_REMOVE, "spelling-remove", ReadOnly, Edit },
/*! /*!
* \var lyx::FuncCode lyx::LFUN_THESAURUS_ENTRY * \var lyx::FuncCode lyx::LFUN_THESAURUS_ENTRY
* \li Action: Look up thesaurus entries with respect to the word under the cursor. * \li Action: Look up thesaurus entries with respect to the word under the cursor.

View File

@ -3169,19 +3169,19 @@ void Paragraph::updateWords()
} }
bool Paragraph::spellCheck(pos_type & from, pos_type & to, WordLangTuple & wl, SpellChecker::Result Paragraph::spellCheck(pos_type & from, pos_type & to, WordLangTuple & wl,
docstring_list & suggestions, bool do_suggestion) const docstring_list & suggestions, bool do_suggestion) const
{ {
SpellChecker * speller = theSpellChecker(); SpellChecker * speller = theSpellChecker();
if (!speller) if (!speller)
return false; return SpellChecker::WORD_OK;
if (!d->layout_->spellcheck || !inInset().allowSpellCheck()) if (!d->layout_->spellcheck || !inInset().allowSpellCheck())
return false; return SpellChecker::WORD_OK;
locateWord(from, to, WHOLE_WORD); locateWord(from, to, WHOLE_WORD);
if (from == to || from >= pos_type(d->text_.size())) if (from == to || from >= pos_type(d->text_.size()))
return false; return SpellChecker::WORD_OK;
docstring word = asString(from, to, AS_STR_INSETS); docstring word = asString(from, to, AS_STR_INSETS);
// Ignore words with digits // Ignore words with digits
@ -3200,29 +3200,19 @@ bool Paragraph::spellCheck(pos_type & from, pos_type & to, WordLangTuple & wl,
} }
wl = WordLangTuple(word, lang); wl = WordLangTuple(word, lang);
SpellChecker::Result res = ignored ? SpellChecker::Result res = ignored ?
SpellChecker::OK : speller->check(wl); SpellChecker::WORD_OK : speller->check(wl);
#if 0
// FIXME: the code below makes aspell abort if a word in an unknown
// language is checked.
// Just ignore any error that the spellchecker reports.
// FIXME: we should through out an exception and catch it in the GUI to
// display the error.
if (!speller->error().empty())
return false;
#endif
bool const misspelled = res != SpellChecker::OK bool const misspelled_ = SpellChecker::misspelled(res) ;
&& res != SpellChecker::IGNORED_WORD;
if (lyxrc.spellcheck_continuously) if (lyxrc.spellcheck_continuously)
d->fontlist_.setMisspelled(from, to, misspelled); d->fontlist_.setMisspelled(from, to, misspelled_);
if (misspelled && do_suggestion) if (misspelled_ && do_suggestion)
speller->suggest(wl, suggestions); speller->suggest(wl, suggestions);
else else
suggestions.clear(); suggestions.clear();
return misspelled; return res;
} }
@ -3232,7 +3222,8 @@ bool Paragraph::isMisspelled(pos_type pos) const
pos_type to = pos; pos_type to = pos;
WordLangTuple wl; WordLangTuple wl;
docstring_list suggestions; docstring_list suggestions;
return spellCheck(from, to, wl, suggestions, false); SpellChecker::Result res = spellCheck(from, to, wl, suggestions, false);
return SpellChecker::misspelled(res) ;
} }

View File

@ -17,6 +17,7 @@
#define PARAGRAPH_H #define PARAGRAPH_H
#include "FontEnums.h" #include "FontEnums.h"
#include "SpellChecker.h"
#include "insets/InsetCode.h" #include "insets/InsetCode.h"
@ -422,8 +423,8 @@ public:
/// Spellcheck word at position \p from and fill in found misspelled word /// Spellcheck word at position \p from and fill in found misspelled word
/// and \p suggestions if \p do_suggestion is true. /// and \p suggestions if \p do_suggestion is true.
/// \return true if pointed word is misspelled. /// \return result from spell checker, SpellChecker::UNKNOWN_WORD when misspelled.
bool spellCheck(pos_type & from, pos_type & to, WordLangTuple & wl, SpellChecker::Result spellCheck(pos_type & from, pos_type & to, WordLangTuple & wl,
docstring_list & suggestions, bool do_suggestion = true) const; docstring_list & suggestions, bool do_suggestion = true) const;
/// Spellcheck word at position \p pos. /// Spellcheck word at position \p pos.

View File

@ -32,19 +32,27 @@ public:
/// the result from checking a single word /// the result from checking a single word
enum Result { enum Result {
/// word is correct /// word is correct
OK = 1, WORD_OK = 1,
/// root of given word was found /// root of given word was found
ROOT, ROOT_FOUND,
/// word found through compound formation /// word found through compound formation
COMPOUND_WORD, COMPOUND_WORD,
/// word not found /// word not found
UNKNOWN_WORD, UNKNOWN_WORD,
/// number of other ignored "word" /// number of other ignored "word"
IGNORED_WORD IGNORED_WORD,
/// number of personal dictionary "word"
LEARNED_WORD
}; };
virtual ~SpellChecker() {} virtual ~SpellChecker() {}
/// does the spell check failed
static bool misspelled(Result res) {
return res != SpellChecker::WORD_OK
&& res != SpellChecker::IGNORED_WORD
&& res != SpellChecker::LEARNED_WORD; }
/// check the given word of the given lang code and return the result /// check the given word of the given lang code and return the result
virtual enum Result check(WordLangTuple const &) = 0; virtual enum Result check(WordLangTuple const &) = 0;
@ -54,6 +62,9 @@ public:
/// insert the given word into the personal dictionary /// insert the given word into the personal dictionary
virtual void insert(WordLangTuple const &) = 0; virtual void insert(WordLangTuple const &) = 0;
/// remove the given word from the personal dictionary
virtual void remove(WordLangTuple const &) = 0;
/// accept the given word temporarily /// accept the given word temporarily
virtual void accept(WordLangTuple const &) = 0; virtual void accept(WordLangTuple const &) = 0;

View File

@ -2044,6 +2044,25 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
break; break;
} }
case LFUN_SPELLING_REMOVE: {
docstring word = from_utf8(cmd.getArg(0));
Language * lang;
if (word.empty()) {
word = cur.selectionAsString(false);
// FIXME
if (word.size() > 100 || word.empty()) {
// Get word or selection
selectWordWhenUnderCursor(cur, WHOLE_WORD);
word = cur.selectionAsString(false);
}
lang = const_cast<Language *>(cur.getFont().language());
} else
lang = const_cast<Language *>(languages.getLanguage(cmd.getArg(1)));
WordLangTuple wl(word, lang);
theSpellChecker()->remove(wl);
break;
}
case LFUN_PARAGRAPH_PARAMS_APPLY: { case LFUN_PARAGRAPH_PARAMS_APPLY: {
// Given data, an encoding of the ParagraphParameters // Given data, an encoding of the ParagraphParameters
// generated in the Paragraph dialog, this function sets // generated in the Paragraph dialog, this function sets
@ -2591,6 +2610,7 @@ bool Text::getStatus(Cursor & cur, FuncRequest const & cmd,
case LFUN_SPELLING_ADD: case LFUN_SPELLING_ADD:
case LFUN_SPELLING_IGNORE: case LFUN_SPELLING_IGNORE:
case LFUN_SPELLING_REMOVE:
enable = theSpellChecker(); enable = theSpellChecker();
break; break;

View File

@ -46,6 +46,7 @@
#include "Paragraph.h" #include "Paragraph.h"
#include "ParIterator.h" #include "ParIterator.h"
#include "Session.h" #include "Session.h"
#include "SpellChecker.h"
#include "TextClass.h" #include "TextClass.h"
#include "TocBackend.h" #include "TocBackend.h"
#include "Toolbars.h" #include "Toolbars.h"
@ -730,39 +731,55 @@ void MenuDefinition::expandGraphicsGroups(BufferView const * bv)
void MenuDefinition::expandSpellingSuggestions(BufferView const * bv) void MenuDefinition::expandSpellingSuggestions(BufferView const * bv)
{ {
if (!bv || !lyxrc.spellcheck_continuously) if (!bv)
return; return;
WordLangTuple wl; WordLangTuple wl;
docstring_list suggestions; docstring_list suggestions;
pos_type from = bv->cursor().pos(); pos_type from = bv->cursor().pos();
pos_type to = from; pos_type to = from;
Paragraph const & par = bv->cursor().paragraph(); Paragraph const & par = bv->cursor().paragraph();
if (!par.spellCheck(from, to, wl, suggestions)) SpellChecker::Result res = par.spellCheck(from, to, wl, suggestions);
return; switch (res) {
LYXERR(Debug::GUI, "Misspelled Word! Suggested Words = "); case SpellChecker::UNKNOWN_WORD:
size_t i = 0; if (lyxrc.spellcheck_continuously) {
MenuItem item(MenuItem::Submenu, qt_("More Spelling Suggestions")); LYXERR(Debug::GUI, "Misspelled Word! Suggested Words = ");
item.setSubmenu(MenuDefinition(qt_("More Spelling Suggestions"))); size_t i = 0;
for (; i != suggestions.size(); ++i) { MenuItem item(MenuItem::Submenu, qt_("More Spelling Suggestions"));
docstring const & suggestion = suggestions[i]; item.setSubmenu(MenuDefinition(qt_("More Spelling Suggestions")));
LYXERR(Debug::GUI, suggestion); for (; i != suggestions.size(); ++i) {
MenuItem w(MenuItem::Command, toqstr(suggestion), docstring const & suggestion = suggestions[i];
FuncRequest(LFUN_WORD_REPLACE, suggestion)); LYXERR(Debug::GUI, suggestion);
if (i < 10) MenuItem w(MenuItem::Command, toqstr(suggestion),
add(w); FuncRequest(LFUN_WORD_REPLACE, suggestion));
else if (i < 10)
item.submenu().add(w); add(w);
else
item.submenu().add(w);
}
if (i >= 10)
add(item);
if (i > 0)
add(MenuItem(MenuItem::Separator));
docstring const arg = wl.word() + " " + from_ascii(wl.lang()->lang());
add(MenuItem(MenuItem::Command, qt_("Add to personal dictionary|c"),
FuncRequest(LFUN_SPELLING_ADD, arg)));
add(MenuItem(MenuItem::Command, qt_("Ignore all|I"),
FuncRequest(LFUN_SPELLING_IGNORE, arg)));
}
break;
case SpellChecker::LEARNED_WORD: {
LYXERR(Debug::GUI, "Learned Word.");
docstring const arg = wl.word() + " " + from_ascii(wl.lang()->lang());
add(MenuItem(MenuItem::Command, qt_("Remove from personal dictionary|r"),
FuncRequest(LFUN_SPELLING_REMOVE, arg)));
}
break;
case SpellChecker::WORD_OK:
case SpellChecker::COMPOUND_WORD:
case SpellChecker::ROOT_FOUND:
case SpellChecker::IGNORED_WORD:
break;
} }
if (i >= 10)
add(item);
if (i > 0)
add(MenuItem(MenuItem::Separator));
docstring const arg = wl.word() + " " + from_ascii(wl.lang()->lang());
add(MenuItem(MenuItem::Command, qt_("Add to personal dictionary|c"),
FuncRequest(LFUN_SPELLING_ADD, arg)));
add(MenuItem(MenuItem::Command, qt_("Ignore all|I"),
FuncRequest(LFUN_SPELLING_IGNORE, arg)));
} }
struct sortLanguageByName { struct sortLanguageByName {

View File

@ -16,16 +16,24 @@
extern "C" { extern "C" {
#endif #endif
typedef enum SpellCheckResult {
SPELL_CHECK_FAILED,
SPELL_CHECK_OK,
SPELL_CHECK_IGNORED,
SPELL_CHECK_LEARNED
} SpellCheckResult ;
typedef struct AppleSpellerRec * AppleSpeller ; typedef struct AppleSpellerRec * AppleSpeller ;
AppleSpeller newAppleSpeller(void); AppleSpeller newAppleSpeller(void);
void freeAppleSpeller(AppleSpeller speller); void freeAppleSpeller(AppleSpeller speller);
int checkAppleSpeller(AppleSpeller speller, const char * word, const char * lang); SpellCheckResult checkAppleSpeller(AppleSpeller speller, const char * word, const char * lang);
void ignoreAppleSpeller(AppleSpeller speller, const char * word); void ignoreAppleSpeller(AppleSpeller speller, const char * word);
size_t makeSuggestionAppleSpeller(AppleSpeller speller, const char * word, const char * lang); size_t makeSuggestionAppleSpeller(AppleSpeller speller, const char * word, const char * lang);
const char * getSuggestionAppleSpeller(AppleSpeller speller, size_t pos); const char * getSuggestionAppleSpeller(AppleSpeller speller, size_t pos);
void learnAppleSpeller(AppleSpeller speller, const char * word); void learnAppleSpeller(AppleSpeller speller, const char * word);
void unlearnAppleSpeller(AppleSpeller speller, const char * word);
int hasLanguageAppleSpeller(AppleSpeller speller, const char * lang); int hasLanguageAppleSpeller(AppleSpeller speller, const char * lang);
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -68,16 +68,16 @@ static NSString * toString(const char * word)
} }
int checkAppleSpeller(AppleSpeller speller, const char * word, const char * lang) SpellCheckResult checkAppleSpeller(AppleSpeller speller, const char * word, const char * lang)
{ {
if (!speller->checker || !lang || !word) if (!speller->checker || !lang || !word)
return 0; return SPELL_CHECK_FAILED;
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSString * word_ = toString(word); NSString * word_ = toString(word);
NSString * lang_ = toString(lang); NSString * lang_ = toString(lang);
NSRange result = [speller->checker NSRange match = [speller->checker
checkSpellingOfString:word_ checkSpellingOfString:word_
startingAt:0 startingAt:0
language:lang_ language:lang_
@ -85,11 +85,17 @@ int checkAppleSpeller(AppleSpeller speller, const char * word, const char * lang
inSpellDocumentWithTag:speller->doctag inSpellDocumentWithTag:speller->doctag
wordCount:NULL]; wordCount:NULL];
SpellCheckResult result = match.length == 0 ? SPELL_CHECK_OK : SPELL_CHECK_FAILED;
if (result == SPELL_CHECK_OK && [NSSpellChecker instancesRespondToSelector:@selector(hasLearnedWord:)]) {
if ([speller->checker hasLearnedWord:word_])
result = SPELL_CHECK_LEARNED;
}
[word_ release]; [word_ release];
[lang_ release]; [lang_ release];
[pool release]; [pool release];
return (result.length ? 0 : 1); return result;
} }
@ -172,7 +178,7 @@ void learnAppleSpeller(AppleSpeller speller, const char * word)
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSString * word_ = toString(word); NSString * word_ = toString(word);
if ([NSSpellChecker instancesRespondToSelector:@selector(learnWord)]) if ([NSSpellChecker instancesRespondToSelector:@selector(learnWord:)])
[speller->checker learnWord:word_]; [speller->checker learnWord:word_];
[word_ release]; [word_ release];
@ -181,13 +187,29 @@ void learnAppleSpeller(AppleSpeller speller, const char * word)
} }
void unlearnAppleSpeller(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(word);
if ([NSSpellChecker instancesRespondToSelector:@selector(unlearnWord:)])
[speller->checker unlearnWord:word_];
[word_ release];
[pool release];
#endif
}
int hasLanguageAppleSpeller(AppleSpeller speller, const char * lang) int hasLanguageAppleSpeller(AppleSpeller speller, const char * lang)
{ {
BOOL result = NO; BOOL result = NO;
#if defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && (__MAC_OS_X_VERSION_MAX_ALLOWED >= 1050) #if defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && (__MAC_OS_X_VERSION_MAX_ALLOWED >= 1050)
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSString * lang_ = toString(lang); NSString * lang_ = toString(lang);
if ([NSSpellChecker instancesRespondToSelector:@selector(availableLanguages)]) { if ([NSSpellChecker instancesRespondToSelector:@selector(availableLanguages:)]) {
NSArray * languages = [speller->checker availableLanguages]; NSArray * languages = [speller->checker availableLanguages];
for (NSString *element in languages) { for (NSString *element in languages) {