]> git.lyx.org Git - lyx.git/blobdiff - src/AspellChecker.cpp
GuiBox.cpp: fix #6721
[lyx.git] / src / AspellChecker.cpp
index 55441516d7d71e32a37e5dfb663d4f776ce0fe5a..a7a1d2977a0611ef0118c9a42e4e1fafeadfca6b 100644 (file)
@@ -19,6 +19,9 @@
 #include "support/debug.h"
 #include "support/docstring_list.h"
 
+#include "support/FileName.h"
+#include "support/Path.h"
+
 #include <aspell.h>
 
 #include <map>
@@ -83,10 +86,48 @@ AspellChecker::Private::~Private()
 }
 
 
+AspellConfig * getConfig()
+{
+       AspellConfig * config = new_aspell_config();
+#ifdef __APPLE__
+       char buf[2048] ;
+       bool have_dict = false;
+#ifdef ASPELL_FRAMEWORK
+       char * framework = ASPELL_FRAMEWORK ;
+
+       if ( strlen(framework) && getPrivateFrameworkPathName(buf, sizeof(buf), framework) ) {
+               lyx::support::FileName const base(buf);
+               lyx::support::FileName const data(base.absFileName() + "/Resources/data");
+               lyx::support::FileName const dict(base.absFileName() + "/Resources/dict");
+               LYXERR(Debug::FILES, "aspell bundle path: " << buf);
+               have_dict = dict.isDirectory() && data.isDirectory();
+               if (have_dict) {
+                       aspell_config_replace(config, "dict-dir", dict.absFileName().c_str());
+                       aspell_config_replace(config, "data-dir", data.absFileName().c_str());
+                       LYXERR(Debug::FILES, "aspell dict: " << dict);
+               }
+       }
+#endif
+       if ( !have_dict ) {
+               lyx::support::FileName const base("/opt/local"); // check for mac-ports data
+               lyx::support::FileName const data(base.absFileName() + "/lib/aspell-0.60");
+               lyx::support::FileName const dict(base.absFileName() + "/share/aspell");
+               have_dict = dict.isDirectory() && data.isDirectory();
+               if (have_dict) {
+                       aspell_config_replace(config, "dict-dir", dict.absFileName().c_str());
+                       aspell_config_replace(config, "data-dir", data.absFileName().c_str());
+                       LYXERR(Debug::FILES, "aspell dict: " << dict);
+               }
+       }
+#endif
+       return config ;
+}
+
+
 AspellSpeller * AspellChecker::Private::addSpeller(string const & lang,
                                                   string const & variety)
 {
-       AspellConfig * config = new_aspell_config();
+       AspellConfig * config = getConfig();
        // Aspell supports both languages and varieties (such as German
        // old vs. new spelling). The respective naming convention is
        // lang_REGION-variety (e.g. de_DE-alt).
@@ -107,6 +148,7 @@ AspellSpeller * AspellChecker::Private::addSpeller(string const & lang,
        else
                // Report run-together words as errors
                aspell_config_replace(config, "run-together", "false");
+
        AspellCanHaveError * err = new_aspell_speller(config);
        if (spell_error_object)
                delete_aspell_can_have_error(spell_error_object);
@@ -116,6 +158,7 @@ AspellSpeller * AspellChecker::Private::addSpeller(string const & lang,
                // FIXME: We should we indicate somehow that this language is not
                // supported.
                spell_error_object = err;
+               LYXERR(Debug::FILES, "aspell error: " << aspell_error_message(err));
                return 0;
        }
        Speller m;
@@ -161,7 +204,7 @@ SpellChecker::Result AspellChecker::check(WordLangTuple const & word)
 {
   
        AspellSpeller * m =
-               d->speller(word.lang_code(), word.lang_variety());
+               d->speller(word.lang()->code(), word.lang()->variety());
 
        if (!m)
                return OK;
@@ -180,7 +223,7 @@ SpellChecker::Result AspellChecker::check(WordLangTuple const & word)
 void AspellChecker::insert(WordLangTuple const & word)
 {
        Spellers::iterator it = d->spellers_.find(
-               d->spellerID(word.lang_code(), word.lang_variety()));
+               d->spellerID(word.lang()->code(), word.lang()->variety()));
        if (it != d->spellers_.end())
                aspell_speller_add_to_personal(it->second.speller, to_utf8(word.word()).c_str(), -1);
 }
@@ -189,7 +232,7 @@ void AspellChecker::insert(WordLangTuple const & word)
 void AspellChecker::accept(WordLangTuple const & word)
 {
        Spellers::iterator it = d->spellers_.find(
-               d->spellerID(word.lang_code(), word.lang_variety()));
+               d->spellerID(word.lang()->code(), word.lang()->variety()));
        if (it != d->spellers_.end())
                aspell_speller_add_to_session(it->second.speller, to_utf8(word.word()).c_str(), -1);
 }
@@ -200,7 +243,7 @@ void AspellChecker::suggest(WordLangTuple const & wl,
 {
        suggestions.clear();
        AspellSpeller * m =
-               d->speller(wl.lang_code(), wl.lang_variety());
+               d->speller(wl.lang()->code(), wl.lang()->variety());
 
        if (!m)
                return;
@@ -223,6 +266,42 @@ void AspellChecker::suggest(WordLangTuple const & wl,
 }
 
 
+bool AspellChecker::hasDictionary(Language const * lang) const
+{
+       if (!lang)
+               return false;
+       // code taken from aspell's list-dicts example
+       AspellConfig * config;
+       AspellDictInfoList * dlist;
+       AspellDictInfoEnumeration * dels;
+       const AspellDictInfo * entry;
+
+       config = getConfig();
+
+       /* the returned pointer should _not_ need to be deleted */
+       dlist = get_aspell_dict_info_list(config);
+
+       /* config is no longer needed */
+       delete_aspell_config(config);
+
+       dels = aspell_dict_info_list_elements(dlist);
+
+       bool have = false;
+       while ((entry = aspell_dict_info_enumeration_next(dels)) != 0)
+       {
+               if (entry->code == lang->code()
+                   && (lang->variety().empty() || entry->jargon == lang->variety())) {
+                       have = true;
+                       break;
+               }
+       }
+
+       delete_aspell_dict_info_enumeration(dels);
+
+       return have;
+}
+
+
 docstring const AspellChecker::error()
 {
        char const * err = 0;