mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-11-10 20:04:46 +00:00
next one
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@20797 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
parent
86af8a2811
commit
e093f9212b
@ -194,7 +194,7 @@ void Dialogs::checkStatus()
|
|||||||
|
|
||||||
for(; it != end; ++it) {
|
for(; it != end; ++it) {
|
||||||
Dialog * const dialog = it->second.get();
|
Dialog * const dialog = it->second.get();
|
||||||
if (dialog->isVisibleView())
|
if (dialog && dialog->isVisibleView())
|
||||||
dialog->checkStatus();
|
dialog->checkStatus();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,348 +0,0 @@
|
|||||||
/**
|
|
||||||
* \file ControlSpellchecker.cpp
|
|
||||||
* This file is part of LyX, the document processor.
|
|
||||||
* Licence details can be found in the file COPYING.
|
|
||||||
*
|
|
||||||
* \author Edwin Leuven
|
|
||||||
*
|
|
||||||
* Full author contact details are available in file CREDITS.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <config.h>
|
|
||||||
|
|
||||||
#include "ControlSpellchecker.h"
|
|
||||||
|
|
||||||
#include "Buffer.h"
|
|
||||||
#include "BufferParams.h"
|
|
||||||
#include "BufferView.h"
|
|
||||||
#include "Cursor.h"
|
|
||||||
#include "CutAndPaste.h"
|
|
||||||
#include "debug.h"
|
|
||||||
#include "gettext.h"
|
|
||||||
#include "Language.h"
|
|
||||||
#include "LyXRC.h"
|
|
||||||
#include "Paragraph.h"
|
|
||||||
|
|
||||||
#if defined(USE_ASPELL)
|
|
||||||
# include "ASpell_local.h"
|
|
||||||
#elif defined(USE_PSPELL)
|
|
||||||
# include "PSpell.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(USE_ISPELL)
|
|
||||||
# include "ISpell.h"
|
|
||||||
#else
|
|
||||||
# include "SpellBase.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "support/textutils.h"
|
|
||||||
#include "support/convert.h"
|
|
||||||
#include "support/docstring.h"
|
|
||||||
|
|
||||||
#include "frontends/alert.h"
|
|
||||||
// FIXME: those two headers are needed because of the
|
|
||||||
// WorkArea::redraw() call below.
|
|
||||||
#include "frontends/LyXView.h"
|
|
||||||
#include "frontends/WorkArea.h"
|
|
||||||
|
|
||||||
using std::advance;
|
|
||||||
using std::distance;
|
|
||||||
using std::endl;
|
|
||||||
using std::string;
|
|
||||||
|
|
||||||
namespace lyx {
|
|
||||||
|
|
||||||
using support::bformat;
|
|
||||||
using support::contains;
|
|
||||||
|
|
||||||
namespace frontend {
|
|
||||||
|
|
||||||
|
|
||||||
ControlSpellchecker::ControlSpellchecker(Dialog & parent)
|
|
||||||
: Controller(parent), exitEarly_(false),
|
|
||||||
oldval_(0), newvalue_(0), count_(0), speller_(0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ControlSpellchecker::~ControlSpellchecker()
|
|
||||||
{
|
|
||||||
delete speller_;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static SpellBase * getSpeller(BufferParams const & bp)
|
|
||||||
{
|
|
||||||
string lang = (lyxrc.isp_use_alt_lang)
|
|
||||||
? lyxrc.isp_alt_lang
|
|
||||||
: bp.language->code();
|
|
||||||
|
|
||||||
#if defined(USE_ASPELL)
|
|
||||||
if (lyxrc.use_spell_lib)
|
|
||||||
return new ASpell(bp, lang);
|
|
||||||
#elif defined(USE_PSPELL)
|
|
||||||
if (lyxrc.use_spell_lib)
|
|
||||||
return new PSpell(bp, lang);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(USE_ISPELL)
|
|
||||||
lang = lyxrc.isp_use_alt_lang ?
|
|
||||||
lyxrc.isp_alt_lang : bp.language->lang();
|
|
||||||
|
|
||||||
return new ISpell(bp, lang);
|
|
||||||
#else
|
|
||||||
return new SpellBase;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool ControlSpellchecker::initialiseParams(std::string const &)
|
|
||||||
{
|
|
||||||
LYXERR(Debug::GUI) << "Spellchecker::initialiseParams" << endl;
|
|
||||||
|
|
||||||
speller_ = getSpeller(buffer().params());
|
|
||||||
if (!speller_)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// reset values to initial
|
|
||||||
oldval_ = 0;
|
|
||||||
newvalue_ = 0;
|
|
||||||
count_ = 0;
|
|
||||||
|
|
||||||
bool const success = speller_->error().empty();
|
|
||||||
|
|
||||||
if (!success) {
|
|
||||||
Alert::error(_("Spellchecker error"),
|
|
||||||
_("The spellchecker could not be started\n")
|
|
||||||
+ speller_->error());
|
|
||||||
delete speller_;
|
|
||||||
speller_ = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return success;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void ControlSpellchecker::clearParams()
|
|
||||||
{
|
|
||||||
LYXERR(Debug::GUI) << "Spellchecker::clearParams" << endl;
|
|
||||||
delete speller_;
|
|
||||||
speller_ = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static bool isLetter(DocIterator const & dit)
|
|
||||||
{
|
|
||||||
return dit.inTexted()
|
|
||||||
&& dit.inset().allowSpellCheck()
|
|
||||||
&& dit.pos() != dit.lastpos()
|
|
||||||
&& (dit.paragraph().isLetter(dit.pos())
|
|
||||||
// We want to pass the ' and escape chars to ispell
|
|
||||||
|| contains(from_utf8(lyxrc.isp_esc_chars + '\''),
|
|
||||||
dit.paragraph().getChar(dit.pos())))
|
|
||||||
&& !dit.paragraph().isDeleted(dit.pos());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static WordLangTuple nextWord(Cursor & cur, ptrdiff_t & progress)
|
|
||||||
{
|
|
||||||
BufferParams const & bp = cur.bv().buffer().params();
|
|
||||||
bool inword = false;
|
|
||||||
bool ignoreword = false;
|
|
||||||
cur.resetAnchor();
|
|
||||||
docstring word;
|
|
||||||
string lang_code;
|
|
||||||
|
|
||||||
while (cur.depth()) {
|
|
||||||
if (isLetter(cur)) {
|
|
||||||
if (!inword) {
|
|
||||||
inword = true;
|
|
||||||
ignoreword = false;
|
|
||||||
cur.resetAnchor();
|
|
||||||
word.clear();
|
|
||||||
lang_code = cur.paragraph().getFontSettings(bp, cur.pos()).language()->code();
|
|
||||||
}
|
|
||||||
// Insets like optional hyphens and ligature
|
|
||||||
// break are part of a word.
|
|
||||||
if (!cur.paragraph().isInset(cur.pos())) {
|
|
||||||
Paragraph::value_type const c =
|
|
||||||
cur.paragraph().getChar(cur.pos());
|
|
||||||
word += c;
|
|
||||||
if (isDigit(c))
|
|
||||||
ignoreword = true;
|
|
||||||
}
|
|
||||||
} else { // !isLetter(cur)
|
|
||||||
if (inword)
|
|
||||||
if (!word.empty() && !ignoreword) {
|
|
||||||
cur.setSelection();
|
|
||||||
return WordLangTuple(word, lang_code);
|
|
||||||
}
|
|
||||||
inword = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
cur.forwardPos();
|
|
||||||
++progress;
|
|
||||||
}
|
|
||||||
|
|
||||||
return WordLangTuple(docstring(), string());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void ControlSpellchecker::check()
|
|
||||||
{
|
|
||||||
LYXERR(Debug::GUI) << "Check the spelling of a word" << endl;
|
|
||||||
|
|
||||||
SpellBase::Result res = SpellBase::OK;
|
|
||||||
|
|
||||||
Cursor cur = bufferview()->cursor();
|
|
||||||
while (cur && cur.pos() && isLetter(cur))
|
|
||||||
cur.backwardPos();
|
|
||||||
|
|
||||||
ptrdiff_t start = 0;
|
|
||||||
ptrdiff_t total = 0;
|
|
||||||
DocIterator it = DocIterator(buffer().inset());
|
|
||||||
for (start = 0; it != cur; it.forwardPos())
|
|
||||||
++start;
|
|
||||||
|
|
||||||
for (total = start; it; it.forwardPos())
|
|
||||||
++total;
|
|
||||||
|
|
||||||
exitEarly_ = false;
|
|
||||||
|
|
||||||
while (res == SpellBase::OK || res == SpellBase::IGNORED_WORD) {
|
|
||||||
word_ = nextWord(cur, start);
|
|
||||||
|
|
||||||
// end of document
|
|
||||||
if (getWord().empty()) {
|
|
||||||
showSummary();
|
|
||||||
exitEarly_ = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
++count_;
|
|
||||||
|
|
||||||
// Update slider if and only if value has changed
|
|
||||||
float progress = total ? float(start)/total : 1;
|
|
||||||
newvalue_ = int(100.0 * progress);
|
|
||||||
if (newvalue_!= oldval_) {
|
|
||||||
LYXERR(Debug::GUI) << "Updating spell progress." << endl;
|
|
||||||
oldval_ = newvalue_;
|
|
||||||
// set progress bar
|
|
||||||
dialog().partialUpdateView(SPELL_PROGRESSED);
|
|
||||||
}
|
|
||||||
|
|
||||||
// speller might be dead ...
|
|
||||||
if (!checkAlive())
|
|
||||||
return;
|
|
||||||
|
|
||||||
res = speller_->check(word_);
|
|
||||||
|
|
||||||
// ... or it might just be reporting an error
|
|
||||||
if (!checkAlive())
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
LYXERR(Debug::GUI) << "Found word \"" << to_utf8(getWord()) << "\"" << endl;
|
|
||||||
|
|
||||||
int const size = cur.selEnd().pos() - cur.selBegin().pos();
|
|
||||||
cur.pos() -= size;
|
|
||||||
bufferview()->putSelectionAt(cur, size, false);
|
|
||||||
// FIXME: if we used a lfun like in find/replace, dispatch would do
|
|
||||||
// that for us
|
|
||||||
bufferview()->update();
|
|
||||||
// FIXME: this Controller is very badly designed...
|
|
||||||
lyxview().currentWorkArea()->redraw();
|
|
||||||
|
|
||||||
// set suggestions
|
|
||||||
if (res != SpellBase::OK && res != SpellBase::IGNORED_WORD) {
|
|
||||||
LYXERR(Debug::GUI) << "Found a word needing checking." << endl;
|
|
||||||
dialog().partialUpdateView(SPELL_FOUND_WORD);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool ControlSpellchecker::checkAlive()
|
|
||||||
{
|
|
||||||
if (speller_->alive() && speller_->error().empty())
|
|
||||||
return true;
|
|
||||||
|
|
||||||
docstring message;
|
|
||||||
if (speller_->error().empty())
|
|
||||||
message = _("The spellchecker has died for some reason.\n"
|
|
||||||
"Maybe it has been killed.");
|
|
||||||
else
|
|
||||||
message = _("The spellchecker has failed.\n") + speller_->error();
|
|
||||||
|
|
||||||
dialog().slotClose();
|
|
||||||
|
|
||||||
Alert::error(_("The spellchecker has failed"), message);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void ControlSpellchecker::showSummary()
|
|
||||||
{
|
|
||||||
if (!checkAlive() || count_ == 0) {
|
|
||||||
dialog().slotClose();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
docstring message;
|
|
||||||
if (count_ != 1)
|
|
||||||
message = bformat(_("%1$d words checked."), count_);
|
|
||||||
else
|
|
||||||
message = _("One word checked.");
|
|
||||||
|
|
||||||
dialog().slotClose();
|
|
||||||
Alert::information(_("Spelling check completed"), message);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void ControlSpellchecker::replace(docstring const & replacement)
|
|
||||||
{
|
|
||||||
LYXERR(Debug::GUI) << "ControlSpellchecker::replace("
|
|
||||||
<< to_utf8(replacement) << ")" << std::endl;
|
|
||||||
cap::replaceSelectionWithString(bufferview()->cursor(), replacement, true);
|
|
||||||
buffer().markDirty();
|
|
||||||
// If we used an LFUN, we would not need that
|
|
||||||
bufferview()->update();
|
|
||||||
// fix up the count
|
|
||||||
--count_;
|
|
||||||
check();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void ControlSpellchecker::replaceAll(docstring const & replacement)
|
|
||||||
{
|
|
||||||
// TODO: add to list
|
|
||||||
replace(replacement);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void ControlSpellchecker::insert()
|
|
||||||
{
|
|
||||||
speller_->insert(word_);
|
|
||||||
check();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
docstring const ControlSpellchecker::getSuggestion() const
|
|
||||||
{
|
|
||||||
return speller_->nextMiss();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
docstring const ControlSpellchecker::getWord() const
|
|
||||||
{
|
|
||||||
return word_.word();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void ControlSpellchecker::ignoreAll()
|
|
||||||
{
|
|
||||||
speller_->accept(word_);
|
|
||||||
check();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace frontend
|
|
||||||
} // namespace lyx
|
|
@ -1,104 +0,0 @@
|
|||||||
// -*- C++ -*-
|
|
||||||
/**
|
|
||||||
* \file ControlSpellchecker.h
|
|
||||||
* This file is part of LyX, the document processor.
|
|
||||||
* Licence details can be found in the file COPYING.
|
|
||||||
*
|
|
||||||
* \author Edwin Leuven
|
|
||||||
*
|
|
||||||
* Full author contact details are available in file CREDITS.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef CONTROLSPELLCHECKER_H
|
|
||||||
#define CONTROLSPELLCHECKER_H
|
|
||||||
|
|
||||||
#include "Dialog.h"
|
|
||||||
#include "WordLangTuple.h"
|
|
||||||
|
|
||||||
|
|
||||||
namespace lyx {
|
|
||||||
|
|
||||||
class SpellBase;
|
|
||||||
|
|
||||||
namespace frontend {
|
|
||||||
|
|
||||||
/** A controller for Spellchecker dialogs.
|
|
||||||
*/
|
|
||||||
class ControlSpellchecker : public Controller
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
enum State {
|
|
||||||
SPELL_PROGRESSED, //< update progress bar
|
|
||||||
SPELL_FOUND_WORD //< found a bad word
|
|
||||||
};
|
|
||||||
|
|
||||||
ControlSpellchecker(Dialog &);
|
|
||||||
~ControlSpellchecker();
|
|
||||||
///
|
|
||||||
virtual bool initialiseParams(std::string const & data);
|
|
||||||
///
|
|
||||||
virtual void clearParams();
|
|
||||||
/// Not needed here
|
|
||||||
virtual void dispatchParams() {}
|
|
||||||
///
|
|
||||||
virtual bool isBufferDependent() const { return true; }
|
|
||||||
///
|
|
||||||
virtual bool exitEarly() const { return exitEarly_; }
|
|
||||||
|
|
||||||
/// replace word with replacement
|
|
||||||
void replace(docstring const &);
|
|
||||||
|
|
||||||
/// replace all occurances of word
|
|
||||||
void replaceAll(docstring const &);
|
|
||||||
|
|
||||||
/// insert word in personal dictionary
|
|
||||||
void insert();
|
|
||||||
|
|
||||||
/// ignore all occurances of word
|
|
||||||
void ignoreAll();
|
|
||||||
|
|
||||||
/// check text until next misspelled/unknown word
|
|
||||||
/// returns true when finished
|
|
||||||
void check();
|
|
||||||
|
|
||||||
/// get suggestion
|
|
||||||
docstring const getSuggestion() const;
|
|
||||||
|
|
||||||
/// get word
|
|
||||||
docstring const getWord() const;
|
|
||||||
|
|
||||||
/// returns progress value
|
|
||||||
int getProgress() const { return oldval_; }
|
|
||||||
|
|
||||||
/// returns word count
|
|
||||||
int getCount() const { return count_; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
/// give error message is spellchecker dies
|
|
||||||
bool checkAlive();
|
|
||||||
|
|
||||||
/// show count of checked words at normal exit
|
|
||||||
void showSummary();
|
|
||||||
|
|
||||||
private:
|
|
||||||
/// set to true when spellchecking is finished
|
|
||||||
bool exitEarly_;
|
|
||||||
|
|
||||||
/// current word being checked and lang code
|
|
||||||
WordLangTuple word_;
|
|
||||||
|
|
||||||
/// values for progress
|
|
||||||
int oldval_;
|
|
||||||
int newvalue_;
|
|
||||||
|
|
||||||
/// word count
|
|
||||||
int count_;
|
|
||||||
|
|
||||||
/// The actual spellchecker object
|
|
||||||
SpellBase * speller_;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace frontend
|
|
||||||
} // namespace lyx
|
|
||||||
|
|
||||||
#endif // CONTROLSPELLCHECKER_H
|
|
@ -20,7 +20,6 @@ SOURCEFILES = \
|
|||||||
ControlPrint.cpp \
|
ControlPrint.cpp \
|
||||||
ControlSearch.cpp \
|
ControlSearch.cpp \
|
||||||
ControlSendto.cpp \
|
ControlSendto.cpp \
|
||||||
ControlSpellchecker.cpp \
|
|
||||||
ControlThesaurus.cpp \
|
ControlThesaurus.cpp \
|
||||||
ControlToc.cpp \
|
ControlToc.cpp \
|
||||||
frontend_helpers.cpp
|
frontend_helpers.cpp
|
||||||
@ -38,7 +37,6 @@ HEADERFILES = \
|
|||||||
ControlPrint.h \
|
ControlPrint.h \
|
||||||
ControlSearch.h \
|
ControlSearch.h \
|
||||||
ControlSendto.h \
|
ControlSendto.h \
|
||||||
ControlSpellchecker.h \
|
|
||||||
ControlThesaurus.h \
|
ControlThesaurus.h \
|
||||||
ControlToc.h \
|
ControlToc.h \
|
||||||
frontend_helpers.h
|
frontend_helpers.h
|
||||||
|
@ -30,7 +30,6 @@
|
|||||||
#include "GuiSearch.h"
|
#include "GuiSearch.h"
|
||||||
#include "GuiSendto.h"
|
#include "GuiSendto.h"
|
||||||
#include "GuiShowFile.h"
|
#include "GuiShowFile.h"
|
||||||
#include "GuiSpellchecker.h"
|
|
||||||
#include "GuiToc.h"
|
#include "GuiToc.h"
|
||||||
#include "GuiView.h"
|
#include "GuiView.h"
|
||||||
#include "TocWidget.h"
|
#include "TocWidget.h"
|
||||||
@ -141,110 +140,107 @@ Dialog * Dialogs::build(string const & name)
|
|||||||
{
|
{
|
||||||
BOOST_ASSERT(isValidName(name));
|
BOOST_ASSERT(isValidName(name));
|
||||||
|
|
||||||
Dialog * dialog = 0;
|
|
||||||
GuiViewBase & guiview = static_cast<GuiViewBase &>(lyxview_);
|
GuiViewBase & guiview = static_cast<GuiViewBase &>(lyxview_);
|
||||||
|
|
||||||
if (name == "aboutlyx") {
|
if (name == "aboutlyx")
|
||||||
dialog = createGuiAbout(lyxview_);
|
return createGuiAbout(lyxview_);
|
||||||
} else if (name == "bibitem") {
|
if (name == "bibitem")
|
||||||
dialog = new GuiBibitemDialog(lyxview_);
|
return new GuiBibitemDialog(lyxview_);
|
||||||
} else if (name == "bibtex") {
|
if (name == "bibtex")
|
||||||
dialog = createGuiBibtex(lyxview_);
|
return createGuiBibtex(lyxview_);
|
||||||
} else if (name == "box") {
|
if (name == "box")
|
||||||
dialog = createGuiBox(lyxview_);
|
return createGuiBox(lyxview_);
|
||||||
} else if (name == "branch") {
|
if (name == "branch")
|
||||||
dialog = createGuiBranch(lyxview_);
|
return createGuiBranch(lyxview_);
|
||||||
} else if (name == "changes") {
|
if (name == "changes")
|
||||||
dialog = createGuiChanges(lyxview_);
|
return createGuiChanges(lyxview_);
|
||||||
} else if (name == "character") {
|
if (name == "character")
|
||||||
dialog = createGuiCharacter(lyxview_);
|
return createGuiCharacter(lyxview_);
|
||||||
} else if (name == "citation") {
|
if (name == "citation")
|
||||||
dialog = createGuiCitation(lyxview_);
|
return createGuiCitation(lyxview_);
|
||||||
} else if (name == "document") {
|
if (name == "document")
|
||||||
dialog = new GuiDocumentDialog(lyxview_);
|
return new GuiDocumentDialog(lyxview_);
|
||||||
} else if (name == "embedding") {
|
if (name == "embedding")
|
||||||
dialog = createGuiEmbeddedFiles(lyxview_);
|
return createGuiEmbeddedFiles(lyxview_);
|
||||||
} else if (name == "errorlist") {
|
if (name == "errorlist")
|
||||||
dialog = createGuiErrorList(lyxview_);
|
return createGuiErrorList(lyxview_);
|
||||||
} else if (name == "ert") {
|
if (name == "ert")
|
||||||
dialog = createGuiERT(lyxview_);
|
return createGuiERT(lyxview_);
|
||||||
} else if (name == "external") {
|
if (name == "external")
|
||||||
dialog = new GuiExternalDialog(lyxview_);
|
return new GuiExternalDialog(lyxview_);
|
||||||
} else if (name == "file") {
|
if (name == "file")
|
||||||
dialog = createGuiShowFile(lyxview_);
|
return createGuiShowFile(lyxview_);
|
||||||
} else if (name == "findreplace") {
|
if (name == "findreplace")
|
||||||
dialog = new GuiSearchDialog(lyxview_);
|
return new GuiSearchDialog(lyxview_);
|
||||||
} else if (name == "float") {
|
if (name == "float")
|
||||||
dialog = createGuiFloat(lyxview_);
|
return createGuiFloat(lyxview_);
|
||||||
} else if (name == "graphics") {
|
if (name == "graphics")
|
||||||
dialog = new GuiGraphicsDialog(lyxview_);
|
return new GuiGraphicsDialog(lyxview_);
|
||||||
} else if (name == "include") {
|
if (name == "include")
|
||||||
dialog = createGuiInclude(lyxview_);
|
return createGuiInclude(lyxview_);
|
||||||
} else if (name == "index") {
|
if (name == "index")
|
||||||
dialog = new GuiIndexDialog(lyxview_);
|
return new GuiIndexDialog(lyxview_);
|
||||||
} else if (name == "nomenclature") {
|
if (name == "nomenclature")
|
||||||
dialog = new GuiNomenclDialog(lyxview_);
|
return new GuiNomenclDialog(lyxview_);
|
||||||
} else if (name == "label") {
|
if (name == "label")
|
||||||
dialog = new GuiLabelDialog(lyxview_);
|
return new GuiLabelDialog(lyxview_);
|
||||||
} else if (name == "log") {
|
if (name == "log")
|
||||||
dialog = createGuiLog(lyxview_);
|
return createGuiLog(lyxview_);
|
||||||
} else if (name == "view-source") {
|
if (name == "view-source")
|
||||||
dialog = createGuiViewSource(lyxview_);
|
return createGuiViewSource(lyxview_);
|
||||||
} else if (name == "mathdelimiter") {
|
if (name == "mathdelimiter")
|
||||||
dialog = new GuiDelimiterDialog(lyxview_);
|
return new GuiDelimiterDialog(lyxview_);
|
||||||
} else if (name == "mathmatrix") {
|
if (name == "mathmatrix")
|
||||||
dialog = new GuiMathMatrixDialog(lyxview_);
|
return new GuiMathMatrixDialog(lyxview_);
|
||||||
} else if (name == "note") {
|
if (name == "note")
|
||||||
dialog = createGuiNote(lyxview_);
|
return createGuiNote(lyxview_);
|
||||||
} else if (name == "paragraph") {
|
if (name == "paragraph") {
|
||||||
#ifdef USE_DOCK_WIDGET
|
#ifdef USE_DOCK_WIDGET
|
||||||
DockView<ControlParagraph, GuiParagraph> * dv =
|
return new DockView<ControlParagraph, GuiParagraph>(guiview, name,
|
||||||
new DockView<ControlParagraph, GuiParagraph>(guiview, name,
|
Qt::TopDockWidgetArea);
|
||||||
Qt::TopDockWidgetArea);
|
|
||||||
#else
|
#else
|
||||||
DialogView<ControlParagraph, GuiParagraph> * dv =
|
return new DialogView<ControlParagraph, GuiParagraph>(guiview, name);
|
||||||
new DialogView<ControlParagraph, GuiParagraph>(guiview, name);
|
|
||||||
#endif
|
#endif
|
||||||
dialog = dv;
|
}
|
||||||
} else if (name == "prefs") {
|
if (name == "prefs")
|
||||||
dialog = new GuiPrefsDialog(lyxview_);
|
return new GuiPrefsDialog(lyxview_);
|
||||||
} else if (name == "print") {
|
if (name == "print")
|
||||||
dialog = new GuiPrintDialog(lyxview_);
|
return new GuiPrintDialog(lyxview_);
|
||||||
} else if (name == "ref") {
|
if (name == "ref")
|
||||||
dialog = createGuiRef(lyxview_);
|
return createGuiRef(lyxview_);
|
||||||
} else if (name == "sendto") {
|
if (name == "sendto")
|
||||||
dialog = new GuiSendtoDialog(lyxview_);
|
return new GuiSendtoDialog(lyxview_);
|
||||||
} else if (name == "spellchecker") {
|
if (name == "spellchecker")
|
||||||
dialog = new GuiSpellcheckerDialog(lyxview_);
|
return createGuiSpellchecker(lyxview_);
|
||||||
} else if (name == "tabular") {
|
if (name == "tabular")
|
||||||
dialog = createGuiTabular(lyxview_);
|
return createGuiTabular(lyxview_);
|
||||||
} else if (name == "tabularcreate") {
|
if (name == "tabularcreate")
|
||||||
dialog = createGuiTabularCreate(lyxview_);
|
return createGuiTabularCreate(lyxview_);
|
||||||
} else if (name == "texinfo") {
|
if (name == "texinfo")
|
||||||
dialog = createGuiTexInfo(lyxview_);
|
return createGuiTexInfo(lyxview_);
|
||||||
#ifdef HAVE_LIBAIKSAURUS
|
#ifdef HAVE_LIBAIKSAURUS
|
||||||
} else if (name == "thesaurus") {
|
if (name == "thesaurus")
|
||||||
dialog = new GuiThesaurusDialog(lyxview_);
|
return new GuiThesaurusDialog(lyxview_);
|
||||||
#endif
|
#endif
|
||||||
} else if (name == "toc") {
|
if (name == "toc") {
|
||||||
#ifdef Q_WS_MACX
|
#ifdef Q_WS_MACX
|
||||||
// On Mac show as a drawer at the right
|
// On Mac show as a drawer at the right
|
||||||
dialog = new DockView<GuiToc, TocWidget>(guiview, name,
|
return new DockView<GuiToc, TocWidget>(guiview, name,
|
||||||
Qt::RightDockWidgetArea, Qt::Drawer);
|
Qt::RightDockWidgetArea, Qt::Drawer);
|
||||||
#else
|
#else
|
||||||
dialog = new DockView<GuiToc, TocWidget>(guiview, name);
|
return new DockView<GuiToc, TocWidget>(guiview, name);
|
||||||
#endif
|
#endif
|
||||||
} else if (name == "url") {
|
|
||||||
dialog = new GuiURLDialog(lyxview_);
|
|
||||||
} else if (name == "vspace") {
|
|
||||||
dialog = createGuiVSpace(lyxview_);
|
|
||||||
} else if (name == "wrap") {
|
|
||||||
dialog = createGuiWrap(lyxview_);
|
|
||||||
} else if (name == "listings") {
|
|
||||||
dialog = createGuiListings(lyxview_);
|
|
||||||
}
|
}
|
||||||
|
if (name == "url")
|
||||||
|
return new GuiURLDialog(lyxview_);
|
||||||
|
if (name == "vspace")
|
||||||
|
return createGuiVSpace(lyxview_);
|
||||||
|
if (name == "wrap")
|
||||||
|
return createGuiWrap(lyxview_);
|
||||||
|
if (name == "listings")
|
||||||
|
return createGuiListings(lyxview_);
|
||||||
|
|
||||||
return dialog;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
* Licence details can be found in the file COPYING.
|
* Licence details can be found in the file COPYING.
|
||||||
*
|
*
|
||||||
* \author John Levon
|
* \author John Levon
|
||||||
|
* \author Edwin Leuven
|
||||||
*
|
*
|
||||||
* Full author contact details are available in file CREDITS.
|
* Full author contact details are available in file CREDITS.
|
||||||
*/
|
*/
|
||||||
@ -12,9 +13,23 @@
|
|||||||
|
|
||||||
#include "GuiSpellchecker.h"
|
#include "GuiSpellchecker.h"
|
||||||
|
|
||||||
#include "ControlSpellchecker.h"
|
|
||||||
#include "qt_helpers.h"
|
#include "qt_helpers.h"
|
||||||
|
|
||||||
|
#include "Buffer.h"
|
||||||
|
#include "BufferParams.h"
|
||||||
|
#include "BufferView.h"
|
||||||
|
#include "Cursor.h"
|
||||||
|
#include "CutAndPaste.h"
|
||||||
|
#include "debug.h"
|
||||||
|
#include "gettext.h"
|
||||||
|
#include "Language.h"
|
||||||
|
#include "LyXRC.h"
|
||||||
|
#include "Paragraph.h"
|
||||||
|
|
||||||
|
#include "support/textutils.h"
|
||||||
|
#include "support/convert.h"
|
||||||
|
#include "support/docstring.h"
|
||||||
|
|
||||||
#include <QProgressBar>
|
#include <QProgressBar>
|
||||||
#include <QLineEdit>
|
#include <QLineEdit>
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
@ -25,33 +40,54 @@
|
|||||||
#include <QTextCharFormat>
|
#include <QTextCharFormat>
|
||||||
#include <QTextDocument>
|
#include <QTextDocument>
|
||||||
|
|
||||||
|
#if defined(USE_ASPELL)
|
||||||
|
# include "ASpell_local.h"
|
||||||
|
#elif defined(USE_PSPELL)
|
||||||
|
# include "PSpell.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(USE_ISPELL)
|
||||||
|
# include "ISpell.h"
|
||||||
|
#else
|
||||||
|
# include "SpellBase.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "frontends/alert.h"
|
||||||
|
// FIXME: those two headers are needed because of the
|
||||||
|
// WorkArea::redraw() call below.
|
||||||
|
#include "frontends/LyXView.h"
|
||||||
|
#include "frontends/WorkArea.h"
|
||||||
|
|
||||||
|
using std::advance;
|
||||||
|
using std::distance;
|
||||||
|
using std::endl;
|
||||||
using std::string;
|
using std::string;
|
||||||
|
|
||||||
|
|
||||||
namespace lyx {
|
namespace lyx {
|
||||||
namespace frontend {
|
namespace frontend {
|
||||||
|
|
||||||
GuiSpellcheckerDialog::GuiSpellcheckerDialog(LyXView & lv)
|
using support::bformat;
|
||||||
: GuiDialog(lv, "spellchecker")
|
using support::contains;
|
||||||
|
|
||||||
|
GuiSpellchecker::GuiSpellchecker(LyXView & lv)
|
||||||
|
: GuiDialog(lv, "spellchecker"), Controller(this), exitEarly_(false),
|
||||||
|
oldval_(0), newvalue_(0), count_(0), speller_(0)
|
||||||
{
|
{
|
||||||
setupUi(this);
|
setupUi(this);
|
||||||
setViewTitle(_("Spellchecker"));
|
setViewTitle(_("Spellchecker"));
|
||||||
setController(new ControlSpellchecker(*this));
|
setController(this, false);
|
||||||
|
|
||||||
connect(closePB, SIGNAL(clicked()), this, SLOT(slotClose()));
|
connect(closePB, SIGNAL(clicked()), this, SLOT(slotClose()));
|
||||||
|
connect(replacePB, SIGNAL(clicked()), this, SLOT(replaceClicked()));
|
||||||
|
connect(ignorePB, SIGNAL(clicked()), this, SLOT(ignoreClicked()));
|
||||||
|
connect(replacePB_3, SIGNAL(clicked()), this, SLOT(acceptClicked()));
|
||||||
|
connect(addPB, SIGNAL(clicked()), this, SLOT(addClicked()));
|
||||||
|
|
||||||
connect(replaceCO, SIGNAL(highlighted(const QString &)),
|
connect(replaceCO, SIGNAL(highlighted(QString)),
|
||||||
this, SLOT(replaceChanged(const QString &)));
|
this, SLOT(replaceChanged(QString)));
|
||||||
connect(replacePB, SIGNAL(clicked()),
|
|
||||||
this, SLOT(replaceClicked()));
|
|
||||||
connect(ignorePB, SIGNAL(clicked()),
|
|
||||||
this, SLOT(ignoreClicked()));
|
|
||||||
connect(replacePB_3, SIGNAL(clicked()),
|
|
||||||
this, SLOT(acceptClicked()));
|
|
||||||
connect(addPB, SIGNAL(clicked()),
|
|
||||||
this, SLOT(addClicked()));
|
|
||||||
connect(suggestionsLW, SIGNAL(itemDoubleClicked(QListWidgetItem*)),
|
connect(suggestionsLW, SIGNAL(itemDoubleClicked(QListWidgetItem*)),
|
||||||
this, SLOT(replaceClicked() ) );
|
this, SLOT(replaceClicked()));
|
||||||
connect(suggestionsLW, SIGNAL(itemClicked(QListWidgetItem*)),
|
connect(suggestionsLW, SIGNAL(itemClicked(QListWidgetItem*)),
|
||||||
this, SLOT(suggestionChanged(QListWidgetItem*)));
|
this, SLOT(suggestionChanged(QListWidgetItem*)));
|
||||||
|
|
||||||
@ -62,37 +98,13 @@ GuiSpellcheckerDialog::GuiSpellcheckerDialog(LyXView & lv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ControlSpellchecker & GuiSpellcheckerDialog::controller()
|
GuiSpellchecker::~GuiSpellchecker()
|
||||||
{
|
{
|
||||||
return static_cast<ControlSpellchecker &>(GuiDialog::controller());
|
delete speller_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void GuiSpellcheckerDialog::acceptClicked()
|
void GuiSpellchecker::suggestionChanged(QListWidgetItem * item)
|
||||||
{
|
|
||||||
accept();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void GuiSpellcheckerDialog::addClicked()
|
|
||||||
{
|
|
||||||
add();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void GuiSpellcheckerDialog::replaceClicked()
|
|
||||||
{
|
|
||||||
replace();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void GuiSpellcheckerDialog::ignoreClicked()
|
|
||||||
{
|
|
||||||
ignore();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void GuiSpellcheckerDialog::suggestionChanged(QListWidgetItem * item)
|
|
||||||
{
|
{
|
||||||
if (replaceCO->count() != 0)
|
if (replaceCO->count() != 0)
|
||||||
replaceCO->setItemText(0, item->text());
|
replaceCO->setItemText(0, item->text());
|
||||||
@ -103,12 +115,12 @@ void GuiSpellcheckerDialog::suggestionChanged(QListWidgetItem * item)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void GuiSpellcheckerDialog::replaceChanged(const QString & str)
|
void GuiSpellchecker::replaceChanged(const QString & str)
|
||||||
{
|
{
|
||||||
if (suggestionsLW->currentItem()->text() == str)
|
if (suggestionsLW->currentItem()->text() == str)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (int i = 0; i < suggestionsLW->count(); ++i) {
|
for (int i = 0; i != suggestionsLW->count(); ++i) {
|
||||||
if (suggestionsLW->item(i)->text() == str) {
|
if (suggestionsLW->item(i)->text() == str) {
|
||||||
suggestionsLW->setCurrentRow(i);
|
suggestionsLW->setCurrentRow(i);
|
||||||
break;
|
break;
|
||||||
@ -117,64 +129,64 @@ void GuiSpellcheckerDialog::replaceChanged(const QString & str)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void GuiSpellcheckerDialog::closeEvent(QCloseEvent * e)
|
void GuiSpellchecker::closeEvent(QCloseEvent * e)
|
||||||
{
|
{
|
||||||
slotClose();
|
slotClose();
|
||||||
GuiDialog::closeEvent(e);
|
GuiDialog::closeEvent(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void GuiSpellcheckerDialog::reject()
|
void GuiSpellchecker::reject()
|
||||||
{
|
{
|
||||||
slotClose();
|
slotClose();
|
||||||
QDialog::reject();
|
QDialog::reject();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void GuiSpellcheckerDialog::updateContents()
|
void GuiSpellchecker::updateContents()
|
||||||
{
|
{
|
||||||
if (isVisibleView() || controller().exitEarly())
|
if (isVisibleView() || exitEarly())
|
||||||
controller().check();
|
check();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void GuiSpellcheckerDialog::accept()
|
void GuiSpellchecker::accept()
|
||||||
{
|
{
|
||||||
controller().ignoreAll();
|
ignoreAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void GuiSpellcheckerDialog::add()
|
void GuiSpellchecker::add()
|
||||||
{
|
{
|
||||||
controller().insert();
|
insert();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void GuiSpellcheckerDialog::ignore()
|
void GuiSpellchecker::ignore()
|
||||||
{
|
{
|
||||||
controller().check();
|
check();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void GuiSpellcheckerDialog::replace()
|
void GuiSpellchecker::replace()
|
||||||
{
|
{
|
||||||
controller().replace(qstring_to_ucs4(replaceCO->currentText()));
|
replace(qstring_to_ucs4(replaceCO->currentText()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void GuiSpellcheckerDialog::partialUpdate(int state)
|
void GuiSpellchecker::partialUpdate(int state)
|
||||||
{
|
{
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case ControlSpellchecker::SPELL_PROGRESSED:
|
case SPELL_PROGRESSED:
|
||||||
spellcheckPR->setValue(controller().getProgress());
|
spellcheckPR->setValue(getProgress());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ControlSpellchecker::SPELL_FOUND_WORD: {
|
case SPELL_FOUND_WORD: {
|
||||||
wordED->setText(toqstr(controller().getWord()));
|
wordED->setText(toqstr(getWord()));
|
||||||
suggestionsLW->clear();
|
suggestionsLW->clear();
|
||||||
|
|
||||||
docstring w;
|
docstring w;
|
||||||
while (!(w = controller().getSuggestion()).empty())
|
while (!(w = getSuggestion()).empty())
|
||||||
suggestionsLW->addItem(toqstr(w));
|
suggestionsLW->addItem(toqstr(w));
|
||||||
|
|
||||||
if (suggestionsLW->count() == 0)
|
if (suggestionsLW->count() == 0)
|
||||||
@ -188,6 +200,283 @@ void GuiSpellcheckerDialog::partialUpdate(int state)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static SpellBase * getSpeller(BufferParams const & bp)
|
||||||
|
{
|
||||||
|
string lang = (lyxrc.isp_use_alt_lang)
|
||||||
|
? lyxrc.isp_alt_lang
|
||||||
|
: bp.language->code();
|
||||||
|
|
||||||
|
#if defined(USE_ASPELL)
|
||||||
|
if (lyxrc.use_spell_lib)
|
||||||
|
return new ASpell(bp, lang);
|
||||||
|
#elif defined(USE_PSPELL)
|
||||||
|
if (lyxrc.use_spell_lib)
|
||||||
|
return new PSpell(bp, lang);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(USE_ISPELL)
|
||||||
|
lang = lyxrc.isp_use_alt_lang ?
|
||||||
|
lyxrc.isp_alt_lang : bp.language->lang();
|
||||||
|
|
||||||
|
return new ISpell(bp, lang);
|
||||||
|
#else
|
||||||
|
return new SpellBase;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool GuiSpellchecker::initialiseParams(std::string const &)
|
||||||
|
{
|
||||||
|
LYXERR(Debug::GUI) << "Spellchecker::initialiseParams" << endl;
|
||||||
|
|
||||||
|
speller_ = getSpeller(buffer().params());
|
||||||
|
if (!speller_)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// reset values to initial
|
||||||
|
oldval_ = 0;
|
||||||
|
newvalue_ = 0;
|
||||||
|
count_ = 0;
|
||||||
|
|
||||||
|
bool const success = speller_->error().empty();
|
||||||
|
|
||||||
|
if (!success) {
|
||||||
|
Alert::error(_("Spellchecker error"),
|
||||||
|
_("The spellchecker could not be started\n")
|
||||||
|
+ speller_->error());
|
||||||
|
delete speller_;
|
||||||
|
speller_ = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GuiSpellchecker::clearParams()
|
||||||
|
{
|
||||||
|
LYXERR(Debug::GUI) << "Spellchecker::clearParams" << endl;
|
||||||
|
delete speller_;
|
||||||
|
speller_ = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static bool isLetter(DocIterator const & dit)
|
||||||
|
{
|
||||||
|
return dit.inTexted()
|
||||||
|
&& dit.inset().allowSpellCheck()
|
||||||
|
&& dit.pos() != dit.lastpos()
|
||||||
|
&& (dit.paragraph().isLetter(dit.pos())
|
||||||
|
// We want to pass the ' and escape chars to ispell
|
||||||
|
|| contains(from_utf8(lyxrc.isp_esc_chars + '\''),
|
||||||
|
dit.paragraph().getChar(dit.pos())))
|
||||||
|
&& !dit.paragraph().isDeleted(dit.pos());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static WordLangTuple nextWord(Cursor & cur, ptrdiff_t & progress)
|
||||||
|
{
|
||||||
|
BufferParams const & bp = cur.bv().buffer().params();
|
||||||
|
bool inword = false;
|
||||||
|
bool ignoreword = false;
|
||||||
|
cur.resetAnchor();
|
||||||
|
docstring word;
|
||||||
|
string lang_code;
|
||||||
|
|
||||||
|
while (cur.depth()) {
|
||||||
|
if (isLetter(cur)) {
|
||||||
|
if (!inword) {
|
||||||
|
inword = true;
|
||||||
|
ignoreword = false;
|
||||||
|
cur.resetAnchor();
|
||||||
|
word.clear();
|
||||||
|
lang_code = cur.paragraph().getFontSettings(bp, cur.pos()).language()->code();
|
||||||
|
}
|
||||||
|
// Insets like optional hyphens and ligature
|
||||||
|
// break are part of a word.
|
||||||
|
if (!cur.paragraph().isInset(cur.pos())) {
|
||||||
|
Paragraph::value_type const c =
|
||||||
|
cur.paragraph().getChar(cur.pos());
|
||||||
|
word += c;
|
||||||
|
if (isDigit(c))
|
||||||
|
ignoreword = true;
|
||||||
|
}
|
||||||
|
} else { // !isLetter(cur)
|
||||||
|
if (inword)
|
||||||
|
if (!word.empty() && !ignoreword) {
|
||||||
|
cur.setSelection();
|
||||||
|
return WordLangTuple(word, lang_code);
|
||||||
|
}
|
||||||
|
inword = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
cur.forwardPos();
|
||||||
|
++progress;
|
||||||
|
}
|
||||||
|
|
||||||
|
return WordLangTuple(docstring(), string());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GuiSpellchecker::check()
|
||||||
|
{
|
||||||
|
LYXERR(Debug::GUI) << "Check the spelling of a word" << endl;
|
||||||
|
|
||||||
|
SpellBase::Result res = SpellBase::OK;
|
||||||
|
|
||||||
|
Cursor cur = bufferview()->cursor();
|
||||||
|
while (cur && cur.pos() && isLetter(cur))
|
||||||
|
cur.backwardPos();
|
||||||
|
|
||||||
|
ptrdiff_t start = 0;
|
||||||
|
ptrdiff_t total = 0;
|
||||||
|
DocIterator it = DocIterator(buffer().inset());
|
||||||
|
for (start = 0; it != cur; it.forwardPos())
|
||||||
|
++start;
|
||||||
|
|
||||||
|
for (total = start; it; it.forwardPos())
|
||||||
|
++total;
|
||||||
|
|
||||||
|
exitEarly_ = false;
|
||||||
|
|
||||||
|
while (res == SpellBase::OK || res == SpellBase::IGNORED_WORD) {
|
||||||
|
word_ = nextWord(cur, start);
|
||||||
|
|
||||||
|
// end of document
|
||||||
|
if (getWord().empty()) {
|
||||||
|
showSummary();
|
||||||
|
exitEarly_ = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
++count_;
|
||||||
|
|
||||||
|
// Update slider if and only if value has changed
|
||||||
|
float progress = total ? float(start)/total : 1;
|
||||||
|
newvalue_ = int(100.0 * progress);
|
||||||
|
if (newvalue_!= oldval_) {
|
||||||
|
LYXERR(Debug::GUI) << "Updating spell progress." << endl;
|
||||||
|
oldval_ = newvalue_;
|
||||||
|
// set progress bar
|
||||||
|
dialog().partialUpdateView(SPELL_PROGRESSED);
|
||||||
|
}
|
||||||
|
|
||||||
|
// speller might be dead ...
|
||||||
|
if (!checkAlive())
|
||||||
|
return;
|
||||||
|
|
||||||
|
res = speller_->check(word_);
|
||||||
|
|
||||||
|
// ... or it might just be reporting an error
|
||||||
|
if (!checkAlive())
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
LYXERR(Debug::GUI) << "Found word \"" << to_utf8(getWord()) << "\"" << endl;
|
||||||
|
|
||||||
|
int const size = cur.selEnd().pos() - cur.selBegin().pos();
|
||||||
|
cur.pos() -= size;
|
||||||
|
bufferview()->putSelectionAt(cur, size, false);
|
||||||
|
// FIXME: if we used a lfun like in find/replace, dispatch would do
|
||||||
|
// that for us
|
||||||
|
bufferview()->update();
|
||||||
|
// FIXME: this Controller is very badly designed...
|
||||||
|
lyxview().currentWorkArea()->redraw();
|
||||||
|
|
||||||
|
// set suggestions
|
||||||
|
if (res != SpellBase::OK && res != SpellBase::IGNORED_WORD) {
|
||||||
|
LYXERR(Debug::GUI) << "Found a word needing checking." << endl;
|
||||||
|
dialog().partialUpdateView(SPELL_FOUND_WORD);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool GuiSpellchecker::checkAlive()
|
||||||
|
{
|
||||||
|
if (speller_->alive() && speller_->error().empty())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
docstring message;
|
||||||
|
if (speller_->error().empty())
|
||||||
|
message = _("The spellchecker has died for some reason.\n"
|
||||||
|
"Maybe it has been killed.");
|
||||||
|
else
|
||||||
|
message = _("The spellchecker has failed.\n") + speller_->error();
|
||||||
|
|
||||||
|
dialog().slotClose();
|
||||||
|
|
||||||
|
Alert::error(_("The spellchecker has failed"), message);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GuiSpellchecker::showSummary()
|
||||||
|
{
|
||||||
|
if (!checkAlive() || count_ == 0) {
|
||||||
|
dialog().slotClose();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
docstring message;
|
||||||
|
if (count_ != 1)
|
||||||
|
message = bformat(_("%1$d words checked."), count_);
|
||||||
|
else
|
||||||
|
message = _("One word checked.");
|
||||||
|
|
||||||
|
dialog().slotClose();
|
||||||
|
Alert::information(_("Spelling check completed"), message);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GuiSpellchecker::replace(docstring const & replacement)
|
||||||
|
{
|
||||||
|
LYXERR(Debug::GUI) << "GuiSpellchecker::replace("
|
||||||
|
<< to_utf8(replacement) << ")" << std::endl;
|
||||||
|
cap::replaceSelectionWithString(bufferview()->cursor(), replacement, true);
|
||||||
|
buffer().markDirty();
|
||||||
|
// If we used an LFUN, we would not need that
|
||||||
|
bufferview()->update();
|
||||||
|
// fix up the count
|
||||||
|
--count_;
|
||||||
|
check();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GuiSpellchecker::replaceAll(docstring const & replacement)
|
||||||
|
{
|
||||||
|
// TODO: add to list
|
||||||
|
replace(replacement);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GuiSpellchecker::insert()
|
||||||
|
{
|
||||||
|
speller_->insert(word_);
|
||||||
|
check();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
docstring GuiSpellchecker::getSuggestion() const
|
||||||
|
{
|
||||||
|
return speller_->nextMiss();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
docstring GuiSpellchecker::getWord() const
|
||||||
|
{
|
||||||
|
return word_.word();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GuiSpellchecker::ignoreAll()
|
||||||
|
{
|
||||||
|
speller_->accept(word_);
|
||||||
|
check();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Dialog * createGuiSpellchecker(LyXView & lv) { return new GuiSpellchecker(lv); }
|
||||||
|
|
||||||
} // namespace frontend
|
} // namespace frontend
|
||||||
} // namespace lyx
|
} // namespace lyx
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
*
|
*
|
||||||
* \author John Levon
|
* \author John Levon
|
||||||
* \author Kalle Dalheimer
|
* \author Kalle Dalheimer
|
||||||
|
* \author Edwin Leuven
|
||||||
*
|
*
|
||||||
* Full author contact details are available in file CREDITS.
|
* Full author contact details are available in file CREDITS.
|
||||||
*/
|
*/
|
||||||
@ -14,29 +15,35 @@
|
|||||||
#define GUISPELLCHECKER_H
|
#define GUISPELLCHECKER_H
|
||||||
|
|
||||||
#include "GuiDialog.h"
|
#include "GuiDialog.h"
|
||||||
#include "ControlSpellchecker.h"
|
|
||||||
#include "ui_SpellcheckerUi.h"
|
#include "ui_SpellcheckerUi.h"
|
||||||
|
#include "Dialog.h"
|
||||||
|
#include "WordLangTuple.h"
|
||||||
|
|
||||||
class QListWidgetItem;
|
class QListWidgetItem;
|
||||||
|
|
||||||
namespace lyx {
|
namespace lyx {
|
||||||
|
|
||||||
|
class SpellBase;
|
||||||
|
|
||||||
namespace frontend {
|
namespace frontend {
|
||||||
|
|
||||||
class GuiSpellcheckerDialog : public GuiDialog, public Ui::SpellcheckerUi
|
class GuiSpellchecker
|
||||||
|
: public GuiDialog, public Ui::SpellcheckerUi, public Controller
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GuiSpellcheckerDialog(LyXView & lv);
|
GuiSpellchecker(LyXView & lv);
|
||||||
|
~GuiSpellchecker();
|
||||||
|
|
||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
void suggestionChanged(QListWidgetItem *);
|
void suggestionChanged(QListWidgetItem *);
|
||||||
|
|
||||||
private Q_SLOTS:
|
private Q_SLOTS:
|
||||||
void acceptClicked();
|
void accept();
|
||||||
void addClicked();
|
void add();
|
||||||
void replaceClicked();
|
void ignore();
|
||||||
void ignoreClicked();
|
void replace();
|
||||||
void replaceChanged(const QString &);
|
void replaceChanged(const QString &);
|
||||||
void reject();
|
void reject();
|
||||||
|
|
||||||
@ -46,14 +53,63 @@ private:
|
|||||||
/// update from controller
|
/// update from controller
|
||||||
void partialUpdate(int id);
|
void partialUpdate(int id);
|
||||||
/// parent controller
|
/// parent controller
|
||||||
ControlSpellchecker & controller();
|
Controller & controller() { return *this; }
|
||||||
////
|
|
||||||
void accept();
|
|
||||||
void add();
|
|
||||||
void ignore();
|
|
||||||
void replace();
|
|
||||||
///
|
///
|
||||||
void updateContents();
|
void updateContents();
|
||||||
|
|
||||||
|
///
|
||||||
|
enum State {
|
||||||
|
SPELL_PROGRESSED, //< update progress bar
|
||||||
|
SPELL_FOUND_WORD //< found a bad word
|
||||||
|
};
|
||||||
|
|
||||||
|
///
|
||||||
|
bool initialiseParams(std::string const & data);
|
||||||
|
///
|
||||||
|
void clearParams();
|
||||||
|
/// Not needed here
|
||||||
|
void dispatchParams() {}
|
||||||
|
///
|
||||||
|
bool isBufferDependent() const { return true; }
|
||||||
|
///
|
||||||
|
bool exitEarly() const { return exitEarly_; }
|
||||||
|
|
||||||
|
/// replace word with replacement
|
||||||
|
void replace(docstring const &);
|
||||||
|
|
||||||
|
/// replace all occurances of word
|
||||||
|
void replaceAll(docstring const &);
|
||||||
|
/// insert word in personal dictionary
|
||||||
|
void insert();
|
||||||
|
/// ignore all occurances of word
|
||||||
|
void ignoreAll();
|
||||||
|
/// check text until next misspelled/unknown word
|
||||||
|
/// returns true when finished
|
||||||
|
void check();
|
||||||
|
/// get suggestion
|
||||||
|
docstring getSuggestion() const;
|
||||||
|
/// get word
|
||||||
|
docstring getWord() const;
|
||||||
|
/// returns progress value
|
||||||
|
int getProgress() const { return oldval_; }
|
||||||
|
/// returns word count
|
||||||
|
int getCount() const { return count_; }
|
||||||
|
/// give error message is spellchecker dies
|
||||||
|
bool checkAlive();
|
||||||
|
/// show count of checked words at normal exit
|
||||||
|
void showSummary();
|
||||||
|
|
||||||
|
/// set to true when spellchecking is finished
|
||||||
|
bool exitEarly_;
|
||||||
|
/// current word being checked and lang code
|
||||||
|
WordLangTuple word_;
|
||||||
|
/// values for progress
|
||||||
|
int oldval_;
|
||||||
|
int newvalue_;
|
||||||
|
/// word count
|
||||||
|
int count_;
|
||||||
|
/// The actual spellchecker object
|
||||||
|
SpellBase * speller_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace frontend
|
} // namespace frontend
|
||||||
|
Loading…
Reference in New Issue
Block a user