#include "commandtags.h"
#include "insets/inset.h"
+#include "WordLangTuple.h"
#include <boost/utility.hpp>
void endOfSpellCheck();
///
void selectLastWord();
- ///
- string const nextWord(float & value);
+ /// return the next word
+ WordLangTuple const nextWord(float & value);
///
bool gotoLabel(string const & label);
///
/* these functions are for the spellchecker */
-string const BufferView::nextWord(float & value)
+WordLangTuple const BufferView::nextWord(float & value)
{
if (!available()) {
value = 1;
- return string();
+ return WordLangTuple();
}
return text->selectNextWordToSpellcheck(this, value);
+2002-08-06 John Levon <levon@movementarian.org>
+
+ * WordLangTuple.h: new file for word + language code tuple
+
+ * SpellBase.h:
+ * pspell.h:
+ * pspell.C:
+ * ispell.h:
+ * ispell.C:
+ * lyxtext.h:
+ * text.C:
+ * text2.C:
+ * BufferView.h:
+ * BufferView2.C: use WordLangTuple
+
+ * layout.h:
+ * buffer.C: remove very dead LYX_LAYOUT_DEFAULT
+
2002-08-06 John Levon <levon@movementarian.org>
* lyx_main.C: fix cmdline batch handling
#include "LString.h" // can't forward declare...
+#include "WordLangTuple.h"
+
class BufferParams;
/**
/// clean up on messy exit
virtual void cleanUp() = 0;
- /// check the given word and return the result
- virtual enum Result check(string const &) = 0;
+ /// check the given word of the given lang code and return the result
+ virtual enum Result check(WordLangTuple const &) = 0;
/// finish this spellchecker instance
virtual void close() = 0;
/// insert the given word into the personal dictionary
- virtual void insert(string const &) = 0;
+ virtual void insert(WordLangTuple const &) = 0;
/// accept the given word temporarily
- virtual void accept(string const &) = 0;
+ virtual void accept(WordLangTuple const &) = 0;
/// return the next near miss after a MISSED result
virtual string const nextMiss() = 0;
--- /dev/null
+/**
+ * \file WordLangTuple.h
+ * Copyright 2002 the LyX Team
+ * Read the file COPYING
+ *
+ * \author John Levon <levon@movementarian.org>
+ */
+
+#ifndef WORD_LANG_TUPLE_H
+#define WORD_LANG_TUPLE_H
+
+#include <config.h>
+#include "LString.h"
+
+/**
+ * A word and its given language code ("en_US").
+ * This is used for spellchecking.
+ */
+class WordLangTuple {
+public:
+ WordLangTuple() {};
+
+ WordLangTuple(string const & w, string const & c)
+ : word_(w), code_(c) {}
+
+ /// return the word
+ string const word() const {
+ return word_;
+ }
+
+ /// return its language code
+ string const lang_code() const {
+ return code_;
+ }
+
+private:
+ /// the word
+ string word_;
+ /// language code of word
+ string code_;
+};
+
+#endif // WORD_LANG_TUPLE_H
int tmpret = lex.findToken(string_paragraph_separation);
if (tmpret == -1)
++tmpret;
- if (tmpret != LYX_LAYOUT_DEFAULT)
- params.paragraph_separation =
- static_cast<BufferParams::PARSEP>(tmpret);
+ params.paragraph_separation =
+ static_cast<BufferParams::PARSEP>(tmpret);
} else if (token == "\\defskip") {
lex.nextToken();
params.defskip = VSpace(lex.getString());
int tmpret = lex.findToken(string_quotes_language);
if (tmpret == -1)
++tmpret;
- if (tmpret != LYX_LAYOUT_DEFAULT) {
- InsetQuotes::quote_language tmpl =
- InsetQuotes::EnglishQ;
- switch (tmpret) {
- case 0:
- tmpl = InsetQuotes::EnglishQ;
- break;
- case 1:
- tmpl = InsetQuotes::SwedishQ;
- break;
- case 2:
- tmpl = InsetQuotes::GermanQ;
- break;
- case 3:
- tmpl = InsetQuotes::PolishQ;
- break;
- case 4:
- tmpl = InsetQuotes::FrenchQ;
- break;
- case 5:
- tmpl = InsetQuotes::DanishQ;
- break;
- }
- params.quotes_language = tmpl;
+ InsetQuotes::quote_language tmpl =
+ InsetQuotes::EnglishQ;
+ switch (tmpret) {
+ case 0:
+ tmpl = InsetQuotes::EnglishQ;
+ break;
+ case 1:
+ tmpl = InsetQuotes::SwedishQ;
+ break;
+ case 2:
+ tmpl = InsetQuotes::GermanQ;
+ break;
+ case 3:
+ tmpl = InsetQuotes::PolishQ;
+ break;
+ case 4:
+ tmpl = InsetQuotes::FrenchQ;
+ break;
+ case 5:
+ tmpl = InsetQuotes::DanishQ;
+ break;
}
+ params.quotes_language = tmpl;
} else if (token == "\\quotes_times") {
lex.nextToken();
switch (lex.getInteger()) {
int tmpret = lex.findToken(string_orientation);
if (tmpret == -1)
++tmpret;
- if (tmpret != LYX_LAYOUT_DEFAULT)
- params.orientation = static_cast<BufferParams::PAPER_ORIENTATION>(tmpret);
+ params.orientation =
+ static_cast<BufferParams::PAPER_ORIENTATION>(tmpret);
} else if (token == "\\paperwidth") {
lex.next();
params.paperwidth = lex.getString();
} else if (token == "\\align") {
int tmpret = lex.findToken(string_align);
if (tmpret == -1) ++tmpret;
- if (tmpret != LYX_LAYOUT_DEFAULT) { // tmpret != 99 ???
- int const tmpret2 = int(pow(2.0, tmpret));
- //lyxerr << "Tmpret2 = " << tmpret2 << endl;
- par->params().align(LyXAlignment(tmpret2));
- }
+ int const tmpret2 = int(pow(2.0, tmpret));
+ par->params().align(LyXAlignment(tmpret2));
} else if (token == "\\added_space_top") {
lex.nextToken();
VSpace value = VSpace(lex.getString());
+2002-08-06 John Levon <levon@movementarian.org>
+
+ * ControlSpellchecker.C:
+ * ControlSpellchecker.h: use WordLangTuple
+
2002-08-06 John Levon <levon@movementarian.org>
* ControlSpellchecker.C: show an alert with the
while ((res == SpellBase::OK || res == SpellBase::IGNORE) && !stop_) {
word_ = lv_.view()->nextWord(newval_);
- if (word_.empty()) {
+ if (word_.word().empty()) {
clearParams();
break;
}
++count_;
// Update slider if and only if value has changed
- newvalue_ = int(100.0*newval_);
+ newvalue_ = int(100.0 * newval_);
if (newvalue_!= oldval_) {
oldval_ = newvalue_;
// set progress bar
view().partialUpdate(0);
}
- if (!speller_->alive()) clearParams();
+ if (!speller_->alive()) {
+ clearParams();
+ stop();
+ return;
+ }
res = speller_->check(word_);
}
- if (!stop_ && !word_.empty())
+ if (!stop_ && !word_.word().empty())
lv_.view()->selectLastWord();
// set suggestions
void ControlSpellchecker::replace(string const & replacement)
{
lv_.view()->replaceWord(replacement);
+ // fix up the count
+ --count_;
check();
}
string ControlSpellchecker::getWord()
{
- string tmp = word_;
+ string tmp = word_.word();
if (rtl_)
std::reverse(tmp.begin(), tmp.end());
return tmp;
// reset values to initial
rtl_ = false;
- word_.erase();
newval_ = 0.0;
oldval_ = 0;
newvalue_ = 0;
#include "ControlDialog_impl.h"
#include "LString.h"
+#include "WordLangTuple.h"
class SpellBase;
/// right to left
bool rtl_;
- /// current word being checked
- string word_;
+ /// current word being checked and lang code
+ WordLangTuple word_;
/// values for progress
float newval_;
+2002-08-06 John Levon <levon@movementarian.org>
+
+ * inset.h:
+ * inset.C:
+ * insetcollapsable.h:
+ * insetcollapsable.C:
+ * insetert.h:
+ * insetert.C:
+ * insettabular.h:
+ * insettabular.C:
+ * insettext.h:
+ * insettext.C: use WordLangTuple for spellcheck
+
2002-08-06 Angus Leeming <leeming@lyx.org>
* insetinclude.C: add a monitor to the previewed image, so that the
}
-string const UpdatableInset::selectNextWordToSpellcheck(BufferView *bv,
+WordLangTuple UpdatableInset::selectNextWordToSpellcheck(BufferView *bv,
float & value) const
{
// we have to unlock ourself in this function by default!
bv->unlockInset(const_cast<UpdatableInset *>(this));
value = 0;
- return string();
+ return WordLangTuple();
}
#include "LString.h"
#include "commandtags.h"
#include "frontends/mouse_state.h"
+#include "WordLangTuple.h"
#include "LColor.h"
class LyXFont;
///
virtual bool allowSpellcheck() { return false; }
///
- virtual string const selectNextWordToSpellcheck(BufferView *, float & value) const;
+ virtual WordLangTuple selectNextWordToSpellcheck(BufferView *, float & value) const;
///
virtual void selectSelectedWord(BufferView *) { return; }
///
}
-string const InsetCollapsable::selectNextWordToSpellcheck(BufferView * bv,
+WordLangTuple InsetCollapsable::selectNextWordToSpellcheck(BufferView * bv,
float & value) const
{
- string const str = inset.selectNextWordToSpellcheck(bv, value);
- if (first_after_edit && str.empty())
+ WordLangTuple word = inset.selectNextWordToSpellcheck(bv, value);
+ if (first_after_edit && word.word().empty())
close(bv);
first_after_edit = false;
- return str;
+ return word;
}
void close(BufferView *) const;
///
bool allowSpellcheck() { return inset.allowSpellcheck(); }
- string const selectNextWordToSpellcheck(BufferView *, float &) const;
+
+ WordLangTuple selectNextWordToSpellcheck(BufferView *, float &) const;
void selectSelectedWord(BufferView * bv) {
inset.selectSelectedWord(bv);
}
-string const InsetERT::selectNextWordToSpellcheck(BufferView * bv,
+WordLangTuple InsetERT::selectNextWordToSpellcheck(BufferView * bv,
float &) const
{
bv->unlockInset(const_cast<InsetERT *>(this));
- return string();
+ return WordLangTuple();
}
void close(BufferView *) const;
///
bool allowSpellcheck() { return false; }
- string const selectNextWordToSpellcheck(BufferView *, float &) const;
+
+ WordLangTuple selectNextWordToSpellcheck(BufferView *, float &) const;
///
int ascent(BufferView *, LyXFont const &) const;
///
}
-string const
+WordLangTuple
InsetTabular::selectNextWordToSpellcheck(BufferView * bv, float & value) const
{
nodraw(true);
if (the_locking_inset) {
- string const str(the_locking_inset->selectNextWordToSpellcheck(bv, value));
- if (!str.empty()) {
+ WordLangTuple word(the_locking_inset->selectNextWordToSpellcheck(bv, value));
+ if (!word.word().empty()) {
nodraw(false);
- return str;
+ return word;
}
if (tabular->IsLastCell(actcell)) {
bv->unlockInset(const_cast<InsetTabular *>(this));
nodraw(false);
- return string();
+ return WordLangTuple();
}
++actcell;
}
UpdatableInset * inset =
static_cast<UpdatableInset*>(tabular->GetCellInset(actcell));
inset->edit(bv, 0, 0, mouse_button::none);
- string const str(selectNextWordInt(bv, value));
+ WordLangTuple word(selectNextWordInt(bv, value));
nodraw(false);
- if (!str.empty())
+ if (!word.word().empty())
resetPos(bv);
- return str;
+ return word;
}
-string InsetTabular::selectNextWordInt(BufferView * bv, float & value) const
+WordLangTuple InsetTabular::selectNextWordInt(BufferView * bv, float & value) const
{
// when entering this function the inset should be ALWAYS locked!
lyx::Assert(the_locking_inset);
- string const str(the_locking_inset->selectNextWordToSpellcheck(bv, value));
- if (!str.empty())
- return str;
+ WordLangTuple word(the_locking_inset->selectNextWordToSpellcheck(bv, value));
+ if (!word.word().empty())
+ return word;
if (tabular->IsLastCell(actcell)) {
bv->unlockInset(const_cast<InsetTabular *>(this));
- return string();
+ return WordLangTuple();
}
// otherwise we have to lock the next inset and ask for it's selecttion
LyXCursor const & cursor(BufferView *) const;
///
bool allowSpellcheck() { return true; }
- string const selectNextWordToSpellcheck(BufferView *, float & value) const;
+ WordLangTuple selectNextWordToSpellcheck(BufferView *, float & value) const;
void selectSelectedWord(BufferView *);
void toggleSelection(BufferView *, bool kill_selection);
///
void getSelection(int & scol, int & ecol,
int & srow, int & erow) const;
///
- string selectNextWordInt(BufferView *, float & value) const;
+ WordLangTuple selectNextWordInt(BufferView *, float & value) const;
///
bool insertAsciiString(BufferView *, string const & buf, bool usePaste);
}
-string const InsetText::selectNextWordToSpellcheck(BufferView * bv, float & value) const
+WordLangTuple InsetText::selectNextWordToSpellcheck(BufferView * bv, float & value) const
{
bool clear = false;
- string str;
+ WordLangTuple word;
if (!lt) {
lt = getLyXText(bv);
clear = true;
}
if (the_locking_inset) {
- str = the_locking_inset->selectNextWordToSpellcheck(bv, value);
- if (!str.empty()) {
+ word = the_locking_inset->selectNextWordToSpellcheck(bv, value);
+ if (!word.word().empty()) {
value += cy(bv);
if (clear)
lt = 0;
- return str;
+ return word;
}
- // we have to go on checking so move cusor to the next char
+ // we have to go on checking so move cursor to the next char
lt->cursor.pos(lt->cursor.pos() + 1);
}
- str = lt->selectNextWordToSpellcheck(bv, value);
- if (str.empty())
+ word = lt->selectNextWordToSpellcheck(bv, value);
+ if (word.word().empty())
bv->unlockInset(const_cast<InsetText *>(this));
else
value = cy(bv);
if (clear)
lt = 0;
- return str;
+ return word;
}
///
bool allowSpellcheck() { return true; }
///
- string const selectNextWordToSpellcheck(BufferView *,
+ WordLangTuple selectNextWordToSpellcheck(BufferView *,
float & value) const;
void selectSelectedWord(BufferView *);
///
}
-enum ISpell::Result ISpell::check(string const & word)
+enum ISpell::Result ISpell::check(WordLangTuple const & word)
{
// FIXME Please rewrite to use string.
Result res;
- ::fputs(word.c_str(), out);
+ ::fputs(word.word().c_str(), out);
::fputc('\n', out);
char buf[1024];
}
-void ISpell::insert(string const & word)
+void ISpell::insert(WordLangTuple const & word)
{
::fputc('*', out); // Insert word in personal dictionary
- ::fputs(word.c_str(), out);
+ ::fputs(word.word().c_str(), out);
::fputc('\n', out);
}
-void ISpell::accept(string const & word)
+void ISpell::accept(WordLangTuple const & word)
{
::fputc('@', out); // Accept in this session
- ::fputs(word.c_str(), out);
+ ::fputs(word.word().c_str(), out);
::fputc('\n', out);
}
virtual void cleanUp();
/// check the given word and return the result
- virtual enum Result check(string const & word);
+ virtual enum Result check(WordLangTuple const & word);
/// finish this spellchecker instance
virtual void close();
/// insert the given word into the personal dictionary
- virtual void insert(string const & word);
+ virtual void insert(WordLangTuple const & word);
/// accept the given word temporarily
- virtual void accept(string const & word);
+ virtual void accept(WordLangTuple const & word);
/// return the next near miss after a MISSED result
virtual string const nextMiss();
#ifndef LAYOUT_H
#define LAYOUT_H
-enum layout_default {
- ///
- LYX_LAYOUT_DEFAULT = 99
-};
-
-
/// The different output types
enum OutputType {
///
#include "layout.h"
#include "LColor.h"
#include "insets/inset.h"
+#include "WordLangTuple.h"
class Buffer;
class BufferParams;
to the beginning of this word.
With SelectSelectedWord can this be highlighted really
*/
- string const selectNextWordToSpellcheck(BufferView *, float & value) const;
+ WordLangTuple selectNextWordToSpellcheck(BufferView *, float & value) const;
///
void selectSelectedWord(BufferView *);
/// returns true if par was empty and was removed
using std::endl;
PSpell::PSpell(BufferParams const &, string const & lang)
- : sc(0), els(0), spell_error_object(0), alive_(false)
+ : els(0), spell_error_object(0)
{
- PspellConfig * config = new_pspell_config();
- pspell_config_replace(config, "language-tag", lang.c_str());
- spell_error_object = new_pspell_manager(config);
- if (pspell_error_number(spell_error_object) == 0) {
- sc = to_pspell_manager(spell_error_object);
- spell_error_object = 0;
- alive_ = true;
- }
+ addManager(lang);
}
close();
if (els)
delete_pspell_string_emulation(els);
+ Managers::iterator it = managers_.begin();
+ Managers::iterator end = managers_.end();
+
+ for (; it != end; ++it) {
+ delete_pspell_manager(it->second.manager);
+ delete_pspell_config(it->second.config);
+ }
}
}
-enum PSpell::Result PSpell::check(string const & word)
+void PSpell::addManager(string const & lang)
+{
+ PspellConfig * config = new_pspell_config();
+ pspell_config_replace(config, "language-tag", lang.c_str());
+ PspellCanHaveError * err = new_pspell_manager(config);
+ if (spell_error_object)
+ delete_pspell_can_have_error(spell_error_object);
+ spell_error_object = 0;
+
+ if (pspell_error_number(err) == 0) {
+ Manager m;
+ m.manager = to_pspell_manager(err);
+ m.config = config;
+ managers_[lang] = m;
+ } else {
+ spell_error_object = err;
+ }
+}
+
+
+enum PSpell::Result PSpell::check(WordLangTuple const & word)
{
Result res = UNKNOWN;
- if (!sc)
- return res;
+ Managers::iterator it = managers_.find(word.lang_code());
+ if (it == managers_.end()) {
+ addManager(word.lang_code());
+ it = managers_.find(word.lang_code());
+ // FIXME
+ if (it == managers_.end())
+ return res;
+ }
- int word_ok = pspell_manager_check(sc, word.c_str());
+ PspellManager * m = it->second.manager;
+
+ int word_ok = pspell_manager_check(m, word.word().c_str());
lyx::Assert(word_ok != -1);
if (word_ok) {
res = OK;
} else {
PspellWordList const * sugs =
- pspell_manager_suggest(sc, word.c_str());
+ pspell_manager_suggest(m, word.word().c_str());
lyx::Assert(sugs != 0);
els = pspell_word_list_elements(sugs);
if (pspell_word_list_empty(sugs))
void PSpell::close()
{
- if (sc)
- pspell_manager_save_all_word_lists(sc);
+ Managers::iterator it = managers_.begin();
+ Managers::iterator end = managers_.end();
+
+ for (; it != end; ++it) {
+ pspell_manager_save_all_word_lists(it->second.manager);
+ }
}
-void PSpell::insert(string const & word)
+void PSpell::insert(WordLangTuple const & word)
{
- if (sc)
- pspell_manager_add_to_personal(sc, word.c_str());
+ Managers::iterator it = managers_.find(word.lang_code());
+ if (it != managers_.end())
+ pspell_manager_add_to_personal(it->second.manager, word.word().c_str());
}
-void PSpell::accept(string const & word)
+void PSpell::accept(WordLangTuple const & word)
{
- if (sc)
- pspell_manager_add_to_session(sc, word.c_str());
+ Managers::iterator it = managers_.find(word.lang_code());
+ if (it != managers_.end())
+ pspell_manager_add_to_session(it->second.manager, word.word().c_str());
}
#ifndef LYX_PSPELL_H
#define LYX_PSPELL_H
+#include <map>
+
#include "SpellBase.h"
class PspellManager;
class PspellStringEmulation;
class PspellCanHaveError;
+class PspellConfig;
class BufferParams;
virtual ~PSpell();
- /// return true if the spellchecker instance still exists
- virtual bool alive() { return alive_; }
+ /**
+ * return true if the spellchecker instance still exists
+ * Always true for pspell, since there is no separate process
+ */
+ virtual bool alive() { return true; }
/// clean up on messy exit
virtual void cleanUp();
/// check the given word and return the result
- virtual enum Result check(string const & word);
+ virtual enum Result check(WordLangTuple const &);
/// finish this spellchecker instance
virtual void close();
/// insert the given word into the personal dictionary
- virtual void insert(string const & word);
+ virtual void insert(WordLangTuple const &);
/// accept the given word temporarily
- virtual void accept(string const & word);
+ virtual void accept(WordLangTuple const &);
/// return the next near miss after a MISSED result
virtual string const nextMiss();
virtual string const error();
private:
- /// main manager
- PspellManager * sc;
+ /// add a manager of the given language
+ void addManager(string const & lang);
+
+ struct Manager {
+ PspellManager * manager;
+ PspellConfig * config;
+ };
+
+ typedef std::map<string, struct Manager> Managers;
+
+ /// the managers
+ Managers managers_;
+
/// FIXME
PspellStringEmulation * els;
/// FIXME
PspellCanHaveError * spell_error_object;
- /// initialised properly ?
- bool alive_;
};
#endif // PSPELL_H
// This function is only used by the spellchecker for NextWord().
// It doesn't handle LYX_ACCENTs and probably never will.
-string const LyXText::selectNextWordToSpellcheck(BufferView * bview,
+WordLangTuple LyXText::selectNextWordToSpellcheck(BufferView * bview,
float & value) const
{
if (the_locking_inset) {
- string str = the_locking_inset->selectNextWordToSpellcheck(bview, value);
- if (!str.empty()) {
+ WordLangTuple word = the_locking_inset->selectNextWordToSpellcheck(bview, value);
+ if (!word.word().empty()) {
value += float(cursor.y())/float(height);
- return str;
+ return word;
}
- // we have to go on checking so move cusor to the next char
+ // we have to go on checking so move cursor to the next char
if (cursor.pos() == cursor.par()->size()) {
if (!cursor.par()->next())
- return str;
+ return word;
cursor.par(cursor.par()->next());
cursor.pos(0);
} else
// Start the selection from here
selection.cursor = cursor;
+ string lang_code(
+ getFont(bview->buffer(), cursor.par(), cursor.pos())
+ .language()->code());
// and find the end of the word (insets like optional hyphens
// and ligature break are part of a word)
while (cursor.pos() < cursor.par()->size()
str += cursor.par()->getChar(i);
}
}
- return str;
+ return WordLangTuple(str, lang_code);
}
// Try implicit word selection
// If there is a change in the language the implicit word selection
// is disabled.
- LyXCursor resetCursor = cursor;
- bool implicitSelection = selectWordWhenUnderCursor(bview, PREVIOUS_WORD);
+ LyXCursor const reset_cursor = cursor;
+ bool const implicitSelection = selectWordWhenUnderCursor(bview, PREVIOUS_WORD);
if (!selection.set()) {
bview->owner()->message(_("Nothing to index!"));
//and cursor is set to the original position.
if (implicitSelection) {
clearSelection();
- cursor = resetCursor;
+ cursor = reset_cursor;
setCursor(bview, cursor.par(), cursor.pos());
selection.cursor = cursor;
}