mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-11-25 10:58:52 +00:00
* add support for the enchant spell checker (bug 6226).
SCons might be broken. git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@33157 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
parent
4322d35b15
commit
7746747506
@ -23,6 +23,26 @@ AC_DEFUN([CHECK_WITH_ASPELL],
|
||||
fi
|
||||
])
|
||||
|
||||
# Macro to add for using enchant spellchecker libraries! -*- sh -*-
|
||||
AC_DEFUN([CHECK_WITH_ENCHANT],
|
||||
[
|
||||
lyx_use_enchant=true
|
||||
AC_ARG_WITH(enchant, AC_HELP_STRING([--without-enchant],[do not check for Enchant library]))
|
||||
test "$with_enchant" = "no" && lyx_use_enchant=false
|
||||
|
||||
if $lyx_use_enchant; then
|
||||
PKG_CHECK_MODULES([ENCHANT], [enchant], [], [lyx_use_enchant=false])
|
||||
AC_MSG_CHECKING([whether to use enchant])
|
||||
if $lyx_use_enchant ; then
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(USE_ENCHANT, 1, [Define as 1 to use the enchant library])
|
||||
lyx_flags="$lyx_flags use-enchant"
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
fi
|
||||
])
|
||||
|
||||
# Macro to add for using hunspell spellchecker libraries! -*- sh -*-
|
||||
AC_DEFUN([CHECK_WITH_HUNSPELL],
|
||||
[
|
||||
@ -55,6 +75,11 @@ AC_DEFUN([LYX_CHECK_SPELL_ENGINES],
|
||||
|
||||
AM_CONDITIONAL(USE_ASPELL, $lyx_use_aspell)
|
||||
|
||||
lyx_use_enchant=false
|
||||
CHECK_WITH_ENCHANT
|
||||
|
||||
AM_CONDITIONAL(USE_ENCHANT, $lyx_use_enchant)
|
||||
|
||||
lyx_use_hunspell=false
|
||||
CHECK_WITH_HUNSPELL
|
||||
|
||||
|
@ -136,7 +136,7 @@ opts.AddVariables(
|
||||
) ),
|
||||
#
|
||||
EnumVariable('spell', 'Choose spell checker to use.', 'auto',
|
||||
allowed_values = ('aspell', 'hunspell', 'auto', 'no') ),
|
||||
allowed_values = ('aspell', 'enchant', 'hunspell', 'auto', 'no') ),
|
||||
# packaging method
|
||||
EnumVariable('packaging', 'Packaging method to use.', default_packaging_method,
|
||||
allowed_values = ('windows', 'posix', 'macosx')),
|
||||
@ -810,8 +810,14 @@ else:
|
||||
# determine headers to use
|
||||
spell_opt = ARGUMENTS.get('spell', 'auto')
|
||||
env['USE_ASPELL'] = False
|
||||
env['USE_ENCHANT'] = False
|
||||
env['USE_HUNSPELL'] = False
|
||||
if spell_opt in ['auto', 'aspell'] and conf.CheckLib(aspell_lib):
|
||||
spell_engine = 'USE_ASPELL'
|
||||
elif spell_opt in ['auto', 'enchant'] and conf.CheckLib('enchant'):
|
||||
spell_engine = 'USE_ENCHANT'
|
||||
elif spell_opt in ['auto', 'hunspell'] and conf.CheckLib('enchant'):
|
||||
spell_engine = 'USE_HUNSPELL'
|
||||
else:
|
||||
spell_engine = None
|
||||
|
||||
@ -1069,7 +1075,7 @@ char * strerror(int n);
|
||||
)
|
||||
|
||||
# these keys are needed in env
|
||||
for key in ['USE_ASPELL', 'HAVE_FCNTL',\
|
||||
for key in ['USE_ASPELL', 'USE_ENCHANT', 'USE_HUNSPELL', 'HAVE_FCNTL',\
|
||||
'HAVE_LIBGDI32', 'HAVE_LIBAIKSAURUS', 'AIKSAURUS_LIB']:
|
||||
# USE_ASPELL etc does not go through result
|
||||
if result.has_key(key):
|
||||
@ -1227,6 +1233,8 @@ libs = [
|
||||
('HAVE_LIBGDI32', 'gdi32'),
|
||||
('HAVE_LIBAIKSAURUS', env['AIKSAURUS_LIB']),
|
||||
('USE_ASPELL', aspell_lib),
|
||||
('USE_ENCHANT', 'enchant'),
|
||||
('USE_HUNSPELL', 'hunspell')
|
||||
]
|
||||
|
||||
for lib in libs:
|
||||
@ -1547,6 +1555,10 @@ Alias('tex2lyx', tex2lyx)
|
||||
#
|
||||
if env.has_key('USE_ASPELL') and env['USE_ASPELL']:
|
||||
src_post_files.append('AspellChecker.cpp')
|
||||
elif env.has_key('USE_ENCHANT') and env['USE_ENCHANT']:
|
||||
src_post_files.append('EnchantChecker.cpp')
|
||||
elif env.has_key('USE_HUNSPELL') and env['USE_HUNSPELL']:
|
||||
src_post_files.append('HunspellChecker.cpp')
|
||||
|
||||
# tells scons how to get these moced files, although not all moced files are needed
|
||||
# (or are actually generated).
|
||||
|
@ -60,6 +60,7 @@ src_header_files = Split('''
|
||||
Dimension.h
|
||||
DispatchResult.h
|
||||
DocIterator.h
|
||||
EnchantChecker.h
|
||||
Encoding.h
|
||||
ErrorList.h
|
||||
Exporter.h
|
||||
@ -251,6 +252,7 @@ src_post_files = Split('''
|
||||
|
||||
src_extra_src_files = Split('''
|
||||
AspellChecker.cpp
|
||||
EnchantChecker.cpp
|
||||
HunspellChecker.cpp
|
||||
main.cpp
|
||||
Section.cpp
|
||||
|
163
src/EnchantChecker.cpp
Normal file
163
src/EnchantChecker.cpp
Normal file
@ -0,0 +1,163 @@
|
||||
/**
|
||||
* \file EnchantChecker.cpp
|
||||
* This file is part of LyX, the document processor.
|
||||
* Licence details can be found in the file COPYING.
|
||||
*
|
||||
* \author Caolán McNamara
|
||||
* \author Jürgen Spitzmüller
|
||||
*
|
||||
* Full author contact details are available in file CREDITS.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <enchant++.h>
|
||||
|
||||
#include "EnchantChecker.h"
|
||||
#include "LyXRC.h"
|
||||
#include "WordLangTuple.h"
|
||||
|
||||
#include "support/lassert.h"
|
||||
#include "support/debug.h"
|
||||
#include "support/docstring_list.h"
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace lyx {
|
||||
|
||||
namespace {
|
||||
|
||||
struct Speller {
|
||||
enchant::Dict * speller;
|
||||
};
|
||||
|
||||
typedef std::map<std::string, Speller> Spellers;
|
||||
|
||||
} // anon namespace
|
||||
|
||||
struct EnchantChecker::Private
|
||||
{
|
||||
Private() {}
|
||||
|
||||
~Private();
|
||||
|
||||
/// add a speller of the given language
|
||||
enchant::Dict * addSpeller(string const & lang);
|
||||
|
||||
///
|
||||
enchant::Dict * speller(string const & lang);
|
||||
|
||||
/// the spellers
|
||||
Spellers spellers_;
|
||||
};
|
||||
|
||||
|
||||
EnchantChecker::Private::~Private()
|
||||
{
|
||||
Spellers::iterator it = spellers_.begin();
|
||||
Spellers::iterator end = spellers_.end();
|
||||
|
||||
for (; it != end; ++it) {
|
||||
delete it->second.speller;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
enchant::Dict * EnchantChecker::Private::addSpeller(string const & lang)
|
||||
{
|
||||
enchant::Broker * instance = enchant::Broker::instance();
|
||||
enchant::Dict * dict = instance->request_dict(lang);
|
||||
|
||||
if (dict) {
|
||||
Speller m;
|
||||
m.speller = dict;
|
||||
spellers_[lang] = m;
|
||||
return m.speller;
|
||||
}
|
||||
// FIXME error handling?
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
enchant::Dict * EnchantChecker::Private::speller(string const & lang)
|
||||
{
|
||||
Spellers::iterator it = spellers_.find(lang);
|
||||
if (it != spellers_.end())
|
||||
return it->second.speller;
|
||||
|
||||
return addSpeller(lang);
|
||||
}
|
||||
|
||||
|
||||
EnchantChecker::EnchantChecker(): d(new Private)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
EnchantChecker::~EnchantChecker()
|
||||
{
|
||||
delete d;
|
||||
}
|
||||
|
||||
|
||||
SpellChecker::Result EnchantChecker::check(WordLangTuple const & word)
|
||||
{
|
||||
enchant::Dict * m = d->speller(word.lang_code());
|
||||
|
||||
if (!m)
|
||||
return OK;
|
||||
|
||||
std::string utf8word(to_utf8(word.word()));
|
||||
|
||||
if (m->check(utf8word))
|
||||
return OK;
|
||||
|
||||
return UNKNOWN_WORD;
|
||||
}
|
||||
|
||||
|
||||
void EnchantChecker::insert(WordLangTuple const & word)
|
||||
{
|
||||
Spellers::iterator it = d->spellers_.find(word.lang_code());
|
||||
if (it != d->spellers_.end())
|
||||
it->second.speller->add(to_utf8(word.word()));
|
||||
}
|
||||
|
||||
|
||||
void EnchantChecker::accept(WordLangTuple const & word)
|
||||
{
|
||||
Spellers::iterator it = d->spellers_.find(word.lang_code());
|
||||
if (it != d->spellers_.end())
|
||||
it->second.speller->add_to_session(to_utf8(word.word()));
|
||||
}
|
||||
|
||||
|
||||
void EnchantChecker::suggest(WordLangTuple const & wl,
|
||||
docstring_list & suggestions)
|
||||
{
|
||||
suggestions.clear();
|
||||
enchant::Dict * m = d->speller(wl.lang_code());
|
||||
|
||||
if (!m)
|
||||
return;
|
||||
|
||||
string utf8word = to_utf8(wl.word());
|
||||
|
||||
vector<string> suggs = m->suggest(utf8word);
|
||||
vector<string>::const_iterator it = suggs.begin();
|
||||
|
||||
for (; it != suggs.end(); ++it)
|
||||
suggestions.push_back(from_utf8(*it));
|
||||
}
|
||||
|
||||
|
||||
docstring const EnchantChecker::error()
|
||||
{
|
||||
return docstring();
|
||||
}
|
||||
|
||||
|
||||
} // namespace lyx
|
49
src/EnchantChecker.h
Normal file
49
src/EnchantChecker.h
Normal file
@ -0,0 +1,49 @@
|
||||
// -*- C++ -*-
|
||||
/**
|
||||
* \file EnchantChecker.h
|
||||
* This file is part of LyX, the document processor.
|
||||
* Licence details can be found in the file COPYING.
|
||||
*
|
||||
* \author Caolán McNamara
|
||||
* \author Jürgen Spitzmüller
|
||||
*
|
||||
* Full author contact details are available in file CREDITS.
|
||||
*/
|
||||
|
||||
#ifndef LYX_ENCHANT_H
|
||||
#define LYX_ENCHANT_H
|
||||
|
||||
#include "SpellChecker.h"
|
||||
|
||||
namespace enchant {
|
||||
class Dict;
|
||||
}
|
||||
|
||||
namespace lyx {
|
||||
|
||||
class BufferParams;
|
||||
|
||||
|
||||
class EnchantChecker : public SpellChecker {
|
||||
public:
|
||||
EnchantChecker();
|
||||
~EnchantChecker();
|
||||
|
||||
/// SpellChecker inherited methods.
|
||||
///@{
|
||||
enum Result check(WordLangTuple const &);
|
||||
void suggest(WordLangTuple const &, docstring_list &);
|
||||
void insert(WordLangTuple const &);
|
||||
void accept(WordLangTuple const &);
|
||||
docstring const error();
|
||||
///@}
|
||||
|
||||
private:
|
||||
struct Private;
|
||||
Private * d;
|
||||
};
|
||||
|
||||
|
||||
} // namespace lyx
|
||||
|
||||
#endif // LYX_ENCHANT_H
|
14
src/LyX.cpp
14
src/LyX.cpp
@ -25,6 +25,7 @@
|
||||
#include "ConverterCache.h"
|
||||
#include "Converter.h"
|
||||
#include "CutAndPaste.h"
|
||||
#include "EnchantChecker.h"
|
||||
#include "Encoding.h"
|
||||
#include "ErrorList.h"
|
||||
#include "Format.h"
|
||||
@ -122,7 +123,7 @@ void reconfigureUserLyXDir()
|
||||
/// The main application class private implementation.
|
||||
struct LyX::Impl
|
||||
{
|
||||
Impl() : spell_checker_(0), aspell_checker_(0), hunspell_checker_(0)
|
||||
Impl() : spell_checker_(0), aspell_checker_(0), enchant_checker_(0), hunspell_checker_(0)
|
||||
{
|
||||
// Set the default User Interface language as soon as possible.
|
||||
// The language used will be derived from the environment
|
||||
@ -133,6 +134,7 @@ struct LyX::Impl
|
||||
~Impl()
|
||||
{
|
||||
delete aspell_checker_;
|
||||
delete enchant_checker_;
|
||||
delete hunspell_checker_;
|
||||
}
|
||||
|
||||
@ -182,6 +184,8 @@ struct LyX::Impl
|
||||
///
|
||||
SpellChecker * aspell_checker_;
|
||||
///
|
||||
SpellChecker * enchant_checker_;
|
||||
///
|
||||
SpellChecker * hunspell_checker_;
|
||||
};
|
||||
|
||||
@ -1288,6 +1292,14 @@ void setSpellChecker()
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#if defined(USE_ENCHANT)
|
||||
if (lyxrc.spellchecker == "enchant") {
|
||||
if (!singleton_->pimpl_->enchant_checker_)
|
||||
singleton_->pimpl_->enchant_checker_ = new EnchantChecker();
|
||||
singleton_->pimpl_->spell_checker_ = singleton_->pimpl_->enchant_checker_;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#if defined(USE_HUNSPELL)
|
||||
if (lyxrc.spellchecker == "hunspell") {
|
||||
if (!singleton_->pimpl_->hunspell_checker_)
|
||||
|
@ -4,7 +4,7 @@ include $(top_srcdir)/config/common.am
|
||||
|
||||
DISTCLEANFILES += config.h libintl.h
|
||||
|
||||
AM_CPPFLAGS += $(PCH_FLAGS) -I$(top_srcdir)/src $(BOOST_INCLUDES)
|
||||
AM_CPPFLAGS += $(PCH_FLAGS) -I$(top_srcdir)/src $(BOOST_INCLUDES) $(ENCHANT_CFLAGS)
|
||||
AM_CPPFLAGS += $(QT4_CPPFLAGS) $(QT4_CORE_INCLUDES)
|
||||
|
||||
if BUILD_CLIENT_SUBDIR
|
||||
@ -21,7 +21,7 @@ EXTRA_DIST = Section.h \
|
||||
pch.h
|
||||
|
||||
OTHERLIBS = $(BOOST_LIBS) $(INTLLIBS) $(MYTHES_LIBS) $(AIKSAURUS_LIBS) \
|
||||
@LIBS@ $(SOCKET_LIBS) $(LIBSHLWAPI) $(LIBPSAPI)
|
||||
$(ENCHANT_LIBS) @LIBS@ $(SOCKET_LIBS) $(LIBSHLWAPI) $(LIBPSAPI)
|
||||
|
||||
noinst_LIBRARIES = liblyxcore.a
|
||||
bin_PROGRAMS = lyx
|
||||
@ -52,6 +52,10 @@ if USE_ASPELL
|
||||
ASPELL = AspellChecker.cpp AspellChecker.h
|
||||
endif
|
||||
|
||||
if USE_ENCHANT
|
||||
ENCHANT = EnchantChecker.cpp EnchantChecker.h
|
||||
endif
|
||||
|
||||
if USE_HUNSPELL
|
||||
HUNSPELL = HunspellChecker.cpp HunspellChecker.h
|
||||
endif
|
||||
@ -71,6 +75,7 @@ lyx_SOURCES = \
|
||||
Compare.h \
|
||||
Dimension.cpp \
|
||||
Dimension.h \
|
||||
$(ENCHANT) \
|
||||
$(HUNSPELL) \
|
||||
PrinterParams.cpp \
|
||||
PrinterParams.h \
|
||||
|
@ -1312,10 +1312,13 @@ PrefSpellchecker::PrefSpellchecker(GuiPreferences * form)
|
||||
setupUi(this);
|
||||
|
||||
#if defined(USE_ASPELL)
|
||||
spellcheckerCB->addItem("aspell");
|
||||
spellcheckerCB->addItem(qt_("aspell"), QString("aspell"));
|
||||
#endif
|
||||
#if defined(USE_ENCHANT)
|
||||
spellcheckerCB->addItem(qt_("enchant"), QString("enchant"));
|
||||
#endif
|
||||
#if defined(USE_HUNSPELL)
|
||||
spellcheckerCB->addItem("hunspell");
|
||||
spellcheckerCB->addItem(qt_("hunspell"), QString("hunspell"));
|
||||
#endif
|
||||
|
||||
if (theSpellChecker()) {
|
||||
@ -1341,7 +1344,8 @@ PrefSpellchecker::PrefSpellchecker(GuiPreferences * form)
|
||||
|
||||
void PrefSpellchecker::apply(LyXRC & rc) const
|
||||
{
|
||||
rc.spellchecker = fromqstr(spellcheckerCB->currentText());
|
||||
rc.spellchecker = fromqstr(spellcheckerCB->itemData(
|
||||
spellcheckerCB->currentIndex()).toString());
|
||||
rc.spellchecker_alt_lang = fromqstr(altLanguageED->text());
|
||||
rc.spellchecker_esc_chars = fromqstr(escapeCharactersED->text());
|
||||
rc.spellchecker_accept_compound = compoundWordCB->isChecked();
|
||||
@ -1351,8 +1355,8 @@ void PrefSpellchecker::apply(LyXRC & rc) const
|
||||
|
||||
void PrefSpellchecker::update(LyXRC const & rc)
|
||||
{
|
||||
spellcheckerCB->setCurrentIndex(spellcheckerCB->findText(
|
||||
toqstr(rc.spellchecker)));
|
||||
spellcheckerCB->setCurrentIndex(
|
||||
spellcheckerCB->findData(toqstr(rc.spellchecker)));
|
||||
altLanguageED->setText(toqstr(rc.spellchecker_alt_lang));
|
||||
escapeCharactersED->setText(toqstr(rc.spellchecker_esc_chars));
|
||||
compoundWordCB->setChecked(rc.spellchecker_accept_compound);
|
||||
|
Loading…
Reference in New Issue
Block a user