mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-11-25 19:07:45 +00:00
Meet per-document spelling dictionaries (fixes #86 [sic!])
Now who can beat that? ;-)
This commit is contained in:
parent
92c6c3b950
commit
07396ab244
@ -116,6 +116,9 @@
|
|||||||
cursor in the search cache that is used by word-find[-backward|-forward] if no argument
|
cursor in the search cache that is used by word-find[-backward|-forward] if no argument
|
||||||
is given to those.
|
is given to those.
|
||||||
|
|
||||||
|
* spelling-add-local adds words for a given language to the document's local spelling
|
||||||
|
dictionary.
|
||||||
|
|
||||||
* inset-split is a new convenience function that splits an inset into two at the given
|
* inset-split is a new convenience function that splits an inset into two at the given
|
||||||
cursor position. This is only implemented for text insets currently.
|
cursor position. This is only implemented for text insets currently.
|
||||||
|
|
||||||
|
@ -4396,6 +4396,15 @@ def revert_koma_frontispiece(document):
|
|||||||
document.append_local_layout(frontispiece_def)
|
document.append_local_layout(frontispiece_def)
|
||||||
|
|
||||||
|
|
||||||
|
def revert_spellchecker_ignore(document):
|
||||||
|
"""Revert document spellchecker disctionary"""
|
||||||
|
i = 0
|
||||||
|
while True:
|
||||||
|
i = find_token(document.header, "\\spellchecker_ignore")
|
||||||
|
if i == -1:
|
||||||
|
return
|
||||||
|
del document.header[i]
|
||||||
|
|
||||||
##
|
##
|
||||||
# Conversion hub
|
# Conversion hub
|
||||||
#
|
#
|
||||||
@ -4463,10 +4472,12 @@ convert = [
|
|||||||
[603, []],
|
[603, []],
|
||||||
[604, []],
|
[604, []],
|
||||||
[605, [convert_vcolumns2]],
|
[605, [convert_vcolumns2]],
|
||||||
[606, [convert_koma_frontispiece]]
|
[606, [convert_koma_frontispiece]],
|
||||||
|
[607, []]
|
||||||
]
|
]
|
||||||
|
|
||||||
revert = [[605, [revert_koma_frontispiece]],
|
revert = [[606, [revert_spellchecker_ignore]],
|
||||||
|
[605, [revert_koma_frontispiece]],
|
||||||
[604, [revert_vcolumns2]],
|
[604, [revert_vcolumns2]],
|
||||||
[603, [revert_branch_darkcols]],
|
[603, [revert_branch_darkcols]],
|
||||||
[602, [revert_darkmode_graphics]],
|
[602, [revert_darkmode_graphics]],
|
||||||
|
@ -78,13 +78,23 @@ string AppleSpellChecker::Private::toString(SpellCheckResult status)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SpellChecker::Result AppleSpellChecker::check(WordLangTuple const & word)
|
SpellChecker::Result AppleSpellChecker::check(WordLangTuple const & word,
|
||||||
|
std::vector<WordLangTuple> docdict)
|
||||||
{
|
{
|
||||||
if (!hasDictionary(word.lang()))
|
if (!hasDictionary(word.lang()))
|
||||||
return NO_DICTIONARY;
|
return NO_DICTIONARY;
|
||||||
|
|
||||||
string const word_str = to_utf8(word.word());
|
string const word_str = to_utf8(word.word());
|
||||||
string const lang = d->languageMap[word.lang()->lang()];
|
string const lang = d->languageMap[word.lang()->lang()];
|
||||||
|
|
||||||
|
vector<WordLangTuple>::const_iterator it = docdict.begin();
|
||||||
|
for (; it != docdict.end(); ++it) {
|
||||||
|
if (it->lang()->code() != word.lang()->code())
|
||||||
|
continue;
|
||||||
|
if (it->word() == word.word())
|
||||||
|
return LEARNED_WORD;
|
||||||
|
}
|
||||||
|
|
||||||
SpellCheckResult result =
|
SpellCheckResult result =
|
||||||
AppleSpeller_check(d->speller,
|
AppleSpeller_check(d->speller,
|
||||||
word_str.c_str(), lang.c_str());
|
word_str.c_str(), lang.c_str());
|
||||||
|
@ -24,7 +24,8 @@ public:
|
|||||||
|
|
||||||
/// \name SpellChecker inherited methods
|
/// \name SpellChecker inherited methods
|
||||||
//@{
|
//@{
|
||||||
enum Result check(WordLangTuple const &) override;
|
enum Result check(WordLangTuple const &,
|
||||||
|
std::vector<WordLangTuple> const &) override;
|
||||||
void suggest(WordLangTuple const &, docstring_list &) override;
|
void suggest(WordLangTuple const &, docstring_list &) override;
|
||||||
void stem(WordLangTuple const &, docstring_list &) override {}
|
void stem(WordLangTuple const &, docstring_list &) override {}
|
||||||
void insert(WordLangTuple const &) override;
|
void insert(WordLangTuple const &) override;
|
||||||
|
@ -428,7 +428,8 @@ AspellChecker::~AspellChecker()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SpellChecker::Result AspellChecker::check(WordLangTuple const & word)
|
SpellChecker::Result AspellChecker::check(WordLangTuple const & word,
|
||||||
|
vector<WordLangTuple> const & docdict)
|
||||||
{
|
{
|
||||||
AspellSpeller * m = d->speller(word.lang());
|
AspellSpeller * m = d->speller(word.lang());
|
||||||
|
|
||||||
@ -439,6 +440,13 @@ SpellChecker::Result AspellChecker::check(WordLangTuple const & word)
|
|||||||
// MSVC compiled Aspell doesn't like it.
|
// MSVC compiled Aspell doesn't like it.
|
||||||
return WORD_OK;
|
return WORD_OK;
|
||||||
|
|
||||||
|
vector<WordLangTuple>::const_iterator it = docdict.begin();
|
||||||
|
for (; it != docdict.end(); ++it) {
|
||||||
|
if (it->lang()->code() != word.lang()->code())
|
||||||
|
continue;
|
||||||
|
if (it->word() == word.word())
|
||||||
|
return LEARNED_WORD;
|
||||||
|
}
|
||||||
SpellChecker::Result rc = d->check(m, word);
|
SpellChecker::Result rc = d->check(m, word);
|
||||||
return (rc == WORD_OK && d->learned(word)) ? LEARNED_WORD : rc;
|
return (rc == WORD_OK && d->learned(word)) ? LEARNED_WORD : rc;
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,8 @@ public:
|
|||||||
|
|
||||||
/// \name SpellChecker inherited methods
|
/// \name SpellChecker inherited methods
|
||||||
//@{
|
//@{
|
||||||
enum Result check(WordLangTuple const &) override;
|
enum Result check(WordLangTuple const &,
|
||||||
|
std::vector<WordLangTuple> const &) override;
|
||||||
void suggest(WordLangTuple const &, docstring_list &) override;
|
void suggest(WordLangTuple const &, docstring_list &) override;
|
||||||
void stem(WordLangTuple const &, docstring_list &) override {}
|
void stem(WordLangTuple const &, docstring_list &) override {}
|
||||||
void insert(WordLangTuple const &) override;
|
void insert(WordLangTuple const &) override;
|
||||||
|
@ -961,6 +961,7 @@ int Buffer::readHeader(Lexer & lex)
|
|||||||
params().biblatex_citestyle.erase();
|
params().biblatex_citestyle.erase();
|
||||||
params().multibib.erase();
|
params().multibib.erase();
|
||||||
params().lineno_opts.clear();
|
params().lineno_opts.clear();
|
||||||
|
params().spellignore().clear();
|
||||||
|
|
||||||
for (int i = 0; i < 4; ++i) {
|
for (int i = 0; i < 4; ++i) {
|
||||||
params().user_defined_bullet(i) = ITEMIZE_DEFAULTS[i];
|
params().user_defined_bullet(i) = ITEMIZE_DEFAULTS[i];
|
||||||
|
@ -341,6 +341,7 @@ public:
|
|||||||
|
|
||||||
AuthorList authorlist;
|
AuthorList authorlist;
|
||||||
BranchList branchlist;
|
BranchList branchlist;
|
||||||
|
IgnoreList spellignore;
|
||||||
Bullet temp_bullets[4];
|
Bullet temp_bullets[4];
|
||||||
Bullet user_defined_bullets[4];
|
Bullet user_defined_bullets[4];
|
||||||
IndicesList indiceslist;
|
IndicesList indiceslist;
|
||||||
@ -600,6 +601,21 @@ IndicesList const & BufferParams::indiceslist() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
typedef std::vector<WordLangTuple> IgnoreList;
|
||||||
|
|
||||||
|
|
||||||
|
IgnoreList & BufferParams::spellignore()
|
||||||
|
{
|
||||||
|
return pimpl_->spellignore;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
IgnoreList const & BufferParams::spellignore() const
|
||||||
|
{
|
||||||
|
return pimpl_->spellignore;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Bullet & BufferParams::temp_bullet(lyx::size_type const index)
|
Bullet & BufferParams::temp_bullet(lyx::size_type const index)
|
||||||
{
|
{
|
||||||
LASSERT(index < 4, return pimpl_->temp_bullets[0]);
|
LASSERT(index < 4, return pimpl_->temp_bullets[0]);
|
||||||
@ -1032,6 +1048,14 @@ string BufferParams::readToken(Lexer & lex, string const & token,
|
|||||||
lcolor.setColor(to_utf8(shortcut)+ "@" + filename.absFileName(), color);
|
lcolor.setColor(to_utf8(shortcut)+ "@" + filename.absFileName(), color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (token == "\\spellchecker_ignore") {
|
||||||
|
lex.eatLine();
|
||||||
|
docstring wl = lex.getDocString();
|
||||||
|
docstring langcode;
|
||||||
|
docstring word = split(wl, langcode, ' ');
|
||||||
|
Language const * lang = languages.getFromCode(to_ascii(langcode));
|
||||||
|
if (lang)
|
||||||
|
spellignore().push_back(WordLangTuple(word, lang));
|
||||||
} else if (token == "\\author") {
|
} else if (token == "\\author") {
|
||||||
lex.eatLine();
|
lex.eatLine();
|
||||||
istringstream ss(lex.getString());
|
istringstream ss(lex.getString());
|
||||||
@ -1408,6 +1432,12 @@ void BufferParams::writeFile(ostream & os, Buffer const * buf) const
|
|||||||
<< "\n";
|
<< "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (auto const & si : spellignore()) {
|
||||||
|
os << "\\spellchecker_ignore " << si.lang()->code()
|
||||||
|
<< " " << to_utf8(si.word())
|
||||||
|
<< "\n";
|
||||||
|
}
|
||||||
|
|
||||||
if (!paperwidth.empty())
|
if (!paperwidth.empty())
|
||||||
os << "\\paperwidth "
|
os << "\\paperwidth "
|
||||||
<< VSpace(paperwidth).asLyXCommand() << '\n';
|
<< VSpace(paperwidth).asLyXCommand() << '\n';
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#include "DocumentClassPtr.h"
|
#include "DocumentClassPtr.h"
|
||||||
#include "LayoutModuleList.h"
|
#include "LayoutModuleList.h"
|
||||||
#include "paper.h"
|
#include "paper.h"
|
||||||
|
#include "WordLangTuple.h"
|
||||||
|
|
||||||
#include "support/copied_ptr.h"
|
#include "support/copied_ptr.h"
|
||||||
#include "support/types.h"
|
#include "support/types.h"
|
||||||
@ -335,6 +336,11 @@ public:
|
|||||||
/// IndicesList:
|
/// IndicesList:
|
||||||
IndicesList & indiceslist();
|
IndicesList & indiceslist();
|
||||||
IndicesList const & indiceslist() const;
|
IndicesList const & indiceslist() const;
|
||||||
|
///
|
||||||
|
typedef std::vector<WordLangTuple> IgnoreList;
|
||||||
|
///
|
||||||
|
IgnoreList & spellignore();
|
||||||
|
IgnoreList const & spellignore() const;
|
||||||
/**
|
/**
|
||||||
* The LyX name of the input encoding for LaTeX. This can be one of
|
* The LyX name of the input encoding for LaTeX. This can be one of
|
||||||
* - \c auto: find out the input encoding from the used languages
|
* - \c auto: find out the input encoding from the used languages
|
||||||
|
@ -118,7 +118,8 @@ EnchantChecker::~EnchantChecker()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SpellChecker::Result EnchantChecker::check(WordLangTuple const & word)
|
SpellChecker::Result EnchantChecker::check(WordLangTuple const & word,
|
||||||
|
std::vector<WordLangTuple> docdict)
|
||||||
{
|
{
|
||||||
enchant::Dict * m = d->speller(word.lang()->code());
|
enchant::Dict * m = d->speller(word.lang()->code());
|
||||||
|
|
||||||
@ -133,6 +134,14 @@ SpellChecker::Result EnchantChecker::check(WordLangTuple const & word)
|
|||||||
if (m->check(utf8word))
|
if (m->check(utf8word))
|
||||||
return WORD_OK;
|
return WORD_OK;
|
||||||
|
|
||||||
|
vector<WordLangTuple>::const_iterator it = docdict.begin();
|
||||||
|
for (; it != docdict.end(); ++it) {
|
||||||
|
if (it->lang()->code() != word.lang()->code())
|
||||||
|
continue;
|
||||||
|
if (it->word() == word.word())
|
||||||
|
return LEARNED_WORD;
|
||||||
|
}
|
||||||
|
|
||||||
return UNKNOWN_WORD;
|
return UNKNOWN_WORD;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,8 +15,9 @@
|
|||||||
|
|
||||||
#include "SpellChecker.h"
|
#include "SpellChecker.h"
|
||||||
|
|
||||||
|
|
||||||
namespace enchant {
|
namespace enchant {
|
||||||
class Dict;
|
class Dict;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace lyx {
|
namespace lyx {
|
||||||
@ -31,7 +32,8 @@ public:
|
|||||||
|
|
||||||
/// SpellChecker inherited methods.
|
/// SpellChecker inherited methods.
|
||||||
///@{
|
///@{
|
||||||
enum Result check(WordLangTuple const &) override;
|
enum Result check(WordLangTuple const &,
|
||||||
|
std::vector<WordLangTuple> const &) override;
|
||||||
void suggest(WordLangTuple const &, docstring_list &) override;
|
void suggest(WordLangTuple const &, docstring_list &) override;
|
||||||
void stem(WordLangTuple const &, docstring_list &) override {}
|
void stem(WordLangTuple const &, docstring_list &) override {}
|
||||||
void insert(WordLangTuple const &) override;
|
void insert(WordLangTuple const &) override;
|
||||||
|
@ -497,6 +497,8 @@ enum FuncCode
|
|||||||
LFUN_LYXFILES_OPEN, // jspitzm 20210210
|
LFUN_LYXFILES_OPEN, // jspitzm 20210210
|
||||||
LFUN_SEARCH_STRING_SET, // stwitt/jspitzm 20210212
|
LFUN_SEARCH_STRING_SET, // stwitt/jspitzm 20210212
|
||||||
LFUN_FONT_NO_SPELLCHECK, // jspitzm 20210305
|
LFUN_FONT_NO_SPELLCHECK, // jspitzm 20210305
|
||||||
|
LFUN_SPELLING_ADD_LOCAL, // jspitzm 20210306
|
||||||
|
// 390
|
||||||
LFUN_LASTACTION // end of the table
|
LFUN_LASTACTION // end of the table
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -70,7 +70,8 @@ struct HunspellChecker::Private
|
|||||||
Hunspell * speller(Language const * lang);
|
Hunspell * speller(Language const * lang);
|
||||||
Hunspell * lookup(Language const * lang);
|
Hunspell * lookup(Language const * lang);
|
||||||
/// ignored words
|
/// ignored words
|
||||||
bool isIgnored(WordLangTuple const & wl) const;
|
bool isIgnored(WordLangTuple const & wl,
|
||||||
|
std::vector<WordLangTuple> const & docdict) const;
|
||||||
/// personal word list interface
|
/// personal word list interface
|
||||||
void remove(WordLangTuple const & wl);
|
void remove(WordLangTuple const & wl);
|
||||||
void insert(WordLangTuple const & wl);
|
void insert(WordLangTuple const & wl);
|
||||||
@ -281,7 +282,8 @@ int HunspellChecker::Private::numDictionaries() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool HunspellChecker::Private::isIgnored(WordLangTuple const & wl) const
|
bool HunspellChecker::Private::isIgnored(WordLangTuple const & wl,
|
||||||
|
vector<WordLangTuple> const & docdict) const
|
||||||
{
|
{
|
||||||
IgnoreList::const_iterator it = ignored_.begin();
|
IgnoreList::const_iterator it = ignored_.begin();
|
||||||
for (; it != ignored_.end(); ++it) {
|
for (; it != ignored_.end(); ++it) {
|
||||||
@ -290,6 +292,13 @@ bool HunspellChecker::Private::isIgnored(WordLangTuple const & wl) const
|
|||||||
if (it->word() == wl.word())
|
if (it->word() == wl.word())
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
it = docdict.begin();
|
||||||
|
for (; it != docdict.end(); ++it) {
|
||||||
|
if (it->lang()->code() != wl.lang()->code())
|
||||||
|
continue;
|
||||||
|
if (it->word() == wl.word())
|
||||||
|
return true;
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -344,9 +353,10 @@ HunspellChecker::~HunspellChecker()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SpellChecker::Result HunspellChecker::check(WordLangTuple const & wl)
|
SpellChecker::Result HunspellChecker::check(WordLangTuple const & wl,
|
||||||
|
vector<WordLangTuple> const & docdict)
|
||||||
{
|
{
|
||||||
if (d->isIgnored(wl))
|
if (d->isIgnored(wl, docdict))
|
||||||
return WORD_OK;
|
return WORD_OK;
|
||||||
|
|
||||||
Hunspell * h = d->speller(wl.lang());
|
Hunspell * h = d->speller(wl.lang());
|
||||||
|
@ -25,7 +25,8 @@ public:
|
|||||||
|
|
||||||
/// \name SpellChecker inherited methods.
|
/// \name SpellChecker inherited methods.
|
||||||
///@{
|
///@{
|
||||||
enum Result check(WordLangTuple const &) override;
|
enum Result check(WordLangTuple const &,
|
||||||
|
std::vector<WordLangTuple> const &) override;
|
||||||
void suggest(WordLangTuple const &, docstring_list &) override;
|
void suggest(WordLangTuple const &, docstring_list &) override;
|
||||||
void stem(WordLangTuple const &, docstring_list &) override;
|
void stem(WordLangTuple const &, docstring_list &) override;
|
||||||
void insert(WordLangTuple const &) override;
|
void insert(WordLangTuple const &) override;
|
||||||
|
@ -3793,6 +3793,19 @@ void LyXAction::init()
|
|||||||
*/
|
*/
|
||||||
{ LFUN_SPELLING_ADD, "spelling-add", ReadOnly, Edit },
|
{ LFUN_SPELLING_ADD, "spelling-add", ReadOnly, Edit },
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \var lyx::FuncCode lyx::LFUN_SPELLING_ADD_LOCAL
|
||||||
|
* \li Action: Add the word under the cursor to the document's local
|
||||||
|
* spell checker dictionary.
|
||||||
|
* The default for the language is retrieved from the cursor position.
|
||||||
|
* \li Syntax: spelling-add-local [<STRING>] [<LANG>]
|
||||||
|
* \li Params: <WORD>: word to add
|
||||||
|
<LANG>: language name (see file languages)
|
||||||
|
* \li Origin: spitz, 6 Mar 2021
|
||||||
|
* \endvar
|
||||||
|
*/
|
||||||
|
{ LFUN_SPELLING_ADD_LOCAL, "spelling-add-local", Noop, Edit },
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \var lyx::FuncCode lyx::LFUN_SPELLING_CONTINUOUSLY
|
* \var lyx::FuncCode lyx::LFUN_SPELLING_CONTINUOUSLY
|
||||||
* \li Action: Toggle continuous spell checking.
|
* \li Action: Toggle continuous spell checking.
|
||||||
|
@ -4860,7 +4860,9 @@ SpellChecker::Result Paragraph::spellCheck(pos_type & from, pos_type & to,
|
|||||||
docstring word = asString(from, to, AS_STR_INSETS | AS_STR_SKIPDELETE);
|
docstring word = asString(from, to, AS_STR_INSETS | AS_STR_SKIPDELETE);
|
||||||
Language * lang = d->getSpellLanguage(from);
|
Language * lang = d->getSpellLanguage(from);
|
||||||
|
|
||||||
if (getFontSettings(d->inset_owner_->buffer().params(), from).fontInfo().nospellcheck() == FONT_ON)
|
BufferParams const & bparams = d->inset_owner_->buffer().params();
|
||||||
|
|
||||||
|
if (getFontSettings(bparams, from).fontInfo().nospellcheck() == FONT_ON)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
wl = WordLangTuple(word, lang);
|
wl = WordLangTuple(word, lang);
|
||||||
@ -4872,10 +4874,10 @@ SpellChecker::Result Paragraph::spellCheck(pos_type & from, pos_type & to,
|
|||||||
pos_type end = to;
|
pos_type end = to;
|
||||||
if (!d->ignoreWord(word)) {
|
if (!d->ignoreWord(word)) {
|
||||||
bool const trailing_dot = to < size() && d->text_[to] == '.';
|
bool const trailing_dot = to < size() && d->text_[to] == '.';
|
||||||
result = speller->check(wl);
|
result = speller->check(wl, bparams.spellignore());
|
||||||
if (SpellChecker::misspelled(result) && trailing_dot) {
|
if (SpellChecker::misspelled(result) && trailing_dot) {
|
||||||
wl = WordLangTuple(word.append(from_ascii(".")), lang);
|
wl = WordLangTuple(word.append(from_ascii(".")), lang);
|
||||||
result = speller->check(wl);
|
result = speller->check(wl, bparams.spellignore());
|
||||||
if (!SpellChecker::misspelled(result)) {
|
if (!SpellChecker::misspelled(result)) {
|
||||||
LYXERR(Debug::GUI, "misspelled word is correct with dot: \"" <<
|
LYXERR(Debug::GUI, "misspelled word is correct with dot: \"" <<
|
||||||
word << "\" [" <<
|
word << "\" [" <<
|
||||||
@ -4987,8 +4989,9 @@ void Paragraph::spellCheck() const
|
|||||||
// start the spell checker on the unit of meaning
|
// start the spell checker on the unit of meaning
|
||||||
docstring word = asString(first, last, AS_STR_INSETS + AS_STR_SKIPDELETE);
|
docstring word = asString(first, last, AS_STR_INSETS + AS_STR_SKIPDELETE);
|
||||||
WordLangTuple wl = WordLangTuple(word, lang);
|
WordLangTuple wl = WordLangTuple(word, lang);
|
||||||
|
BufferParams const & bparams = d->inset_owner_->buffer().params();
|
||||||
SpellChecker::Result result = !word.empty() ?
|
SpellChecker::Result result = !word.empty() ?
|
||||||
speller->check(wl) : SpellChecker::WORD_OK;
|
speller->check(wl, bparams.spellignore()) : SpellChecker::WORD_OK;
|
||||||
d->markMisspelledWords(first, last, result, word, skips);
|
d->markMisspelledWords(first, last, result, word, skips);
|
||||||
first = ++last;
|
first = ++last;
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
#define SPELL_BASE_H
|
#define SPELL_BASE_H
|
||||||
|
|
||||||
#include "support/strfwd.h"
|
#include "support/strfwd.h"
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
|
||||||
namespace lyx {
|
namespace lyx {
|
||||||
@ -59,7 +60,8 @@ public:
|
|||||||
&& res != LEARNED_WORD; }
|
&& res != 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 &,
|
||||||
|
std::vector<WordLangTuple> const &) = 0;
|
||||||
|
|
||||||
/// Gives suggestions.
|
/// Gives suggestions.
|
||||||
virtual void suggest(WordLangTuple const &, docstring_list & suggestions) = 0;
|
virtual void suggest(WordLangTuple const &, docstring_list & suggestions) = 0;
|
||||||
|
@ -67,6 +67,7 @@
|
|||||||
|
|
||||||
#include "support/convert.h"
|
#include "support/convert.h"
|
||||||
#include "support/debug.h"
|
#include "support/debug.h"
|
||||||
|
#include "support/docstring_list.h"
|
||||||
#include "support/filetools.h"
|
#include "support/filetools.h"
|
||||||
#include "support/gettext.h"
|
#include "support/gettext.h"
|
||||||
#include "support/lassert.h"
|
#include "support/lassert.h"
|
||||||
@ -2730,6 +2731,47 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case LFUN_SPELLING_ADD_LOCAL: {
|
||||||
|
Language const * language = getLanguage(cur, cmd.getArg(1));
|
||||||
|
docstring word = from_utf8(cmd.getArg(0));
|
||||||
|
if (word.empty()) {
|
||||||
|
word = cur.selectionAsString(false);
|
||||||
|
if (word.size() > 100)
|
||||||
|
break;
|
||||||
|
if (word.empty()) {
|
||||||
|
// Get word or selection
|
||||||
|
selectWordWhenUnderCursor(cur, WHOLE_WORD);
|
||||||
|
word = cur.selectionAsString(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
WordLangTuple wl(word, language);
|
||||||
|
bool has_item = false;
|
||||||
|
vector<WordLangTuple> il = bv->buffer().params().spellignore();
|
||||||
|
vector<WordLangTuple>::const_iterator it = il.begin();
|
||||||
|
for (; it != il.end(); ++it) {
|
||||||
|
if (it->lang()->code() != wl.lang()->code())
|
||||||
|
continue;
|
||||||
|
if (it->word() == wl.word()) {
|
||||||
|
has_item = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!has_item) {
|
||||||
|
cur.recordUndoBufferParams();
|
||||||
|
bv->buffer().params().spellignore().push_back(wl);
|
||||||
|
cur.recordUndo();
|
||||||
|
// trigger re-check
|
||||||
|
WordLangTuple wl;
|
||||||
|
docstring_list suggestions;
|
||||||
|
Paragraph const & par = cur.paragraph();
|
||||||
|
pos_type from = cur.pos();
|
||||||
|
pos_type to = from;
|
||||||
|
par.spellCheck(from, to, wl, suggestions, true, true);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
case LFUN_SPELLING_IGNORE: {
|
case LFUN_SPELLING_IGNORE: {
|
||||||
Language const * language = getLanguage(cur, cmd.getArg(1));
|
Language const * language = getLanguage(cur, cmd.getArg(1));
|
||||||
docstring word = from_utf8(cmd.getArg(0));
|
docstring word = from_utf8(cmd.getArg(0));
|
||||||
@ -3459,6 +3501,7 @@ bool Text::getStatus(Cursor & cur, FuncRequest const & cmd,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case LFUN_SPELLING_ADD:
|
case LFUN_SPELLING_ADD:
|
||||||
|
case LFUN_SPELLING_ADD_LOCAL:
|
||||||
case LFUN_SPELLING_IGNORE:
|
case LFUN_SPELLING_IGNORE:
|
||||||
case LFUN_SPELLING_REMOVE:
|
case LFUN_SPELLING_REMOVE:
|
||||||
enable = theSpellChecker() != nullptr;
|
enable = theSpellChecker() != nullptr;
|
||||||
|
@ -428,7 +428,7 @@ bool SpellcheckerWidget::initialiseParams(std::string const &)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SpellcheckerWidget::on_ignoreAllPB_clicked()
|
void SpellcheckerWidget::on_skipAllPB_clicked()
|
||||||
{
|
{
|
||||||
/// ignore all occurrences of word
|
/// ignore all occurrences of word
|
||||||
if (d->disabled())
|
if (d->disabled())
|
||||||
@ -442,6 +442,21 @@ void SpellcheckerWidget::on_ignoreAllPB_clicked()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SpellcheckerWidget::on_ignoreAllPB_clicked()
|
||||||
|
{
|
||||||
|
/// ignore all occurrences of word
|
||||||
|
if (d->disabled())
|
||||||
|
return;
|
||||||
|
LYXERR(Debug::GUI, "Spellchecker: ignore all button");
|
||||||
|
if (d->word_.lang() && !d->word_.word().empty())
|
||||||
|
dispatch(FuncRequest(LFUN_SPELLING_ADD_LOCAL,
|
||||||
|
d->word_.word() + " " + from_ascii(d->word_.lang()->lang())));
|
||||||
|
d->forward();
|
||||||
|
d->check();
|
||||||
|
d->canCheck();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void SpellcheckerWidget::on_addPB_clicked()
|
void SpellcheckerWidget::on_addPB_clicked()
|
||||||
{
|
{
|
||||||
/// insert word in personal dictionary
|
/// insert word in personal dictionary
|
||||||
@ -455,12 +470,25 @@ void SpellcheckerWidget::on_addPB_clicked()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SpellcheckerWidget::on_skipPB_clicked()
|
||||||
|
{
|
||||||
|
/// ignore this occurrence of word
|
||||||
|
if (d->disabled())
|
||||||
|
return;
|
||||||
|
LYXERR(Debug::GUI, "Spellchecker: skip button");
|
||||||
|
d->forward();
|
||||||
|
d->check();
|
||||||
|
d->canCheck();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void SpellcheckerWidget::on_ignorePB_clicked()
|
void SpellcheckerWidget::on_ignorePB_clicked()
|
||||||
{
|
{
|
||||||
/// ignore this occurrence of word
|
/// ignore this occurrence of word
|
||||||
if (d->disabled())
|
if (d->disabled())
|
||||||
return;
|
return;
|
||||||
LYXERR(Debug::GUI, "Spellchecker: ignore button");
|
LYXERR(Debug::GUI, "Spellchecker: ignore button");
|
||||||
|
dispatch(FuncRequest(LFUN_FONT_NO_SPELLCHECK));
|
||||||
d->forward();
|
d->forward();
|
||||||
d->check();
|
d->check();
|
||||||
d->canCheck();
|
d->canCheck();
|
||||||
|
@ -42,7 +42,9 @@ private Q_SLOTS:
|
|||||||
void on_replaceCO_highlighted(const QString & str);
|
void on_replaceCO_highlighted(const QString & str);
|
||||||
void on_languageCO_activated(int index);
|
void on_languageCO_activated(int index);
|
||||||
void on_ignoreAllPB_clicked();
|
void on_ignoreAllPB_clicked();
|
||||||
|
void on_skipAllPB_clicked();
|
||||||
void on_addPB_clicked();
|
void on_addPB_clicked();
|
||||||
|
void on_skipPB_clicked();
|
||||||
void on_ignorePB_clicked();
|
void on_ignorePB_clicked();
|
||||||
void on_replacePB_clicked();
|
void on_replacePB_clicked();
|
||||||
|
|
||||||
|
@ -862,10 +862,12 @@ void MenuDefinition::expandSpellingSuggestions(BufferView const * bv)
|
|||||||
docstring const arg = wl.word() + " " + from_ascii(wl.lang()->lang());
|
docstring const arg = wl.word() + " " + from_ascii(wl.lang()->lang());
|
||||||
add(MenuItem(MenuItem::Command, qt_("Add to personal dictionary|n"),
|
add(MenuItem(MenuItem::Command, qt_("Add to personal dictionary|n"),
|
||||||
FuncRequest(LFUN_SPELLING_ADD, arg)));
|
FuncRequest(LFUN_SPELLING_ADD, arg)));
|
||||||
add(MenuItem(MenuItem::Command, qt_("Ignore|g"),
|
add(MenuItem(MenuItem::Command, qt_("Ignore this occurrence|g"),
|
||||||
FuncRequest(LFUN_FONT_NO_SPELLCHECK, arg)));
|
FuncRequest(LFUN_FONT_NO_SPELLCHECK, arg)));
|
||||||
add(MenuItem(MenuItem::Command, qt_("Ignore all|I"),
|
add(MenuItem(MenuItem::Command, qt_("Ignore all for this session|I"),
|
||||||
FuncRequest(LFUN_SPELLING_IGNORE, arg)));
|
FuncRequest(LFUN_SPELLING_IGNORE, arg)));
|
||||||
|
add(MenuItem(MenuItem::Command, qt_("Ignore all in this document|d"),
|
||||||
|
FuncRequest(LFUN_SPELLING_ADD_LOCAL, arg)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -6,8 +6,8 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>300</width>
|
<width>477</width>
|
||||||
<height>380</height>
|
<height>488</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="minimumSize">
|
<property name="minimumSize">
|
||||||
@ -19,7 +19,78 @@
|
|||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
<string>Spell Checker</string>
|
<string>Spell Checker</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="gridLayout" columnstretch="1,0">
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
|
<item row="0" column="0">
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="languageLA">
|
||||||
|
<property name="text">
|
||||||
|
<string>&Language:</string>
|
||||||
|
</property>
|
||||||
|
<property name="buddy">
|
||||||
|
<cstring>languageCO</cstring>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QComboBox" name="languageCO">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Minimum">
|
||||||
|
<horstretch>100</horstretch>
|
||||||
|
<verstretch>32</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>The checked language. Switching this alters the language of the checked word.</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0" colspan="2">
|
||||||
|
<widget class="Line" name="line">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QLabel" name="TextLabel3">
|
||||||
|
<property name="text">
|
||||||
|
<string>Unknown &word:</string>
|
||||||
|
</property>
|
||||||
|
<property name="buddy">
|
||||||
|
<cstring>wordED</cstring>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="0">
|
||||||
|
<widget class="QLineEdit" name="wordED">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Current word</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="1">
|
||||||
|
<widget class="QPushButton" name="skipPB">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Skip this match and go to next misspelling</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>S&kip</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="0">
|
||||||
|
<widget class="QLabel" name="TextLabel1">
|
||||||
|
<property name="text">
|
||||||
|
<string>Repla&cement:</string>
|
||||||
|
</property>
|
||||||
|
<property name="buddy">
|
||||||
|
<cstring>replaceCO</cstring>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item row="5" column="0">
|
<item row="5" column="0">
|
||||||
<widget class="QComboBox" name="replaceCO">
|
<widget class="QComboBox" name="replaceCO">
|
||||||
<property name="focusPolicy">
|
<property name="focusPolicy">
|
||||||
@ -49,60 +120,6 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="0" column="0" colspan="2">
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="languageLA">
|
|
||||||
<property name="text">
|
|
||||||
<string>&Language:</string>
|
|
||||||
</property>
|
|
||||||
<property name="buddy">
|
|
||||||
<cstring>languageCO</cstring>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QComboBox" name="languageCO">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Minimum">
|
|
||||||
<horstretch>100</horstretch>
|
|
||||||
<verstretch>32</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>The checked language. Switching this alters the language of the checked word.</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="0">
|
|
||||||
<widget class="QLabel" name="TextLabel3">
|
|
||||||
<property name="text">
|
|
||||||
<string>Unknown &word:</string>
|
|
||||||
</property>
|
|
||||||
<property name="buddy">
|
|
||||||
<cstring>wordED</cstring>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="3" column="0">
|
|
||||||
<widget class="QLineEdit" name="wordED">
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>Current word</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="4" column="0">
|
|
||||||
<widget class="QLabel" name="TextLabel1">
|
|
||||||
<property name="text">
|
|
||||||
<string>Repla&cement:</string>
|
|
||||||
</property>
|
|
||||||
<property name="buddy">
|
|
||||||
<cstring>replaceCO</cstring>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="6" column="0">
|
<item row="6" column="0">
|
||||||
<widget class="QLabel" name="TextLabel2">
|
<widget class="QLabel" name="TextLabel2">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
@ -122,24 +139,37 @@
|
|||||||
<item row="6" column="1">
|
<item row="6" column="1">
|
||||||
<widget class="QPushButton" name="replaceAllPB">
|
<widget class="QPushButton" name="replaceAllPB">
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string/>
|
<string>Replace all occurrences of the word in the document with current choice</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Re&place All</string>
|
<string>Re&place All</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="0" colspan="2">
|
<item row="7" column="0" rowspan="5">
|
||||||
<widget class="Line" name="line">
|
<widget class="QListWidget" name="suggestionsLW"/>
|
||||||
<property name="orientation">
|
</item>
|
||||||
<enum>Qt::Horizontal</enum>
|
<item row="7" column="1">
|
||||||
|
<widget class="QPushButton" name="ignorePB">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Ignore this occurrence of the word permanently</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Ign&ore</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="7" column="0" rowspan="4">
|
|
||||||
<widget class="QListWidget" name="suggestionsLW"/>
|
|
||||||
</item>
|
|
||||||
<item row="9" column="1">
|
<item row="9" column="1">
|
||||||
|
<widget class="QPushButton" name="ignoreAllPB">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Ignore all occurrences of this word within this document. This is perdurant beyond the current session.</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>I&gnore All</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="10" column="1">
|
||||||
<widget class="QPushButton" name="addPB">
|
<widget class="QPushButton" name="addPB">
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>Add the word to your personal dictionary</string>
|
<string>Add the word to your personal dictionary</string>
|
||||||
@ -149,7 +179,7 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="10" column="1">
|
<item row="11" column="1">
|
||||||
<spacer>
|
<spacer>
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
<enum>Qt::Vertical</enum>
|
<enum>Qt::Vertical</enum>
|
||||||
@ -165,23 +195,13 @@
|
|||||||
</property>
|
</property>
|
||||||
</spacer>
|
</spacer>
|
||||||
</item>
|
</item>
|
||||||
<item row="3" column="1">
|
|
||||||
<widget class="QPushButton" name="ignorePB">
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>Ignore this word</string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Ign&ore</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="4" column="1">
|
<item row="4" column="1">
|
||||||
<widget class="QPushButton" name="ignoreAllPB">
|
<widget class="QPushButton" name="skipAllPB">
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>Ignore this word throughout this session</string>
|
<string>Skips all occurrences of this word within the current session.</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>I&gnore All</string>
|
<string>Skip A&ll</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
@ -32,8 +32,8 @@ extern char const * const lyx_version_info;
|
|||||||
|
|
||||||
// Do not remove the comment below, so we get merge conflict in
|
// Do not remove the comment below, so we get merge conflict in
|
||||||
// independent branches. Instead add your own.
|
// independent branches. Instead add your own.
|
||||||
#define LYX_FORMAT_LYX 606 // spitz: frontispiece KOMA layout
|
#define LYX_FORMAT_LYX 607 // spitz: \\spellchecker_ignore buffer param
|
||||||
#define LYX_FORMAT_TEX2LYX 606
|
#define LYX_FORMAT_TEX2LYX 607
|
||||||
|
|
||||||
#if LYX_FORMAT_TEX2LYX != LYX_FORMAT_LYX
|
#if LYX_FORMAT_TEX2LYX != LYX_FORMAT_LYX
|
||||||
#ifndef _MSC_VER
|
#ifndef _MSC_VER
|
||||||
|
Loading…
Reference in New Issue
Block a user