#include <sys/select.h>
#endif
+#include <algorithm>
+
#include "LString.h"
#include "sp_form.h"
#include "spellchecker.h"
#include "debug.h"
#include "support/lstrings.h"
-extern LyXRC *lyxrc;
-extern BufferView *current_view;
+using std::reverse;
+using std::endl;
// Spellchecker status
enum {
ISP_IGNORE
};
-static bool RunSpellChecker(string const &);
+static bool RunSpellChecker(BufferView * bv);
-static FILE *in, *out; /* streams to communicate with ispell */
+static FILE * in, * out; /* streams to communicate with ispell */
pid_t isp_pid = -1; // pid for the `ispell' process. Also used (RO) in
// lyx_cb.C
int flag;
int count;
string str;
- char **misses;
+ char ** misses;
isp_result() {
flag = ISP_UNKNOWN;
count = 0;
misses = static_cast<char**>(0);
}
~isp_result() {
- if (misses) delete[] misses;
+ delete[] misses;
}
};
void SpellOptionsUpdate()
{
// Alternate language
- if (lyxrc->isp_alt_lang.empty()) {
- lyxrc->isp_use_alt_lang = false;
+ if (lyxrc.isp_alt_lang.empty()) {
+ lyxrc.isp_use_alt_lang = false;
} else {
fl_set_input(fd_form_spell_options->altlang_input,
- lyxrc->isp_alt_lang.c_str());
+ lyxrc.isp_alt_lang.c_str());
}
- if (lyxrc->isp_use_alt_lang) {
+ if (lyxrc.isp_use_alt_lang) {
fl_set_button(fd_form_spell_options->buflang, 0);
fl_set_button(fd_form_spell_options->altlang, 1);
} else {
}
// Personal dictionary
- if (lyxrc->isp_pers_dict.empty()) {
- lyxrc->isp_use_pers_dict = false;
+ if (lyxrc.isp_pers_dict.empty()) {
+ lyxrc.isp_use_pers_dict = false;
} else {
fl_set_input(fd_form_spell_options->perdict_input,
- lyxrc->isp_pers_dict.c_str());
+ lyxrc.isp_pers_dict.c_str());
}
fl_set_button(fd_form_spell_options->perdict,
- lyxrc->isp_use_pers_dict ? 1:0);
+ lyxrc.isp_use_pers_dict ? 1:0);
// Escape chars
- if (lyxrc->isp_esc_chars.empty()) {
- lyxrc->isp_use_esc_chars = false;
+ if (lyxrc.isp_esc_chars.empty()) {
+ lyxrc.isp_use_esc_chars = false;
} else {
fl_set_input(fd_form_spell_options->esc_chars_input,
- lyxrc->isp_esc_chars.c_str());
+ lyxrc.isp_esc_chars.c_str());
}
fl_set_button(fd_form_spell_options->esc_chars,
- lyxrc->isp_use_esc_chars ? 1:0);
+ lyxrc.isp_use_esc_chars ? 1:0);
// Options
fl_set_button(fd_form_spell_options->compounds,
- lyxrc->isp_accept_compound ? 1 : 0);
+ lyxrc.isp_accept_compound ? 1 : 0);
fl_set_button(fd_form_spell_options->inpenc,
- lyxrc->isp_use_input_encoding ? 1 : 0);
+ lyxrc.isp_use_input_encoding ? 1 : 0);
}
// Update spellchecker options
void SpellOptionsApplyCB(FL_OBJECT *, long)
{
// Build new status from form data
- lyxrc->isp_use_alt_lang =
+ lyxrc.isp_use_alt_lang =
fl_get_button(fd_form_spell_options->altlang);
- lyxrc->isp_use_pers_dict =
+ lyxrc.isp_use_pers_dict =
fl_get_button(fd_form_spell_options->perdict);
- lyxrc->isp_accept_compound =
+ lyxrc.isp_accept_compound =
fl_get_button(fd_form_spell_options->compounds);
- lyxrc->isp_use_esc_chars =
+ lyxrc.isp_use_esc_chars =
fl_get_button(fd_form_spell_options->esc_chars);
- lyxrc->isp_use_input_encoding =
+ lyxrc.isp_use_input_encoding =
fl_get_button(fd_form_spell_options->inpenc);
// Update strings with data from input fields
- lyxrc->isp_alt_lang =
+ lyxrc.isp_alt_lang =
fl_get_input(fd_form_spell_options->altlang_input);
- lyxrc->isp_pers_dict =
+ lyxrc.isp_pers_dict =
fl_get_input(fd_form_spell_options->perdict_input);
- lyxrc->isp_esc_chars =
+ lyxrc.isp_esc_chars =
fl_get_input(fd_form_spell_options->esc_chars_input);
// Update form
// Could also use a clean up. (Asger Alstrup)
static
-void create_ispell_pipe(string const & lang)
+void create_ispell_pipe(BufferParams const & params, string const & lang)
{
static char o_buf[BUFSIZ]; // jc: it could be smaller
int pipein[2], pipeout[2];
close(pipeout[1]);
argc = 0;
- char * tmp = new char[lyxrc->isp_command.length() + 1];
- lyxrc->isp_command.copy(tmp, lyxrc->isp_command.length());
- tmp[lyxrc->isp_command.length()] = '\0';
+ char * tmp = new char[lyxrc.isp_command.length() + 1];
+ lyxrc.isp_command.copy(tmp, lyxrc.isp_command.length());
+ tmp[lyxrc.isp_command.length()] = '\0';
argv[argc++] = tmp;
tmp = new char[3];
string("-a").copy(tmp, 2); tmp[2] = '\0'; // pipe mode
argv[argc++] = tmp;
}
- if (lyxrc->isp_accept_compound) {
+ if (lyxrc.isp_accept_compound) {
// Consider run-together words as legal compounds
tmp = new char[3];
string("-C").copy(tmp, 2); tmp[2] = '\0';
string("-B").copy(tmp, 2); tmp[2] = '\0';
argv[argc++] = tmp;
}
- if (lyxrc->isp_use_esc_chars) {
+ if (lyxrc.isp_use_esc_chars) {
// Specify additional characters that
// can be part of a word
tmp = new char[3];
string("-w").copy(tmp, 2); tmp[2] = '\0';
argv[argc++] = tmp;
// Put the escape chars in ""s
- string tms = "\"" + lyxrc->isp_esc_chars + "\"";
+ string tms = "\"" + lyxrc.isp_esc_chars + "\"";
tmp = new char[tms.length() + 1];
tms.copy(tmp, tms.length()); tmp[tms.length()] = '\0';
argv[argc++] = tmp;
}
- if (lyxrc->isp_use_pers_dict) {
+ if (lyxrc.isp_use_pers_dict) {
// Specify an alternate personal dictionary
tmp = new char[3];
string("-p").copy(tmp, 2);
tmp[2]= '\0';
argv[argc++] = tmp;
- tmp = new char[lyxrc->isp_pers_dict.length() + 1];
- lyxrc->isp_pers_dict.copy(tmp, lyxrc->isp_pers_dict.length());
- tmp[lyxrc->isp_pers_dict.length()] = '\0';
+ tmp = new char[lyxrc.isp_pers_dict.length() + 1];
+ lyxrc.isp_pers_dict.copy(tmp, lyxrc.isp_pers_dict.length());
+ tmp[lyxrc.isp_pers_dict.length()] = '\0';
argv[argc++] = tmp;
}
- if (lyxrc->isp_use_input_encoding &&
- current_view->buffer()->params.inputenc != "default") {
+ if (lyxrc.isp_use_input_encoding &&
+ params.inputenc != "default") {
tmp = new char[3];
string("-T").copy(tmp, 2); tmp[2] = '\0';
argv[argc++] = tmp; // Input encoding
- tmp = new char[current_view->buffer()->params.inputenc.length() + 1];
- current_view->buffer()->params.inputenc.copy(tmp, current_view->buffer()->params.inputenc.length());
- tmp[current_view->buffer()->params.inputenc.length()] = '\0';
+ tmp = new char[params.inputenc.length() + 1];
+ params.inputenc.copy(tmp, params.inputenc.length());
+ tmp[params.inputenc.length()] = '\0';
argv[argc++] = tmp;
}
argv[argc++] = 0;
- execvp("ispell", const_cast<char * const *>(argv));
+ execvp(argv[0], const_cast<char * const *>(argv));
// free the memory used by string::copy in the
// setup of argv
- for (int i= 0; i < argc -1; i++)
+ for (int i= 0; i < argc -1; ++i)
delete[] argv[i];
lyxerr << "LyX: Failed to start ispell!" << endl;
if (count) result->misses = new char*[count];
p = strpbrk(nb, ":");
p += 2;
- for (i = 0; i<count; i++) {
+ for (i = 0; i < count; ++i) {
result->misses[i] = p;
p = strpbrk(p, ",\n");
*p = 0;
- p+= 2;
+ p += 2;
}
break;
}
}
-static
-inline void ispell_terminate()
+static inline
+void ispell_terminate()
{
// Note: If you decide to optimize this out when it is not
// needed please note that when Aspell is used this command
}
-static
-inline void ispell_terse_mode()
+static inline
+void ispell_terse_mode()
{
fputs("!\n", out); // Set terse mode (silently accept correct words)
}
-static
-inline void ispell_insert_word(char const *word)
+static inline
+void ispell_insert_word(char const *word)
{
fputc('*', out); // Insert word in personal dictionary
fputs(word, out);
}
-static
-inline void ispell_accept_word(char const *word)
+static inline
+void ispell_accept_word(char const *word)
{
fputc('@', out); // Accept in this session
fputs(word, out);
fputc('\n', out);
}
-static
-inline void ispell_store_replacement(char const *mis, string const & cor) {
+static inline
+void ispell_store_replacement(char const *mis, string const & cor) {
if(actual_spell_checker == ASC_ASPELL) {
fputs("$$ra ", out);
fputs(mis, out);
}
-void ShowSpellChecker()
+void ShowSpellChecker(BufferView * bv)
{
- FL_OBJECT *obj;
+ FL_OBJECT * obj;
int ret;
// Exit if we don't have a document open
- if (!current_view->getScreen())
+ if (!bv->available())
return;
if (fd_form_spell_check == 0) {
fl_set_object_lcol(fd_form_spell_check->input, FL_BLACK);
fl_set_object_lcol(fd_form_spell_check->browser, FL_BLACK);
// activate replace only if the file is not read-only
- if (!current_view->buffer()->isReadonly()) {
+ if (!bv->buffer()->isReadonly()) {
fl_activate_object(fd_form_spell_check->replace);
fl_set_object_lcol(fd_form_spell_check->replace, FL_BLACK);
}
fl_set_object_lcol(fd_form_spell_check->options, FL_INACTIVE);
fl_set_object_lcol(fd_form_spell_check->start, FL_INACTIVE);
- ret = RunSpellChecker(current_view->buffer()->GetLanguage());
+ ret = RunSpellChecker(bv);
// deactivate insert, accept, replace, and stop
fl_deactivate_object(fd_form_spell_check->insert);
if (obj == fd_form_spell_check->done) break;
}
fl_hide_form(fd_form_spell_check->form_spell_check);
- current_view->endOfSpellCheck();
+ bv->endOfSpellCheck();
return;
}
// Perform an ispell session
static
-bool RunSpellChecker(string const & lang)
+bool RunSpellChecker(BufferView * bv)
{
- isp_result *result;
- char *word;
- int i, oldval, clickline, newvalue;
- float newval;
- FL_OBJECT *obj;
- unsigned int word_count = 0;
+ isp_result * result;
+ int i, newvalue;
+ FL_OBJECT * obj;
- string tmp = (lyxrc->isp_use_alt_lang) ? lyxrc->isp_alt_lang:lang;
+ string tmp = (lyxrc.isp_use_alt_lang) ? lyxrc.isp_alt_lang : bv->buffer()->GetLanguage();
+ bool rtl = tmp == "hebrew" || tmp == "arabic";
- oldval = 0; /* used for updating slider only when needed */
- newval = 0.0;
+ int oldval = 0; /* used for updating slider only when needed */
+ float newval = 0.0;
/* create ispell process */
- create_ispell_pipe(tmp);
+ create_ispell_pipe(bv->buffer()->params, tmp);
if (isp_pid == -1) {
fl_show_message(
"Check /usr/lib/ispell or set another\n"
"dictionary in the Spellchecker Options menu."), "", "");
fclose(out);
- return true;
+ return false;
}
// Put ispell in terse mode to improve speed
ispell_terse_mode();
+ unsigned int word_count = 0;
while (true) {
- word = current_view->nextWord(newval);
+ char * word = bv->nextWord(newval);
if (word == 0) break;
- word_count++;
+ ++word_count;
// Update slider if and only if value has changed
newvalue = int(100.0*newval);
if(newvalue!= oldval) {
oldval = newvalue;
fl_set_slider_value(fd_form_spell_check->slider, oldval);
+ }
+
+ if (word_count%1000 == 0) {
+ obj = fl_check_forms();
+ if (obj == fd_form_spell_check->stop) {
+ delete[] word;
+ ispell_terminate();
+ return true;
+ }
+ if (obj == fd_form_spell_check->done) {
+ delete[] word;
+ ispell_terminate();
+ return false;
+ }
}
result = ispell_check_word(word);
if (isp_pid == -1) {
+ delete result;
delete[] word;
break;
}
- obj = fl_check_forms();
- if (obj == fd_form_spell_check->stop) {
- delete result;
- delete[] word;
- ispell_terminate();
- return true;
- }
- if (obj == fd_form_spell_check->done) {
- delete result;
- delete[] word;
- ispell_terminate();
- return false;
- }
-
switch (result->flag) {
case ISP_UNKNOWN:
case ISP_MISSED:
- current_view->selectLastWord();
- fl_set_object_label(fd_form_spell_check->text, word);
+ {
+ bv->selectLastWord();
+ if (rtl) {
+ string tmp = word;
+ reverse(tmp.begin(),tmp.end());
+ fl_set_object_label(fd_form_spell_check->text, tmp.c_str());
+ } else
+ fl_set_object_label(fd_form_spell_check->text, word);
fl_set_input(fd_form_spell_check->input, word);
fl_clear_browser(fd_form_spell_check->browser);
- for (i= 0; i<result->count; i++) {
- fl_add_browser_line(fd_form_spell_check->browser, result->misses[i]);
+ for (i = 0; i < result->count; ++i) {
+ if (rtl) {
+ string tmp = result->misses[i];
+ reverse(tmp.begin(),tmp.end());
+ fl_add_browser_line(fd_form_spell_check->browser, tmp.c_str());
+ } else
+ fl_add_browser_line(fd_form_spell_check->browser, result->misses[i]);
}
- clickline = -1;
+ int clickline = -1;
while (true) {
obj = fl_do_forms();
if (obj == fd_form_spell_check->insert) {
if (obj == fd_form_spell_check->replace ||
obj == fd_form_spell_check->input) {
ispell_store_replacement(word, fl_get_input(fd_form_spell_check->input));
- current_view->replaceWord(fl_get_input(fd_form_spell_check->input));
+ bv->replaceWord(fl_get_input(fd_form_spell_check->input));
break;
}
if (obj == fd_form_spell_check->browser) {
if (clickline ==
fl_get_browser(fd_form_spell_check->browser)) {
ispell_store_replacement(word, fl_get_input(fd_form_spell_check->input));
- current_view->replaceWord(fl_get_input(fd_form_spell_check->input));
+ bv->replaceWord(fl_get_input(fd_form_spell_check->input));
break;
}
clickline = fl_get_browser(fd_form_spell_check->browser);
- fl_set_input(fd_form_spell_check->input,
- fl_get_browser_line(fd_form_spell_check->browser,
- fl_get_browser(fd_form_spell_check->browser)));
-
+ /// Why not use
+ /// fl_set_input(fd_form_spell_check->input, result->misses[clickline-1]); ?
+ if (rtl) {
+ string tmp = fl_get_browser_line(fd_form_spell_check->browser,
+ clickline);
+ reverse(tmp.begin(),tmp.end());
+ fl_set_input(fd_form_spell_check->input, tmp.c_str());
+ } else
+ fl_set_input(fd_form_spell_check->input,
+ fl_get_browser_line(fd_form_spell_check->browser,
+ clickline));
}
if (obj == fd_form_spell_check->stop) {
delete result;
return false;
}
}
+ }
default:
delete result;
delete[] word;
if(isp_pid!= -1) {
ispell_terminate();
- string word_msg;
- word_msg += tostr(word_count);
+ string word_msg(tostr(word_count));
if (word_count != 1) {
word_msg += _(" words checked.");
} else {
}
-//void sigchldhandler(int sig)
-void sigchldhandler(pid_t pid, int *status)
+void sigchldhandler(pid_t pid, int * status)
{
- //int status ;
-
- if (isp_pid>0)
- //if (waitpid(isp_pid, &status, WNOHANG) == isp_pid) {
+ if (isp_pid > 0)
if (pid == isp_pid) {
isp_pid= -1;
fcntl(isp_fd, F_SETFL, O_NONBLOCK); /* set the file descriptor
to nonblocking so we can
continue */
}
- //sigchldchecker(sig);
sigchldchecker(pid, status);
}