seg fault in word_check()
[vspell.git] / ui / gtk / main.cpp
blob2cc56aa8755baeb11fb796615d12b0c9e74bdfb7
1 #include <gtk/gtk.h> // -*- tab-width:2 coding: viscii mode: c++ -*-
2 #include <stdlib.h>
3 #include <stdio.h>
4 #include <string.h>
5 #include <sstream>
6 #include "config.h"
7 #include <spell.h>
8 #include <vspell.h>
9 #include <syllable.h>
11 using namespace std;
13 class MyText : public Text
15 public:
16 MyText(VSpell* vs):Text(vs) {}
18 bool word_check();
20 protected:
21 virtual bool ui_syllable_check();
22 virtual bool ui_word_check();
24 void show_wrong_syllables(unsigned p);
25 void show_words();
26 void show_wrong_words(unsigned p);
28 void iter_at(GtkTextIter &iter,int pos);
29 string word_to_utf8(unsigned seg_id);
32 class MyTextFactory : public TextFactory
34 public:
35 Text* create(VSpell *vs) const {
36 return new MyText(vs);
40 static GtkTextTagTable *tagtable_main;
41 static GtkTextBuffer *textbuffer_main;
42 static GtkWidget *textview_main;
43 static GtkWidget *log_main;
44 static GtkWidget *spell_entry;
45 static GtkWidget *ignore_button,*ignore_all_button,*spell_button,*open_button;
46 static GtkListStore *list_store;
47 static MyTextFactory myfactory;
48 static VSpell vspell(myfactory);
49 static bool word_boundaries;
51 static void text_reset(GtkTextBuffer *textbuffer_main)
53 GtkTextIter start,end;
54 gtk_text_buffer_get_start_iter(textbuffer_main,&start);
55 gtk_text_buffer_get_end_iter(textbuffer_main,&end);
56 gtk_text_buffer_remove_all_tags (textbuffer_main, &start,&end);
59 void MyText::iter_at(GtkTextIter &iter,int pos)
61 gtk_text_buffer_get_iter_at_offset(textbuffer_main,&iter,offset+pos);
64 void MyText::show_wrong_syllables(unsigned p)
66 Suggestions &sugg = suggestions;
67 int cc,ii,nn,i,n = sugg.size();
68 gtk_text_buffer_set_text (textbuffer_main,
69 vspell->get_utf8_text().c_str(),
70 strlen(vspell->get_utf8_text().c_str()));
71 GtkTextIter start,end;
72 iter_at(start,0);
73 iter_at(end,length);
74 gtk_text_buffer_apply_tag_by_name(textbuffer_main,
75 "bg-syllable", &start, &end);
76 for (i = 0;i < n;i ++) {
77 int id = sugg[i].id;
78 int from = st[id].start;
79 int len = strlen(get_sarch()[st[id].id]);
80 printf("Syllable Mispelled: %d (%s) at %d\n",
81 id,get_sarch()[st[id].id],from);
82 iter_at(start,from);
83 iter_at(end,from+len);
84 gtk_text_buffer_apply_tag_by_name (textbuffer_main,
85 (i == p ? "mispelled" : "mispelled2"),
86 &start,&end);
90 void MyText::show_words()
92 int n,cc,i,nn;
93 GtkTextIter start,end;
95 n = seg.size();
96 cc = 0;
97 for (i = 0;i < n;i ++) {
98 nn = seg[i].node.node->get_syllable_count();
99 if (nn == 1 && !word_boundaries) {
100 cc += nn;
101 continue;
103 int from = st[cc].start;
104 int to = st[cc+nn-1].start+strlen(get_sarch()[st[cc+nn-1].id]);
105 printf("From %d to %d(%d)\n",from,to,n);
106 iter_at(start,from);
107 iter_at(end,to);
108 gtk_text_buffer_apply_tag_by_name (textbuffer_main, "word",
109 &start,&end);
110 cc += nn;
114 void MyText::show_wrong_words(unsigned p)
116 int n,cc,nn,i,ii;
117 GtkTextIter start,end;
119 Suggestions &sugg = suggestions;
120 gtk_text_buffer_set_text (textbuffer_main,
121 vspell->get_utf8_text().c_str(),
122 strlen(vspell->get_utf8_text().c_str()));
123 iter_at(start,0);
124 iter_at(end,length);
125 gtk_text_buffer_apply_tag_by_name(textbuffer_main,
126 "bg-word", &start, &end);
128 show_words();
129 n = sugg.size();
130 for (i = 0;i < n;i ++) {
131 int id = sugg[i].id;
132 for (cc = ii = 0;ii < id;ii ++)
133 cc += seg[ii].node.node->get_syllable_count();
135 nn = seg[id].node.node->get_syllable_count();
137 int from = st[cc].start;
138 int to = st[cc+nn-1].start+strlen(get_sarch()[st[cc+nn-1].id]);
139 printf("Mispelled at %d\n",id);
140 iter_at(start,from);
141 iter_at(end,to);
142 gtk_text_buffer_apply_tag_by_name (textbuffer_main,
143 (i == p ? "mispelled" : "mispelled2"),
144 &start,&end);
148 static void button_reset_callback (GtkWidget *button, gpointer data)
150 text_reset(textbuffer_main);
153 static bool is_checking = true;
154 static bool ignore = false;
155 static bool ignore_all = false;
156 static bool processed = false;
158 static void set_state(bool spellcheck)
160 GtkTextIter start,end;
162 if (spellcheck == is_checking)
163 return;
165 is_checking = spellcheck;
166 if (is_checking || !word_boundaries) {
167 gtk_text_buffer_get_start_iter(textbuffer_main,&start);
168 gtk_text_buffer_get_end_iter(textbuffer_main,&end);
169 gtk_text_buffer_remove_all_tags (textbuffer_main, &start,&end);
172 gtk_text_view_set_editable(GTK_TEXT_VIEW(textview_main),!is_checking);
173 gtk_widget_set_sensitive(GTK_WIDGET(open_button),!is_checking);
174 gtk_widget_set_sensitive(GTK_WIDGET(spell_button),!is_checking);
175 gtk_widget_set_sensitive(GTK_WIDGET(ignore_button),is_checking);
176 gtk_widget_set_sensitive(GTK_WIDGET(ignore_all_button),is_checking);
177 ignore = true;
180 static void button_spell_callback (GtkWidget *button, gpointer data)
182 GtkTextIter start,end;
184 set_state(true);
186 gtk_text_buffer_get_start_iter(textbuffer_main,&start);
187 gtk_text_buffer_get_end_iter(textbuffer_main,&end);
189 gchar *buffer = gtk_text_buffer_get_text(textbuffer_main,&start,&end,FALSE);
190 //int len = g_utf8_strlen(buffer,-1);
192 vspell.check(buffer);
193 set_state(false);
194 if (!word_boundaries)
195 gtk_text_buffer_set_text (textbuffer_main, vspell.get_utf8_text().c_str(),strlen(vspell.get_utf8_text().c_str()));
199 static void button_ignore_all_callback(GtkWidget *button,gpointer data)
201 //set_state(false);
202 ignore_all = true;
205 static void button_spell_accept_callback (GtkWidget *button, gpointer data)
207 processed = true;
210 static void spell_entry_activate_callback(GtkEntry *entry, gpointer data)
212 button_spell_accept_callback(NULL,NULL);
215 static void button_ignore_callback (GtkWidget *button, gpointer data)
217 ignore = true;
220 static void button_exit_callback (GtkWidget *button, gpointer data)
222 exit(0);
225 static void window_destroy_callback (GtkObject *object,
226 gpointer user_data)
228 exit(0);
231 static void button_search_callback(GtkWidget *button, gpointer data);
233 static void
234 candidates_row_activated (GtkTreeView *treeview,
235 GtkTreePath *path,
236 GtkTreeViewColumn *arg2,
237 gpointer user_data)
239 GtkTreeIter iter;
240 const char *s;
241 if (!gtk_tree_model_get_iter(GTK_TREE_MODEL(list_store),&iter,path))
242 return;
243 gtk_tree_model_get(GTK_TREE_MODEL(list_store),&iter,0,&s,-1);
244 gtk_entry_set_text(GTK_ENTRY(spell_entry),s);
247 void strict_spelling_checking_cb(GtkToggleButton *b,VSpell *vspell)
249 bool state = gtk_toggle_button_get_active(b);
250 vspell->set_strict_word_checking(state);
251 //gtk_toggle_button_set_active(b,state);
254 void length_normalization_cb(GtkToggleButton *b,VSpell *vspell)
256 bool state = gtk_toggle_button_get_active(b);
257 vspell->set_normalization(state);
258 //gtk_toggle_button_set_active(b,state);
261 void penalty_modification_cb(GtkEntry *b,VSpell *vspell)
263 const char *s = gtk_entry_get_text(b);
264 float val;
265 if (sscanf(s,"%f",&val) == 1)
266 vspell->set_penalty(val);
269 void trigram_cb(GtkToggleButton *b,VSpell *vspell)
271 bool state = gtk_toggle_button_get_active(b);
272 vspell->set_trigram(state);
273 //gtk_toggle_button_set_active(b,state);
276 void word_boundaries_cb(GtkToggleButton *b,VSpell *vspell)
278 word_boundaries = gtk_toggle_button_get_active(b);
279 //gtk_toggle_button_set_active(b,state);
282 int main(int argc,char **argv)
284 gtk_init(&argc,&argv);
286 // sarch["<root>"];
288 vspell.init();
289 vspell.set_penalty(0.05);
290 vspell.set_normalization(true);
291 vspell.set_trigram(true);
292 word_boundaries = true;
294 GtkWidget *window_main = gtk_window_new(GTK_WINDOW_TOPLEVEL);
295 gtk_container_set_border_width(GTK_CONTAINER(window_main),10);
296 gtk_window_set_default_size(GTK_WINDOW(window_main),400,200);
297 g_signal_connect(window_main,"destroy",G_CALLBACK(window_destroy_callback),NULL);
299 GtkWidget *notebook = gtk_notebook_new();
300 GtkWidget *page1,*page2;
301 gtk_container_add(GTK_CONTAINER(window_main),notebook);
303 GtkWidget *vbox_main = gtk_vbox_new(FALSE,10);
304 page1 = vbox_main;
305 gtk_container_set_border_width(GTK_CONTAINER(page1),10);
306 gtk_notebook_append_page(GTK_NOTEBOOK(notebook),page1,gtk_label_new("Main"));
309 // Search box
310 GtkWidget *hbox_search = gtk_hbox_new(FALSE,10);
311 gtk_box_pack_start(GTK_BOX(vbox_main),hbox_search,FALSE,TRUE,0);
313 GtkWidget *entry_search = gtk_entry_new();
314 gtk_box_pack_start(GTK_BOX(hbox_search),entry_search,TRUE,TRUE,0);
315 GtkWidget *button_search = gtk_button_new_with_mnemonic("_Search");
316 g_signal_connect(button_search,"clicked",
317 G_CALLBACK(button_search_callback),entry_search);
318 gtk_box_pack_start(GTK_BOX(hbox_search),button_search,FALSE,TRUE,0);
320 log_main = gtk_label_new("");
321 gtk_label_set_line_wrap(GTK_LABEL(log_main),true);
322 gtk_box_pack_start(GTK_BOX(vbox_main),log_main,FALSE,FALSE,0);
325 // Text box+Spell box
326 GtkWidget *paned = gtk_hpaned_new();
327 gtk_paned_set_position(GTK_PANED(paned),300);
328 gtk_box_pack_start(GTK_BOX(vbox_main),paned,TRUE,TRUE,0);
330 // --textbox
331 GtkWidget *scrolled_window = gtk_scrolled_window_new(NULL,NULL);
332 gtk_paned_add1(GTK_PANED(paned),scrolled_window);
334 tagtable_main = gtk_text_tag_table_new();
335 textbuffer_main = gtk_text_buffer_new(tagtable_main);
336 gtk_text_buffer_create_tag (textbuffer_main, "mispelled",
337 "weight", PANGO_WEIGHT_BOLD,
338 "style", PANGO_STYLE_ITALIC,
339 "foreground", "red",
340 NULL);
341 gtk_text_buffer_create_tag (textbuffer_main, "mispelled2",
342 "weight", PANGO_WEIGHT_BOLD,
343 "style", PANGO_STYLE_ITALIC,
344 NULL);
345 gtk_text_buffer_create_tag (textbuffer_main, "word",
346 "underline", (gboolean)TRUE,
347 NULL);
348 gtk_text_buffer_create_tag (textbuffer_main, "bg-word",
349 "background", "grey",
350 NULL);
351 gtk_text_buffer_create_tag (textbuffer_main, "bg-syllable",
352 "background", "lightgrey",
353 NULL);
355 textview_main = gtk_text_view_new_with_buffer(textbuffer_main);
356 gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(textview_main),GTK_WRAP_WORD);
357 gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrolled_window),textview_main);
359 // --spellbox
360 GtkWidget *spell_vbox = gtk_vbox_new(FALSE,10);
361 gtk_paned_add2(GTK_PANED(paned),spell_vbox);
363 GtkWidget *spell_entry_hbox = gtk_hbox_new(FALSE,5);
364 gtk_box_pack_start(GTK_BOX(spell_vbox),spell_entry_hbox,FALSE,FALSE,0);
366 spell_entry = gtk_entry_new();
367 g_signal_connect(G_OBJECT(spell_entry),"activate",G_CALLBACK(spell_entry_activate_callback),NULL);
368 gtk_box_pack_start(GTK_BOX(spell_entry_hbox),spell_entry,TRUE,TRUE,0);
370 GtkWidget *spell_entry_button = gtk_button_new();
371 GtkWidget *spell_entry_button_image = gtk_image_new_from_stock(GTK_STOCK_OK,GTK_ICON_SIZE_BUTTON);
372 g_signal_connect(spell_entry_button,"clicked",G_CALLBACK(button_spell_accept_callback),NULL);
373 gtk_container_add(GTK_CONTAINER(spell_entry_button),spell_entry_button_image);
374 gtk_box_pack_start(GTK_BOX(spell_entry_hbox),spell_entry_button,FALSE,FALSE,0);
376 GtkWidget *view = gtk_scrolled_window_new(NULL,NULL);
377 gtk_box_pack_start(GTK_BOX(spell_vbox),view,TRUE,TRUE,0);
379 GtkWidget *w = gtk_tree_view_new();
380 gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(view),w);
381 list_store = gtk_list_store_new(1,G_TYPE_STRING);
382 gtk_tree_view_set_model(GTK_TREE_VIEW(w),GTK_TREE_MODEL(list_store));
383 gtk_tree_view_append_column(GTK_TREE_VIEW(w),
384 gtk_tree_view_column_new_with_attributes("Candidates",
385 gtk_cell_renderer_text_new(),
386 "text",
388 NULL));
389 g_signal_connect(G_OBJECT(w),"row-activated",
390 G_CALLBACK(candidates_row_activated),
391 NULL);
393 // Commands
394 GtkWidget *hbox_command = gtk_hbox_new(TRUE,10);
395 gtk_box_pack_start(GTK_BOX(vbox_main),hbox_command,FALSE,TRUE,0);
397 open_button = gtk_button_new_with_mnemonic("_Open");
398 //g_signal_connect(button_spell,"clicked",G_CALLBACK(button_spell_callback),NULL);
399 gtk_box_pack_start(GTK_BOX(hbox_command),open_button,FALSE,TRUE,0);
400 spell_button = gtk_button_new_with_mnemonic("_Check");
401 g_signal_connect(spell_button,"clicked",G_CALLBACK(button_spell_callback),NULL);
402 gtk_box_pack_start(GTK_BOX(hbox_command),spell_button,FALSE,TRUE,0);
403 //GtkWidget *button_reset = gtk_button_new_with_mnemonic("_Reset");
404 //g_signal_connect(button_reset,"clicked",G_CALLBACK(button_reset_callback),NULL);
405 //gtk_box_pack_start(GTK_BOX(hbox_command),button_reset,FALSE,TRUE,0);
406 ignore_button = gtk_button_new_with_mnemonic("_Ignore");
407 g_signal_connect(ignore_button,"clicked",G_CALLBACK(button_ignore_callback),NULL);
408 gtk_box_pack_start(GTK_BOX(hbox_command),ignore_button,FALSE,TRUE,0);
409 ignore_all_button = gtk_button_new_with_mnemonic("Ignore _All");
410 g_signal_connect(ignore_all_button,"clicked",G_CALLBACK(button_ignore_all_callback),NULL);
411 gtk_box_pack_start(GTK_BOX(hbox_command),ignore_all_button,FALSE,TRUE,0);
412 GtkWidget *button_exit = gtk_button_new_with_mnemonic("_Exit");
413 g_signal_connect(button_exit,"clicked",G_CALLBACK(button_exit_callback),NULL);
414 gtk_box_pack_start(GTK_BOX(hbox_command),button_exit,FALSE,TRUE,0);
416 vbox_main = gtk_vbox_new(FALSE,10);
417 page2 = vbox_main;
418 gtk_container_set_border_width(GTK_CONTAINER(page2),10);
419 gtk_notebook_append_page(GTK_NOTEBOOK(notebook),page2,gtk_label_new("Settings"));
420 w = gtk_check_button_new_with_label("Strict spelling checking");
421 gtk_box_pack_start(GTK_BOX(vbox_main),w,FALSE,FALSE,0);
422 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w),vspell.get_strict_word_checking());
423 g_signal_connect(G_OBJECT(w),"toggled",G_CALLBACK(strict_spelling_checking_cb),&vspell);
425 w = gtk_check_button_new_with_label("Length normalization");
426 gtk_box_pack_start(GTK_BOX(vbox_main),w,FALSE,FALSE,0);
427 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w),vspell.get_normalization());
428 g_signal_connect(G_OBJECT(w),"toggled",G_CALLBACK(length_normalization_cb),&vspell);
430 w = gtk_check_button_new_with_label("Trigram");
431 gtk_box_pack_start(GTK_BOX(vbox_main),w,FALSE,FALSE,0);
432 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w),vspell.get_trigram());
433 g_signal_connect(G_OBJECT(w),"toggled",G_CALLBACK(trigram_cb),&vspell);
435 w = gtk_check_button_new_with_label("Show word boundaries");
436 gtk_box_pack_start(GTK_BOX(vbox_main),w,FALSE,FALSE,0);
437 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w),word_boundaries);
438 g_signal_connect(G_OBJECT(w),"toggled",G_CALLBACK(word_boundaries_cb),&vspell);
440 GtkWidget *hbox = gtk_hbox_new(FALSE,10);
441 gtk_box_pack_start(GTK_BOX(vbox_main),hbox,FALSE,FALSE,0);
442 gtk_box_pack_start(GTK_BOX(hbox),gtk_label_new("Penalty modification"),FALSE,FALSE,0);
443 w = gtk_entry_new();
444 gtk_box_pack_start(GTK_BOX(hbox),w,FALSE,FALSE,0);
445 char buff[100];
446 sprintf(buff,"%f",vspell.get_penalty());
447 gtk_entry_set_text(GTK_ENTRY(w),buff);
448 g_signal_connect(G_OBJECT(w),"changed",G_CALLBACK(penalty_modification_cb),&vspell);
450 set_state(false);
452 gtk_widget_show_all(window_main);
453 gtk_main();
456 void button_search_callback(GtkWidget *button, gpointer data)
458 GtkWidget *entry_search = GTK_WIDGET(data);
459 const char *text = gtk_entry_get_text(GTK_ENTRY(data));
461 string is(viet_to_viscii(text));
462 int p = 0;
463 string s;
464 vector<strid> ids;
465 while (p < is.size()) {
466 int pp = is.find(' ',p);
467 if (pp == string::npos)
468 pp = is.size();
469 s = is.substr(p,pp-p);
470 p = pp+1;
471 strid id = get_sarch()[s];
472 if (!get_sarch().in_dict(id)) {
473 char *str = g_strdup_printf("%s not found",viet_to_utf8(s.c_str()));
474 gtk_label_set_text(GTK_LABEL(log_main),str);
475 g_free(str);
476 return;
478 ids.push_back(id);
482 WordNodePtr ptr;
483 ptr = get_root()->follow_syllables(ids);
484 if (ptr) {
485 char *str = g_strdup_printf("Word %s found with prob %.02f.",text,ptr->get_prob());
486 gtk_label_set_text(GTK_LABEL(log_main),str);
487 g_free(str);
488 } else
489 gtk_label_set_text(GTK_LABEL(log_main),"Word not found.");
493 void candidates_reset()
495 gtk_list_store_clear(list_store);
498 void candidates_add(const gchar *s)
500 GtkTreeIter iter;
501 gtk_list_store_append(list_store,&iter);
502 gtk_list_store_set(list_store,&iter,
503 0,s,
504 -1);
507 bool MyText::ui_syllable_check()
509 unsigned i,n = suggestions.size();
510 for (i = 0;i < n;i ++) {
511 show_wrong_syllables(i);
512 // query
513 int from,len;
514 from = st[suggestions[i].id].start;
515 len = strlen(get_sarch()[st[suggestions[i].id].id]);
516 string s = substr(from,len);
517 gtk_entry_set_text(GTK_ENTRY(spell_entry),s.c_str());
518 vector<string> candidates;
519 Candidates c;
520 candidates_reset();
521 get_syllable_candidates(get_sarch()[st[suggestions[i].id].id],c);
522 c.get_list(candidates);
523 vector<string>::iterator iter;
524 for (iter = candidates.begin();iter != candidates.end();++ iter)
525 candidates_add(viet_to_utf8(iter->c_str()));
526 processed = ignore_all = ignore = false;
527 while (!gtk_main_iteration() && !ignore && !ignore_all && !processed);
529 if (ignore)
530 continue;
532 if (ignore_all)
533 return true; // force to exit
535 if (processed) {
536 cerr << "Input: The right one is:" << endl;
538 const gchar *s = gtk_entry_get_text(GTK_ENTRY(spell_entry));
540 if (*s == 0)
541 continue; // i don't accept an empty string
543 replace(st[suggestions[i].id].start, // from
544 strlen(get_sarch()[st[suggestions[i].id].get_id()]), // size
545 s); // text
546 vspell->add(get_sarch()[viet_to_viscii_force(s)]);
548 return false;
550 return true; // some things went wrong
552 return !is_checking;
555 string MyText::word_to_utf8(unsigned seg_id)
557 vector<strid> sylls;
558 string s;
559 seg[seg_id].node->get_syllables(sylls);
560 int i,n = sylls.size();
561 for (i = 0;i < n;i ++) {
562 if (i)
563 s += " ";
564 Syllable syll;
565 syll.parse(get_sarch()[sylls[i]]);
566 s += viet_to_utf8(syll.to_str().c_str());
568 return s;
571 bool MyText::ui_word_check()
573 unsigned i,n = suggestions.size();
574 int pos,pos2,count;
576 for (i = 0;i < n;i ++) {
577 show_wrong_words(i);
578 // query
579 count = seg[suggestions[i].id].node->get_syllable_count();
580 pos = (*seg.we)[seg[suggestions[i].id].id].pos;
581 pos2 = pos+count-1;
582 int from,len;
583 from = st[pos].start;
584 len = st[pos2].start+strlen(get_sarch()[st[pos2].id])-from;
585 string s = substr(from,len);
586 gtk_entry_set_text(GTK_ENTRY(spell_entry),s.c_str());
587 candidates_reset();
588 candidates_add(word_to_utf8(suggestions[i].id).c_str());
589 processed = ignore_all = ignore = false;
590 while (!gtk_main_iteration() && !ignore && !ignore_all && !processed);
592 if (ignore)
593 continue;
595 if (ignore_all)
596 return true; // force to exit
598 if (processed) {
599 string s = gtk_entry_get_text(GTK_ENTRY(spell_entry));
601 if (s.empty())
602 continue;
604 count = seg[suggestions[i].id].node->get_syllable_count();
605 pos = (*seg.we)[seg[suggestions[i].id].id].pos;
606 pos2 = pos+count-1;
608 string::size_type p;
609 vector<unsigned> separators;
610 while ((p = s.find('|')) != string::npos) {
611 separators.push_back(st[pos].start+g_utf8_strlen(s.substr(0,p).c_str(),-1)+offset);
612 s.erase(p,1);
615 replace(st[pos].start, // from
616 st[pos2].start+strlen(get_sarch()[st[pos2].get_id()])-st[pos].start, // size
617 s.c_str()); // text
619 // add separators after replacing the text, to have old separators removed
620 vspell->add_word(viet_to_viscii_force(s.c_str()));
621 vspell->add_separators(separators);
622 return false; // continue checking
624 return true; // some things went wrong
626 return !is_checking;
629 bool MyText::word_check()
631 bool ret = Text::word_check();
632 if (word_boundaries)
633 show_words();
634 return ret;