terrible bug in PenaltyDAG and Penalty2DAG.
[vspell.git] / ui / gtk / main.cpp
blob08429d288e07b16f7c42f8b9627a2682c8d40f45
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 penalty2_modification_cb(GtkEntry *b,VSpell *vspell)
271 const char *s = gtk_entry_get_text(b);
272 float val;
273 if (sscanf(s,"%f",&val) == 1)
274 vspell->set_penalty2(val);
277 void trigram_cb(GtkToggleButton *b,VSpell *vspell)
279 bool state = gtk_toggle_button_get_active(b);
280 vspell->set_trigram(state);
281 //gtk_toggle_button_set_active(b,state);
284 void word_boundaries_cb(GtkToggleButton *b,VSpell *vspell)
286 word_boundaries = gtk_toggle_button_get_active(b);
287 //gtk_toggle_button_set_active(b,state);
290 int main(int argc,char **argv)
292 gtk_init(&argc,&argv);
294 // sarch["<root>"];
296 vspell.init();
297 vspell.set_penalty(0.9);
298 vspell.set_penalty2(0.1);
299 vspell.set_normalization(true);
300 vspell.set_trigram(true);
301 word_boundaries = true;
303 GtkWidget *window_main = gtk_window_new(GTK_WINDOW_TOPLEVEL);
304 gtk_container_set_border_width(GTK_CONTAINER(window_main),10);
305 gtk_window_set_default_size(GTK_WINDOW(window_main),400,200);
306 g_signal_connect(window_main,"destroy",G_CALLBACK(window_destroy_callback),NULL);
308 GtkWidget *notebook = gtk_notebook_new();
309 GtkWidget *page1,*page2;
310 gtk_container_add(GTK_CONTAINER(window_main),notebook);
312 GtkWidget *vbox_main = gtk_vbox_new(FALSE,10);
313 page1 = vbox_main;
314 gtk_container_set_border_width(GTK_CONTAINER(page1),10);
315 gtk_notebook_append_page(GTK_NOTEBOOK(notebook),page1,gtk_label_new("Main"));
318 // Search box
319 GtkWidget *hbox_search = gtk_hbox_new(FALSE,10);
320 gtk_box_pack_start(GTK_BOX(vbox_main),hbox_search,FALSE,TRUE,0);
322 GtkWidget *entry_search = gtk_entry_new();
323 gtk_box_pack_start(GTK_BOX(hbox_search),entry_search,TRUE,TRUE,0);
324 GtkWidget *button_search = gtk_button_new_with_mnemonic("_Search");
325 g_signal_connect(button_search,"clicked",
326 G_CALLBACK(button_search_callback),entry_search);
327 gtk_box_pack_start(GTK_BOX(hbox_search),button_search,FALSE,TRUE,0);
329 log_main = gtk_label_new("");
330 gtk_label_set_line_wrap(GTK_LABEL(log_main),true);
331 gtk_box_pack_start(GTK_BOX(vbox_main),log_main,FALSE,FALSE,0);
334 // Text box+Spell box
335 GtkWidget *paned = gtk_hpaned_new();
336 gtk_paned_set_position(GTK_PANED(paned),300);
337 gtk_box_pack_start(GTK_BOX(vbox_main),paned,TRUE,TRUE,0);
339 // --textbox
340 GtkWidget *scrolled_window = gtk_scrolled_window_new(NULL,NULL);
341 gtk_paned_add1(GTK_PANED(paned),scrolled_window);
343 tagtable_main = gtk_text_tag_table_new();
344 textbuffer_main = gtk_text_buffer_new(tagtable_main);
345 gtk_text_buffer_create_tag (textbuffer_main, "mispelled",
346 "weight", PANGO_WEIGHT_BOLD,
347 "style", PANGO_STYLE_ITALIC,
348 "foreground", "red",
349 NULL);
350 gtk_text_buffer_create_tag (textbuffer_main, "mispelled2",
351 "weight", PANGO_WEIGHT_BOLD,
352 "style", PANGO_STYLE_ITALIC,
353 NULL);
354 gtk_text_buffer_create_tag (textbuffer_main, "word",
355 "underline", (gboolean)TRUE,
356 NULL);
357 gtk_text_buffer_create_tag (textbuffer_main, "bg-word",
358 "background", "grey",
359 NULL);
360 gtk_text_buffer_create_tag (textbuffer_main, "bg-syllable",
361 "background", "lightgrey",
362 NULL);
364 textview_main = gtk_text_view_new_with_buffer(textbuffer_main);
365 gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(textview_main),GTK_WRAP_WORD);
366 gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrolled_window),textview_main);
368 // --spellbox
369 GtkWidget *spell_vbox = gtk_vbox_new(FALSE,10);
370 gtk_paned_add2(GTK_PANED(paned),spell_vbox);
372 GtkWidget *spell_entry_hbox = gtk_hbox_new(FALSE,5);
373 gtk_box_pack_start(GTK_BOX(spell_vbox),spell_entry_hbox,FALSE,FALSE,0);
375 spell_entry = gtk_entry_new();
376 g_signal_connect(G_OBJECT(spell_entry),"activate",G_CALLBACK(spell_entry_activate_callback),NULL);
377 gtk_box_pack_start(GTK_BOX(spell_entry_hbox),spell_entry,TRUE,TRUE,0);
379 GtkWidget *spell_entry_button = gtk_button_new();
380 GtkWidget *spell_entry_button_image = gtk_image_new_from_stock(GTK_STOCK_OK,GTK_ICON_SIZE_BUTTON);
381 g_signal_connect(spell_entry_button,"clicked",G_CALLBACK(button_spell_accept_callback),NULL);
382 gtk_container_add(GTK_CONTAINER(spell_entry_button),spell_entry_button_image);
383 gtk_box_pack_start(GTK_BOX(spell_entry_hbox),spell_entry_button,FALSE,FALSE,0);
385 GtkWidget *view = gtk_scrolled_window_new(NULL,NULL);
386 gtk_box_pack_start(GTK_BOX(spell_vbox),view,TRUE,TRUE,0);
388 GtkWidget *w = gtk_tree_view_new();
389 gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(view),w);
390 list_store = gtk_list_store_new(1,G_TYPE_STRING);
391 gtk_tree_view_set_model(GTK_TREE_VIEW(w),GTK_TREE_MODEL(list_store));
392 gtk_tree_view_append_column(GTK_TREE_VIEW(w),
393 gtk_tree_view_column_new_with_attributes("Candidates",
394 gtk_cell_renderer_text_new(),
395 "text",
397 NULL));
398 g_signal_connect(G_OBJECT(w),"row-activated",
399 G_CALLBACK(candidates_row_activated),
400 NULL);
402 // Commands
403 GtkWidget *hbox_command = gtk_hbox_new(TRUE,10);
404 gtk_box_pack_start(GTK_BOX(vbox_main),hbox_command,FALSE,TRUE,0);
406 open_button = gtk_button_new_with_mnemonic("_Open");
407 //g_signal_connect(button_spell,"clicked",G_CALLBACK(button_spell_callback),NULL);
408 gtk_box_pack_start(GTK_BOX(hbox_command),open_button,FALSE,TRUE,0);
409 spell_button = gtk_button_new_with_mnemonic("_Check");
410 g_signal_connect(spell_button,"clicked",G_CALLBACK(button_spell_callback),NULL);
411 gtk_box_pack_start(GTK_BOX(hbox_command),spell_button,FALSE,TRUE,0);
412 //GtkWidget *button_reset = gtk_button_new_with_mnemonic("_Reset");
413 //g_signal_connect(button_reset,"clicked",G_CALLBACK(button_reset_callback),NULL);
414 //gtk_box_pack_start(GTK_BOX(hbox_command),button_reset,FALSE,TRUE,0);
415 ignore_button = gtk_button_new_with_mnemonic("_Ignore");
416 g_signal_connect(ignore_button,"clicked",G_CALLBACK(button_ignore_callback),NULL);
417 gtk_box_pack_start(GTK_BOX(hbox_command),ignore_button,FALSE,TRUE,0);
418 ignore_all_button = gtk_button_new_with_mnemonic("Ignore _All");
419 g_signal_connect(ignore_all_button,"clicked",G_CALLBACK(button_ignore_all_callback),NULL);
420 gtk_box_pack_start(GTK_BOX(hbox_command),ignore_all_button,FALSE,TRUE,0);
421 GtkWidget *button_exit = gtk_button_new_with_mnemonic("_Exit");
422 g_signal_connect(button_exit,"clicked",G_CALLBACK(button_exit_callback),NULL);
423 gtk_box_pack_start(GTK_BOX(hbox_command),button_exit,FALSE,TRUE,0);
425 vbox_main = gtk_vbox_new(FALSE,10);
426 page2 = vbox_main;
427 gtk_container_set_border_width(GTK_CONTAINER(page2),10);
428 gtk_notebook_append_page(GTK_NOTEBOOK(notebook),page2,gtk_label_new("Settings"));
429 w = gtk_check_button_new_with_label("Strict spelling checking");
430 gtk_box_pack_start(GTK_BOX(vbox_main),w,FALSE,FALSE,0);
431 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w),vspell.get_strict_word_checking());
432 g_signal_connect(G_OBJECT(w),"toggled",G_CALLBACK(strict_spelling_checking_cb),&vspell);
434 w = gtk_check_button_new_with_label("Length normalization");
435 gtk_box_pack_start(GTK_BOX(vbox_main),w,FALSE,FALSE,0);
436 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w),vspell.get_normalization());
437 g_signal_connect(G_OBJECT(w),"toggled",G_CALLBACK(length_normalization_cb),&vspell);
439 w = gtk_check_button_new_with_label("Trigram");
440 gtk_box_pack_start(GTK_BOX(vbox_main),w,FALSE,FALSE,0);
441 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w),vspell.get_trigram());
442 g_signal_connect(G_OBJECT(w),"toggled",G_CALLBACK(trigram_cb),&vspell);
444 w = gtk_check_button_new_with_label("Show word boundaries");
445 gtk_box_pack_start(GTK_BOX(vbox_main),w,FALSE,FALSE,0);
446 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w),word_boundaries);
447 g_signal_connect(G_OBJECT(w),"toggled",G_CALLBACK(word_boundaries_cb),&vspell);
449 GtkWidget *hbox = gtk_hbox_new(FALSE,10);
450 gtk_box_pack_start(GTK_BOX(vbox_main),hbox,FALSE,FALSE,0);
451 gtk_box_pack_start(GTK_BOX(hbox),gtk_label_new("Penalty"),FALSE,FALSE,0);
452 w = gtk_entry_new();
453 gtk_box_pack_start(GTK_BOX(hbox),w,FALSE,FALSE,0);
454 char buff[100];
455 sprintf(buff,"%f",vspell.get_penalty());
456 gtk_entry_set_text(GTK_ENTRY(w),buff);
457 g_signal_connect(G_OBJECT(w),"changed",G_CALLBACK(penalty_modification_cb),&vspell);
459 hbox = gtk_hbox_new(FALSE,10);
460 gtk_box_pack_start(GTK_BOX(vbox_main),hbox,FALSE,FALSE,0);
461 gtk_box_pack_start(GTK_BOX(hbox),gtk_label_new("Penalty2"),FALSE,FALSE,0);
462 w = gtk_entry_new();
463 gtk_box_pack_start(GTK_BOX(hbox),w,FALSE,FALSE,0);
464 sprintf(buff,"%f",vspell.get_penalty2());
465 gtk_entry_set_text(GTK_ENTRY(w),buff);
466 g_signal_connect(G_OBJECT(w),"changed",G_CALLBACK(penalty2_modification_cb),&vspell);
468 set_state(false);
470 gtk_widget_show_all(window_main);
471 gtk_main();
474 void button_search_callback(GtkWidget *button, gpointer data)
476 GtkWidget *entry_search = GTK_WIDGET(data);
477 const char *text = gtk_entry_get_text(GTK_ENTRY(data));
479 string is(viet_to_viscii(text));
480 int p = 0;
481 string s;
482 vector<strid> ids;
483 while (p < is.size()) {
484 int pp = is.find(' ',p);
485 if (pp == string::npos)
486 pp = is.size();
487 s = is.substr(p,pp-p);
488 p = pp+1;
489 strid id = get_sarch()[s];
490 if (!get_sarch().in_dict(id)) {
491 char *str = g_strdup_printf("%s not found",viet_to_utf8(s.c_str()));
492 gtk_label_set_text(GTK_LABEL(log_main),str);
493 g_free(str);
494 return;
496 ids.push_back(id);
500 WordNodePtr ptr;
501 ptr = get_root()->follow_syllables(ids);
502 if (ptr) {
503 char *str = g_strdup_printf("Word %s found with prob %.02f.",text,ptr->get_prob());
504 gtk_label_set_text(GTK_LABEL(log_main),str);
505 g_free(str);
506 } else
507 gtk_label_set_text(GTK_LABEL(log_main),"Word not found.");
511 void candidates_reset()
513 gtk_list_store_clear(list_store);
516 void candidates_add(const gchar *s)
518 GtkTreeIter iter;
519 gtk_list_store_append(list_store,&iter);
520 gtk_list_store_set(list_store,&iter,
521 0,s,
522 -1);
525 bool MyText::ui_syllable_check()
527 unsigned i,n = suggestions.size();
528 for (i = 0;i < n;i ++) {
529 show_wrong_syllables(i);
530 // query
531 int from,len;
532 from = st[suggestions[i].id].start;
533 len = strlen(get_sarch()[st[suggestions[i].id].id]);
534 string s = substr(from,len);
535 gtk_entry_set_text(GTK_ENTRY(spell_entry),s.c_str());
536 vector<string> candidates;
537 Candidates c;
538 candidates_reset();
539 get_syllable_candidates(get_sarch()[st[suggestions[i].id].id],c);
540 c.get_list(candidates);
541 vector<string>::iterator iter;
542 for (iter = candidates.begin();iter != candidates.end();++ iter)
543 candidates_add(viet_to_utf8(iter->c_str()));
544 processed = ignore_all = ignore = false;
545 while (!gtk_main_iteration() && !ignore && !ignore_all && !processed);
547 if (ignore)
548 continue;
550 if (ignore_all)
551 return true; // force to exit
553 if (processed) {
554 cerr << "Input: The right one is:" << endl;
556 const gchar *s = gtk_entry_get_text(GTK_ENTRY(spell_entry));
558 if (*s == 0)
559 continue; // i don't accept an empty string
561 replace(st[suggestions[i].id].start, // from
562 strlen(get_sarch()[st[suggestions[i].id].get_id()]), // size
563 s); // text
564 vspell->add(get_sarch()[viet_to_viscii_force(s)]);
566 return false;
568 return true; // some things went wrong
570 return !is_checking;
573 string MyText::word_to_utf8(unsigned seg_id)
575 vector<strid> sylls;
576 string s;
577 seg[seg_id].node->get_syllables(sylls);
578 int i,n = sylls.size();
579 for (i = 0;i < n;i ++) {
580 if (i)
581 s += " ";
582 Syllable syll;
583 syll.parse(get_sarch()[sylls[i]]);
584 s += viet_to_utf8(syll.to_str().c_str());
586 return s;
589 bool MyText::ui_word_check()
591 unsigned i,n = suggestions.size();
592 int pos,pos2,count;
594 for (i = 0;i < n;i ++) {
595 show_wrong_words(i);
596 // query
597 count = seg[suggestions[i].id].node->get_syllable_count();
598 pos = (*seg.we)[seg[suggestions[i].id].id].pos;
599 pos2 = pos+count-1;
600 int from,len;
601 from = st[pos].start;
602 len = st[pos2].start+strlen(get_sarch()[st[pos2].id])-from;
603 string s = substr(from,len);
604 gtk_entry_set_text(GTK_ENTRY(spell_entry),s.c_str());
605 candidates_reset();
606 candidates_add(word_to_utf8(suggestions[i].id).c_str());
607 processed = ignore_all = ignore = false;
608 while (!gtk_main_iteration() && !ignore && !ignore_all && !processed);
610 if (ignore)
611 continue;
613 if (ignore_all)
614 return true; // force to exit
616 if (processed) {
617 string s = gtk_entry_get_text(GTK_ENTRY(spell_entry));
619 if (s.empty())
620 continue;
622 count = seg[suggestions[i].id].node->get_syllable_count();
623 pos = (*seg.we)[seg[suggestions[i].id].id].pos;
624 pos2 = pos+count-1;
626 string::size_type p;
627 vector<unsigned> separators;
628 while ((p = s.find('|')) != string::npos) {
629 separators.push_back(st[pos].start+g_utf8_strlen(s.substr(0,p).c_str(),-1)+offset);
630 s.erase(p,1);
633 replace(st[pos].start, // from
634 st[pos2].start+strlen(get_sarch()[st[pos2].get_id()])-st[pos].start, // size
635 s.c_str()); // text
637 // add separators after replacing the text, to have old separators removed
638 vspell->add_word(viet_to_viscii_force(s.c_str()));
639 vspell->add_separators(separators);
640 return false; // continue checking
642 return true; // some things went wrong
644 return !is_checking;
647 bool MyText::word_check()
649 bool ret = Text::word_check();
650 if (word_boundaries)
651 show_words();
652 return ret;