diff options
author | b0ric <b0risov.alexandr@rambler.ru> | 2009-08-15 20:10:40 +0300 |
---|---|---|
committer | b0ric <b0risov.alexandr@rambler.ru> | 2009-08-15 20:10:40 +0300 |
commit | 9d2cc46e50218768b43d4f8b80647828bca74576 (patch) | |
tree | 82f6670a01248d517ff0c3b8070cffc16ea4b48f | |
parent | d2b347e0aa6e5fc3de95253c43900c15938dbaaf (diff) |
It seems that everything is working except settings (they are in TODO)
-rw-r--r-- | confwin.c | 281 | ||||
-rw-r--r-- | confwin.h | 4 | ||||
-rw-r--r-- | dict.c | 19 | ||||
-rw-r--r-- | dict.h | 6 | ||||
-rw-r--r-- | dictwin.c | 354 | ||||
-rw-r--r-- | dictwin.h | 4 | ||||
-rw-r--r-- | engparser.c | 12 | ||||
-rw-r--r-- | engparser.h | 6 | ||||
-rw-r--r-- | interface.c | 383 | ||||
-rw-r--r-- | interface.h | 41 | ||||
-rw-r--r-- | main.c | 29 | ||||
-rw-r--r-- | main.h | 6 | ||||
-rw-r--r-- | mainwin.c | 369 | ||||
-rw-r--r-- | mainwin.h | 4 | ||||
-rw-r--r-- | subtitle.h | 32 | ||||
-rw-r--r-- | word.c | 161 | ||||
-rw-r--r-- | word.h | 28 |
17 files changed, 983 insertions, 756 deletions
@@ -10,59 +10,258 @@ * * WordExtract is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with WordExtract. If not, see <http://www.gnu.org/licenses/>. + * along with WordExtract. If not, see <http://www.gnu.org/licenses/>. */ #include <gtk/gtk.h> #include "mainwin.h" +#include "engparser.h" +#include "main.h" static GtkWidget *conf_win; +/*quote controls*/ +static GtkWidget *wquot_btn; /*==excl_with_quoted_btn (here and below*/ +static GtkWidget *quoted_btn; /*'excl_' part of vatiable name is omitted)*/ +static GtkWidget *st_quote_btn; +static GtkWidget *mid_quote_btn; +static GtkWidget *after_quote_btn; +static GtkWidget *end_quote_btn; +/*hyphen controls*/ +static GtkWidget *whyph_btn; +static GtkWidget *hyphened_btn; +static GtkWidget *st_hyphen_btn; +static GtkWidget *mid_hyphen_btn; +static GtkWidget *after_hyphen_btn; +static GtkWidget *end_hyphen_btn; static void ok_btn_click(GtkWidget *, gpointer); static void cancel_btn_click(GtkWidget *, gpointer); +static void wquot_btn_click(GtkWidget *, gpointer); +static void mid_quote_btn_click(GtkWidget *, gpointer); +static void after_quote_btn_click(GtkWidget *, gpointer); +static void whyph_btn_click(GtkWidget *, gpointer); +static void mid_hyphen_btn_click(GtkWidget *, gpointer); +static void after_hyphen_btn_click(GtkWidget *, gpointer); void create_conf_win() { conf_win = gtk_window_new(GTK_WINDOW_TOPLEVEL); - gtk_widget_set_size_request(conf_win, 550, 410); + gtk_widget_set_size_request(conf_win, 440, 330); gtk_window_set_title(GTK_WINDOW(conf_win), "WordExtract Preferences"); gtk_window_set_transient_for(GTK_WINDOW(conf_win), GTK_WINDOW(main_window)); gtk_window_set_position(GTK_WINDOW(conf_win), GTK_WIN_POS_CENTER_ON_PARENT); gtk_window_set_modal(GTK_WINDOW(conf_win), TRUE); gtk_window_set_skip_taskbar_hint(GTK_WINDOW(conf_win), TRUE); - GtkWidget *vbox; - vbox = gtk_vbox_new(FALSE, 2); + GtkWidget *vbox = gtk_vbox_new(FALSE, 2); gtk_container_add(GTK_CONTAINER(conf_win), vbox); gtk_widget_show(vbox); - GtkWidget *tabs; - tabs = gtk_notebook_new(); - gtk_box_pack_start(GTK_BOX(vbox), tabs, TRUE, FALSE, 2); + GtkWidget *tabs = gtk_notebook_new(); + gtk_box_pack_start(GTK_BOX(vbox), tabs, TRUE, TRUE, 2); + /*'General' tab*/ + GtkWidget *gen_label = gtk_label_new("General"); + GtkWidget *gen_frame = gtk_frame_new(NULL); + gtk_container_set_border_width(GTK_CONTAINER(gen_frame), 5); + gtk_frame_set_shadow_type(GTK_FRAME(gen_frame), GTK_SHADOW_IN); + gtk_widget_show(gen_frame); + + GtkWidget *gen_table = gtk_table_new(6, 12, TRUE); + gtk_container_set_border_width(GTK_CONTAINER(gen_table), 10); + gtk_container_add(GTK_CONTAINER(gen_frame), gen_table); + gtk_widget_show(gen_table); + + GtkWidget *save_label = gtk_label_new("<b>Words saving options</b>"); + gtk_label_set_use_markup(GTK_LABEL(save_label), TRUE); + gtk_table_attach_defaults(GTK_TABLE(gen_table), save_label, 0, 6, 0, 1); + gtk_misc_set_alignment(GTK_MISC(save_label), 0, 0.5); + gtk_widget_show(save_label); + + GtkWidget *col_label = gtk_label_new("Columns: "); + gtk_misc_set_alignment(GTK_MISC(col_label), 0, 0.5); + gtk_table_attach_defaults(GTK_TABLE(gen_table), col_label, 1, 4, 1, 2); + gtk_widget_show(col_label); + + GtkObject *col_adjust = gtk_adjustment_new(save_user_words.columns, 1, 10, 1, 2, 0); + GtkWidget *col_counter = gtk_spin_button_new(GTK_ADJUSTMENT(col_adjust), 0.5, 0); + gtk_widget_set_tooltip_text(col_counter, "Specify how many columns will be in the saved list of the words"); + gtk_table_attach_defaults(GTK_TABLE(gen_table), col_counter, 5, 7, 1, 2); + gtk_widget_show(col_counter); + + gboolean field_sens = (save_user_words.columns > 1) ? TRUE : FALSE; + GtkWidget *field_label = gtk_label_new("Field langth: "); + gtk_misc_set_alignment(GTK_MISC(field_label), 0, 0.5); + gtk_widget_set_sensitive(field_label, field_sens); + gtk_table_attach_defaults(GTK_TABLE(gen_table), field_label, 1, 4, 2, 3); + gtk_widget_show(field_label); + + GtkObject *field_adjust = gtk_adjustment_new(save_user_words.col_width, 10, 100, 1, 10, 0); + GtkWidget *field_counter = gtk_spin_button_new(GTK_ADJUSTMENT(field_adjust), 0.5, 0); + gtk_widget_set_tooltip_text(field_counter, "Specify length of one field (in symbols) in the saved list of the words"); + gtk_widget_set_sensitive(field_counter, field_sens); + gtk_table_attach_defaults(GTK_TABLE(gen_table), field_counter, 5, 7, 2, 3); + gtk_widget_show(field_counter); + gtk_notebook_append_page(GTK_NOTEBOOK(tabs), gen_frame, gen_label); + + /*'Analysing' tab*/ + GtkWidget *analys_label = gtk_label_new("Analysing"); + GtkWidget *analys_frame = gtk_frame_new(NULL); + gtk_container_set_border_width(GTK_CONTAINER(analys_frame), 5); + gtk_frame_set_shadow_type(GTK_FRAME(analys_frame), GTK_SHADOW_IN); + gtk_widget_show(analys_frame); + + GtkWidget *analys_sc_win = gtk_scrolled_window_new(NULL, NULL); + gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(analys_sc_win), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + gtk_container_add(GTK_CONTAINER(analys_frame), analys_sc_win); + gtk_widget_show(analys_sc_win); + + GtkWidget *analys_table = gtk_table_new(17, 12, TRUE); + gtk_container_set_border_width(GTK_CONTAINER(analys_table), 10); + gtk_widget_set_size_request(analys_table, 390, 700); + gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(analys_sc_win), analys_table); + gtk_widget_show(analys_table); + + GtkWidget *lang_label = gtk_label_new("Analyser language: "); + gtk_table_attach_defaults(GTK_TABLE(analys_table), lang_label, 0, 4, 0, 1); + gtk_widget_show(lang_label); + + GtkWidget *lang_box = gtk_combo_box_new_text(); + gtk_combo_box_append_text(GTK_COMBO_BOX(lang_box), "English"); + gtk_combo_box_set_active(GTK_COMBO_BOX(lang_box), 0); + gtk_table_attach_defaults(GTK_TABLE(analys_table), lang_box, 5, 9, 0, 1); + gtk_widget_set_tooltip_text(lang_box, "Language of the text you want to analyse"); + gtk_widget_show(lang_box); + + GtkWidget *wcap_btn = gtk_check_button_new_with_label("Exclude words with capital letters"); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(wcap_btn), (gboolean) excl_w_capital); + gtk_table_attach_defaults(GTK_TABLE(analys_table), wcap_btn, 0, 12, 1, 2); + gtk_widget_show(wcap_btn); + + GtkWidget *lower_first_cap = gtk_check_button_new_with_label("Lower first capital in each sentence"); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lower_first_cap), (gboolean) lower_first_capital); + gtk_table_attach_defaults(GTK_TABLE(analys_table), lower_first_cap, 0, 12, 2, 3); + gtk_widget_show(lower_first_cap); + + GtkWidget *quote_label = gtk_label_new("<b>Quotes analysis</b>"); + gtk_label_set_use_markup(GTK_LABEL(quote_label), TRUE); + gtk_misc_set_alignment(GTK_MISC(quote_label), 0, 0.5); + gtk_table_attach_defaults(GTK_TABLE(analys_table), quote_label, 0, 12, 3, 4); + gtk_widget_show(quote_label); + + wquot_btn = gtk_check_button_new_with_label("Exclude words with quotes"); + gboolean quotes = quote.excl_symbolled&"e.excl_w_starting&"e.excl_w_middle + &"e.excl_w_ending&"e.excl_word_after_symb; + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(wquot_btn), quotes); + gtk_table_attach_defaults(GTK_TABLE(analys_table), wquot_btn, 1, 12, 4, 5); + g_signal_connect(G_OBJECT(wquot_btn), "clicked", G_CALLBACK(wquot_btn_click), NULL); + gtk_widget_show(wquot_btn); + + quoted_btn = gtk_check_button_new_with_label("Exclude 'quoted' words"); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(quoted_btn), quote.excl_symbolled); + gtk_widget_set_sensitive(quoted_btn, !quotes); + gtk_table_attach_defaults(GTK_TABLE(analys_table), quoted_btn, 2, 12, 5, 6); + gtk_widget_show(quoted_btn); + + st_quote_btn = gtk_check_button_new_with_label("Exclude words with 'quote in the beginning"); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(st_quote_btn), quote.excl_w_starting); + gtk_widget_set_sensitive(st_quote_btn, !quotes); + gtk_table_attach_defaults(GTK_TABLE(analys_table), st_quote_btn, 2, 12, 6, 7); + gtk_widget_show(st_quote_btn); + + mid_quote_btn = gtk_check_button_new_with_label("Exclude words with quo'te in the middle"); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(mid_quote_btn), quote.excl_w_middle); + gtk_widget_set_sensitive(mid_quote_btn, !quotes&&!quote.excl_word_after_symb); + gtk_table_attach_defaults(GTK_TABLE(analys_table), mid_quote_btn, 2, 12, 7, 8); + g_signal_connect(G_OBJECT(mid_quote_btn), "clicked", G_CALLBACK(mid_quote_btn_click), NULL); + gtk_widget_show(mid_quote_btn); + + after_quote_btn = gtk_check_button_new(); + GtkWidget *after_quote_label = gtk_label_new("Exclude part of the word after quo<s>'te</s>"); + gtk_label_set_use_markup(GTK_LABEL(after_quote_label), TRUE); + gtk_container_add(GTK_CONTAINER(after_quote_btn), after_quote_label); + gtk_widget_show(after_quote_label); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(after_quote_btn), quote.excl_word_after_symb); + gtk_widget_set_sensitive(after_quote_btn, !quotes&&!quote.excl_w_middle); + gtk_table_attach_defaults(GTK_TABLE(analys_table), after_quote_btn, 2, 12, 8, 9); + g_signal_connect(G_OBJECT(after_quote_btn), "clicked", G_CALLBACK(after_quote_btn_click), NULL); + gtk_widget_show(after_quote_btn); + + end_quote_btn = gtk_check_button_new_with_label("Exclude words with quote' in the end"); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(end_quote_btn), quote.excl_w_ending); + gtk_widget_set_sensitive(end_quote_btn, !quotes); + gtk_table_attach_defaults(GTK_TABLE(analys_table), end_quote_btn, 2, 12, 9, 10); + gtk_widget_show(end_quote_btn); + + GtkWidget *hyphen_label = gtk_label_new("<b>Hyphen analysis</b>"); + gtk_label_set_use_markup(GTK_LABEL(hyphen_label), TRUE); + gtk_misc_set_alignment(GTK_MISC(hyphen_label), 0, 0.5); + gtk_table_attach_defaults(GTK_TABLE(analys_table), hyphen_label, 0, 12, 10, 11); + gtk_widget_show(hyphen_label); + + whyph_btn = gtk_check_button_new_with_label("Exclude words with hyphens"); + gboolean hyphens = hyphen.excl_symbolled&&hyphen.excl_w_starting&&hyphen.excl_w_middle + &&hyphen.excl_w_ending&&hyphen.excl_word_after_symb; + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(whyph_btn), hyphens); + gtk_table_attach_defaults(GTK_TABLE(analys_table), whyph_btn, 1, 12, 11, 12); + g_signal_connect(G_OBJECT(whyph_btn), "clicked", G_CALLBACK(whyph_btn_click), NULL); + gtk_widget_show(whyph_btn); + + hyphened_btn = gtk_check_button_new_with_label("Exclude -hyphened- words"); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(hyphened_btn), hyphen.excl_symbolled); + gtk_widget_set_sensitive(hyphened_btn, !hyphens); + gtk_table_attach_defaults(GTK_TABLE(analys_table), hyphened_btn, 2, 12, 12, 13); + gtk_widget_show(hyphened_btn); + + st_hyphen_btn = gtk_check_button_new_with_label("Exclude words with -hyphen in the beginning"); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(st_hyphen_btn), hyphen.excl_w_starting); + gtk_widget_set_sensitive(st_hyphen_btn, !hyphens); + gtk_table_attach_defaults(GTK_TABLE(analys_table), st_hyphen_btn, 2, 12, 13, 14); + gtk_widget_show(st_hyphen_btn); + + mid_hyphen_btn = gtk_check_button_new_with_label("Exclude words with hy-phen in the middle"); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(mid_hyphen_btn), hyphen.excl_w_middle); + gtk_widget_set_sensitive(mid_hyphen_btn, !hyphens); + gtk_table_attach_defaults(GTK_TABLE(analys_table), mid_hyphen_btn, 2, 12, 14, 15); + g_signal_connect(G_OBJECT(mid_hyphen_btn), "clicked", G_CALLBACK(mid_hyphen_btn_click), NULL); + gtk_widget_show(mid_hyphen_btn); + + after_hyphen_btn = gtk_check_button_new(); + GtkWidget *after_hyphen_label = gtk_label_new("Exclude part of the word after hy<s>-phen</s>"); + gtk_label_set_use_markup(GTK_LABEL(after_hyphen_label), TRUE); + gtk_container_add(GTK_CONTAINER(after_hyphen_btn), after_hyphen_label); + gtk_widget_show(after_hyphen_label); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(after_hyphen_btn), hyphen.excl_word_after_symb); + gtk_widget_set_sensitive(mid_hyphen_btn, !hyphens&&!hyphen.excl_word_after_symb); + gtk_table_attach_defaults(GTK_TABLE(analys_table), after_hyphen_btn, 2, 12, 15, 16); + g_signal_connect(G_OBJECT(after_hyphen_btn), "clicked", G_CALLBACK(after_hyphen_btn_click), NULL); + gtk_widget_show(after_hyphen_btn); + + end_hyphen_btn = gtk_check_button_new_with_label("Exclude words with hyphen- in the end"); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(end_hyphen_btn), hyphen.excl_w_ending); + gtk_widget_set_sensitive(end_hyphen_btn, !hyphens); + gtk_table_attach_defaults(GTK_TABLE(analys_table), end_hyphen_btn, 2, 12, 16, 17); + gtk_widget_show(end_hyphen_btn); + gtk_notebook_append_page(GTK_NOTEBOOK(tabs), analys_frame, analys_label); gtk_widget_show(tabs); - GtkWidget *hbox; - hbox = gtk_hbox_new(FALSE, 2); + GtkWidget *hbox = gtk_hbox_new(FALSE, 2); gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); gtk_widget_show(hbox); - GtkWidget *btn_hbox; - btn_hbox = gtk_hbox_new(TRUE, 2); + GtkWidget *btn_hbox = gtk_hbox_new(TRUE, 2); gtk_box_pack_end(GTK_BOX(hbox), btn_hbox, FALSE, FALSE, 0); gtk_widget_show(btn_hbox); - GtkWidget *ok_btn; - ok_btn = gtk_button_new_from_stock(GTK_STOCK_OK); + GtkWidget *ok_btn = gtk_button_new_from_stock(GTK_STOCK_OK); gtk_box_pack_end(GTK_BOX(btn_hbox), ok_btn, TRUE, TRUE, 0); g_signal_connect(G_OBJECT(ok_btn), "clicked", G_CALLBACK(ok_btn_click), NULL); gtk_widget_show(ok_btn); - GtkWidget *cancel_btn; - cancel_btn = gtk_button_new_from_stock(GTK_STOCK_CANCEL); + GtkWidget *cancel_btn = gtk_button_new_from_stock(GTK_STOCK_CANCEL); gtk_box_pack_end(GTK_BOX(btn_hbox), cancel_btn, TRUE, TRUE, 0); g_signal_connect(G_OBJECT(cancel_btn), "clicked", G_CALLBACK(cancel_btn_click), NULL); gtk_widget_show(cancel_btn); @@ -81,3 +280,53 @@ static void cancel_btn_click(GtkWidget *widget, gpointer data) gtk_widget_destroy(conf_win); } +static void wquot_btn_click(GtkWidget *button, gpointer data) +{ + gboolean state = !gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button)); + gtk_widget_set_sensitive(quoted_btn, state); + gtk_widget_set_sensitive(st_quote_btn, state); + gtk_widget_set_sensitive(mid_quote_btn, state); + gtk_widget_set_sensitive(after_quote_btn, state); + gtk_widget_set_sensitive(end_quote_btn, state); +} + +static void mid_quote_btn_click(GtkWidget *button, gpointer data) +{ + gboolean state = !gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button)); + gtk_widget_set_sensitive(after_quote_btn, state); +} + +static void after_quote_btn_click(GtkWidget *button, gpointer data) +{ + gboolean state = !gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button)); + gtk_widget_set_sensitive(mid_quote_btn, state); +} + +static void whyph_btn_click(GtkWidget *button, gpointer data) +{ + gboolean state = !gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button)); + gtk_widget_set_sensitive(hyphened_btn, state); + gtk_widget_set_sensitive(st_hyphen_btn, state); + gtk_widget_set_sensitive(mid_hyphen_btn, state); + gtk_widget_set_sensitive(after_hyphen_btn, state); + gtk_widget_set_sensitive(end_hyphen_btn, state); +} + +static void mid_hyphen_btn_click(GtkWidget *button, gpointer data) +{ + gboolean state = !gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button)); + gtk_widget_set_sensitive(after_hyphen_btn, state); +} + +static void after_hyphen_btn_click(GtkWidget *button, gpointer data) +{ + gboolean state = !gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button)); + gtk_widget_set_sensitive(mid_hyphen_btn, state); +} + + + + + + + @@ -10,11 +10,11 @@ * * WordExtract is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with WordExtract. If not, see <http://www.gnu.org/licenses/>. + * along with WordExtract. If not, see <http://www.gnu.org/licenses/>. */ #ifndef CONFWIN_H @@ -10,11 +10,11 @@ * * WordExtract is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with WordExtract. If not, see <http://www.gnu.org/licenses/>. + * along with WordExtract. If not, see <http://www.gnu.org/licenses/>. */ #include <sys/stat.h> @@ -25,6 +25,7 @@ #include "main.h" Word *dict; +SortedWords dict_words = {0, NULL}; static void create_dict_file(char *path); @@ -48,14 +49,24 @@ Word *load_dict() if (strcmp(word, "\0") == 0) /*to not process final blank line*/ break; word[strlen(word)-1] = '\0'; - root = add_word_record(root, word); + root = add_word(root, word); for (i = 0; i < WORDLENGTH; i++) word[i] = 0; } fclose(fdict); + dict_words = get_sorted(root); return root; } +void save_dict(FILE *file, Word *root) +{ + if (root != NULL) { + fprintf(file, "%s\n", root->word); + save_dict(file, root->lsibl); + save_dict(file, root->rsibl); + } +} + int is_in_dict(char *word, Word *dic_rec) { int cond; @@ -74,7 +85,7 @@ int is_in_dict(char *word, Word *dic_rec) void create_dict_file(char *path) { - mode_t mode_0755 = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH; + mode_t mode_0755 = S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH; struct stat st; FILE *fdict; char file[PATH_LENGTH] = {0}; @@ -10,11 +10,11 @@ * * WordExtract is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with WordExtract. If not, see <http://www.gnu.org/licenses/>. + * along with WordExtract. If not, see <http://www.gnu.org/licenses/>. */ #ifndef DICTIONARY_H @@ -27,8 +27,10 @@ #define NOT_IN_DICT 0 extern Word *dict; +extern SortedWords dict_words; Word *load_dict(); +void save_dict(FILE *, Word *); int is_in_dict(char *, Word *); #endif /*DICT_H*/ @@ -10,30 +10,50 @@ * * WordExtract is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with WordExtract. If not, see <http://www.gnu.org/licenses/>. + * along with WordExtract. If not, see <http://www.gnu.org/licenses/>. */ #include <gtk/gtk.h> +#include <gdk/gdkkeysyms.h> #include <stdlib.h> +#include <string.h> #include "dictwin.h" #include "mainwin.h" #include "dict.h" -enum {WORD_ITEM = 0, N_COLUMNS}; +enum {ICON_COL = 0, ICON_STR_COL, WORD_COL, N_COLUMNS}; +enum {WORD_ITEM = 0}; +static GtkWidget *dict_words_list; +static GtkWidget *user_words_list; +static GtkListStore *user_store_model; +static GtkWidget *words_cnt_label; + +static void set_words_count(); +static void gtk_renderer_set_stock_icon(GtkTreeViewColumn *, GtkCellRenderer *, GtkTreeModel *, GtkTreeIter *, gpointer); +static gboolean dict_words_popup_by_click(GtkWidget *, GdkEventButton *, gpointer); +static gboolean dict_words_popup_by_keybd(GtkWidget *, gpointer); +static void dict_words_popup(GtkWidget *widget, GdkEventButton *); +static void remove_word_item_click(GtkWidget *, gpointer); +static gboolean dict_words_list_key_press(GtkWidget *, GdkEventKey *, gpointer); +static gboolean user_words_list_key_press(GtkWidget *, GdkEventKey *, gpointer); static void fill_dict_words(GtkListStore *, char **); +static void add_btn_click(GtkWidget *, gpointer); +static gboolean add_entry_key_press(GtkWidget *, GdkEventKey *, gpointer); static void cancel_btn_click(GtkWidget *, gpointer); static void ok_btn_click(GtkWidget *, gpointer); void create_dict_win() { - GtkWidget *dict_win; - - dict_win = gtk_window_new(GTK_WINDOW_TOPLEVEL); + /*at first we refresh sorted list of words*/ + free(dict_words.by_az); + dict_words = get_sorted(dict); + + GtkWidget *dict_win = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_widget_set_size_request(dict_win, 550, 410); gtk_window_set_title(GTK_WINDOW(dict_win), "My Dictionary"); gtk_window_set_transient_for(GTK_WINDOW(dict_win), GTK_WINDOW(main_window)); @@ -41,132 +61,132 @@ void create_dict_win() gtk_window_set_modal(GTK_WINDOW(dict_win), TRUE); gtk_window_set_skip_taskbar_hint(GTK_WINDOW(dict_win), TRUE); - GtkWidget *vbox; - vbox = gtk_vbox_new(FALSE, 2); + GtkWidget *vbox = gtk_vbox_new(FALSE, 2); gtk_container_add(GTK_CONTAINER(dict_win), vbox); gtk_widget_show(vbox); - GtkWidget *dict_hbox; - dict_hbox = gtk_hbox_new(TRUE, 2); + GtkWidget *dict_hbox = gtk_hbox_new(TRUE, 2); gtk_box_pack_start(GTK_BOX(vbox), dict_hbox, TRUE, TRUE, 2); gtk_widget_show(dict_hbox); /*dictionary panel*/ - GtkWidget *dict_vbox; - dict_vbox = gtk_vbox_new(FALSE, 2); + GtkWidget *dict_vbox = gtk_vbox_new(FALSE, 2); gtk_box_pack_start(GTK_BOX(dict_hbox), dict_vbox, TRUE, TRUE, 0); gtk_widget_show(dict_vbox); - GtkWidget *dict_label; - dict_label = gtk_label_new("Words in your dictionary: "); + GtkWidget *dict_label = gtk_label_new("Words in your dictionary: "); gtk_box_pack_start(GTK_BOX(dict_vbox), dict_label, FALSE, FALSE, 0); gtk_widget_show(dict_label); - GtkWidget *dict_sc; - dict_sc = gtk_scrolled_window_new(NULL, NULL); - gtk_box_pack_start(GTK_BOX(dict_vbox), dict_sc, TRUE, TRUE, 0); + GtkWidget *dict_sc = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(dict_sc), GTK_SHADOW_IN); + gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(dict_sc), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + gtk_box_pack_start(GTK_BOX(dict_vbox), dict_sc, TRUE, TRUE, 0); gtk_widget_show(dict_sc); - char **dict_words; - GtkWidget *dict_words_list; - GtkListStore *store_model; - GtkCellRenderer *renderer; - GtkTreeViewColumn *column; dict_words_list = gtk_tree_view_new(); gtk_tree_selection_set_mode(gtk_tree_view_get_selection(GTK_TREE_VIEW(dict_words_list)), GTK_SELECTION_SINGLE); gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(dict_words_list), FALSE); gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(dict_words_list), TRUE); gtk_container_add(GTK_CONTAINER(dict_sc), dict_words_list); - store_model = gtk_list_store_new(N_COLUMNS, G_TYPE_STRING); + GtkListStore *store_model = gtk_list_store_new(1, G_TYPE_STRING); gtk_tree_view_set_model(GTK_TREE_VIEW(dict_words_list), GTK_TREE_MODEL(store_model)); - renderer = gtk_cell_renderer_text_new(); + + GtkCellRenderer *renderer = gtk_cell_renderer_text_new(); g_object_set(renderer, "editable", TRUE, NULL); - column = gtk_tree_view_column_new_with_attributes("List Items", renderer, "text", WORD_ITEM, NULL); + GtkTreeViewColumn *column = gtk_tree_view_column_new_with_attributes("List Items", renderer, "text", WORD_ITEM, NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(dict_words_list), column); - dict_words = get_sorted(dict); - fill_dict_words(store_model, dict_words); - free(dict_words); + g_signal_connect(G_OBJECT(dict_words_list), "button-press-event", G_CALLBACK(dict_words_popup_by_click), NULL); + g_signal_connect(G_OBJECT(dict_words_list), "popup-menu", G_CALLBACK(dict_words_popup_by_keybd), NULL); + fill_dict_words(store_model, dict_words.by_az); + + g_signal_connect(G_OBJECT(dict_words_list), "key-press-event", G_CALLBACK(dict_words_list_key_press), NULL); gtk_widget_show(dict_words_list); - /*user text panel*/ - GtkWidget *user_vbox; - user_vbox = gtk_vbox_new(FALSE, 2); + /*user words panel*/ + GtkWidget *user_vbox = gtk_vbox_new(FALSE, 2); gtk_box_pack_start(GTK_BOX(dict_hbox), user_vbox, TRUE, TRUE, 0); gtk_widget_show(user_vbox); - GtkWidget *user_label; - user_label = gtk_label_new("Changes to your dictionary: "); + GtkWidget *user_label = gtk_label_new("Changes to your dictionary: "); gtk_box_pack_start(GTK_BOX(user_vbox), user_label, FALSE, FALSE, 0); gtk_widget_show(user_label); - GtkWidget *user_sc; - user_sc = gtk_scrolled_window_new(NULL, NULL); - gtk_box_pack_start(GTK_BOX(user_vbox), user_sc, TRUE, TRUE, 0); + GtkWidget *user_sc = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(user_sc), GTK_SHADOW_IN); + gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(user_sc), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + gtk_box_pack_start(GTK_BOX(user_vbox), user_sc, TRUE, TRUE, 0); gtk_widget_show(user_sc); - GtkWidget *user_words; - GtkListStore *user_store_model; - GtkCellRenderer *user_renderer; - GtkTreeViewColumn *user_column; - user_words = gtk_tree_view_new(); - gtk_tree_selection_set_mode(gtk_tree_view_get_selection(GTK_TREE_VIEW(user_words)), GTK_SELECTION_SINGLE); - gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(user_words), FALSE); - gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(user_words), TRUE); - gtk_container_add(GTK_CONTAINER(user_sc), user_words); - user_store_model = gtk_list_store_new(N_COLUMNS, G_TYPE_STRING); - gtk_tree_view_set_model(GTK_TREE_VIEW(user_words), GTK_TREE_MODEL(user_store_model)); - user_renderer = gtk_cell_renderer_text_new(); - g_object_set(user_renderer, "editable", TRUE, NULL); - user_column = gtk_tree_view_column_new_with_attributes("List Items", user_renderer, "text", WORD_ITEM, NULL); - gtk_tree_view_append_column(GTK_TREE_VIEW(user_words), user_column); - gtk_widget_show(user_words); - - GtkWidget *entry_hbox; - entry_hbox = gtk_hbox_new(FALSE, 2); + user_words_list = gtk_tree_view_new(); + gtk_tree_selection_set_mode(gtk_tree_view_get_selection(GTK_TREE_VIEW(user_words_list)), GTK_SELECTION_SINGLE); + gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(user_words_list), FALSE); + gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(user_words_list), TRUE); + user_store_model = gtk_list_store_new(N_COLUMNS, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING); + gtk_tree_view_set_model(GTK_TREE_VIEW(user_words_list), GTK_TREE_MODEL(user_store_model)); + g_object_unref(user_store_model); + + GtkTreeViewColumn *user_column = gtk_tree_view_column_new(); + GtkCellRenderer *icon_renderer = gtk_cell_renderer_pixbuf_new(); + gtk_tree_view_column_pack_start(user_column, icon_renderer, TRUE); + gtk_tree_view_column_set_attributes(user_column, icon_renderer, "pixbuf", ICON_COL, NULL); + gtk_tree_view_column_set_cell_data_func(user_column, icon_renderer, gtk_renderer_set_stock_icon, NULL, NULL); + gtk_tree_view_append_column(GTK_TREE_VIEW(user_words_list), user_column); + /*second data fild is for icon stock id. so it doesn't need column*/ + user_column = gtk_tree_view_column_new(); + renderer = gtk_cell_renderer_text_new(); + g_object_set(renderer, "editable", TRUE, NULL); + gtk_tree_view_column_pack_start(user_column, renderer, TRUE); + gtk_tree_view_column_set_attributes(user_column, renderer, "text", WORD_COL, NULL); + gtk_tree_view_append_column(GTK_TREE_VIEW(user_words_list), user_column); + gtk_container_add(GTK_CONTAINER(user_sc), user_words_list); + + g_signal_connect(G_OBJECT(user_words_list), "key-press-event", G_CALLBACK(user_words_list_key_press), NULL); + gtk_widget_show(user_words_list); + + GtkWidget *entry_hbox = gtk_hbox_new(FALSE, 2); gtk_box_pack_start(GTK_BOX(user_vbox), entry_hbox, FALSE, FALSE, 0); gtk_widget_show(entry_hbox); - GtkWidget *add_label; - add_label = gtk_label_new("Add word: "); + GtkWidget *add_label = gtk_label_new("Add word: "); gtk_box_pack_start(GTK_BOX(entry_hbox), add_label, FALSE, FALSE, 0); gtk_widget_show(add_label); - GtkWidget *add_entry; - add_entry = gtk_entry_new_with_max_length(WORDLENGTH); + GtkWidget *add_entry = gtk_entry_new_with_max_length(WORDLENGTH); gtk_box_pack_start(GTK_BOX(entry_hbox), add_entry, FALSE, FALSE, 0); + g_signal_connect(G_OBJECT(add_entry), "activate", G_CALLBACK(add_btn_click), NULL); + g_signal_connect(G_OBJECT(add_entry), "key-press-event", G_CALLBACK(add_entry_key_press), (gpointer) user_words_list); gtk_widget_show(add_entry); - GtkWidget *add_btn; - GtkWidget *image; - add_btn = gtk_button_new(); - image = gtk_image_new_from_stock(GTK_STOCK_ADD, GTK_ICON_SIZE_BUTTON); + GtkWidget *add_btn = gtk_button_new(); + GtkWidget *image = gtk_image_new_from_stock(GTK_STOCK_ADD, GTK_ICON_SIZE_BUTTON); gtk_container_add(GTK_CONTAINER(add_btn), image); gtk_widget_show(image); gtk_box_pack_start(GTK_BOX(entry_hbox), add_btn, FALSE, FALSE, 0); gtk_widget_set_tooltip_text(GTK_WIDGET(add_btn), "Add word to the dictionary"); + g_signal_connect(G_OBJECT(add_btn), "clicked", G_CALLBACK(add_btn_click), (gpointer) add_entry); gtk_widget_show(add_btn); - GtkWidget *hbox; - hbox = gtk_hbox_new(FALSE, 2); - gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); + GtkWidget *hbox = gtk_hbox_new(FALSE, 2); + gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 2); gtk_widget_show(hbox); - GtkWidget *btn_hbox; - btn_hbox = gtk_hbox_new(TRUE, 2); + words_cnt_label = gtk_label_new(""); + set_words_count(); + gtk_box_pack_start(GTK_BOX(hbox), words_cnt_label, FALSE, FALSE, 0); + gtk_widget_show(words_cnt_label); + + GtkWidget *btn_hbox = gtk_hbox_new(TRUE, 2); gtk_box_pack_end(GTK_BOX(hbox), btn_hbox, FALSE, FALSE, 0); gtk_widget_show(btn_hbox); - GtkWidget *cancel_btn; - cancel_btn = gtk_button_new_from_stock(GTK_STOCK_CANCEL); + GtkWidget *cancel_btn = gtk_button_new_from_stock(GTK_STOCK_CANCEL); gtk_box_pack_end(GTK_BOX(btn_hbox), cancel_btn, TRUE, TRUE, 0); gtk_widget_set_tooltip_text(GTK_WIDGET(cancel_btn), "Discard changes and close the window"); g_signal_connect(G_OBJECT(cancel_btn), "clicked", G_CALLBACK(cancel_btn_click), (gpointer) dict_win); gtk_widget_show(cancel_btn); - GtkWidget *ok_btn; - ok_btn = gtk_button_new_from_stock(GTK_STOCK_OK); + GtkWidget *ok_btn = gtk_button_new_from_stock(GTK_STOCK_OK); gtk_box_pack_end(GTK_BOX(btn_hbox), ok_btn, TRUE, TRUE, 0); gtk_widget_set_tooltip_text(GTK_WIDGET(ok_btn), "Apply changes and close the window"); g_signal_connect(G_OBJECT(ok_btn), "clicked", G_CALLBACK(ok_btn_click), (gpointer) dict_win); @@ -178,16 +198,166 @@ void create_dict_win() static void fill_dict_words(GtkListStore *store, char **word_list) { GtkTreeIter iter; - int cnt, i; + int i; - cnt = get_words_count(dict); - for (i = 0; i < cnt; i++) { + for (i = 0; i < dict_words.count; i++) { gtk_list_store_append(store, &iter); gtk_list_store_set(store, &iter, WORD_ITEM, *word_list, -1); word_list++; } } +static void set_words_count() +{ + char words_cnt_str[40] = {0}; + sprintf(words_cnt_str, "<b> Words in your dictionary: %d</b>", dict_words.count); + gtk_label_set_text(GTK_LABEL(words_cnt_label), words_cnt_str); + gtk_label_set_use_markup(GTK_LABEL(words_cnt_label), TRUE); +} + +static void gtk_renderer_set_stock_icon(GtkTreeViewColumn *column, GtkCellRenderer *renderer, + GtkTreeModel *model, GtkTreeIter *iter, gpointer data) +{ + gchar *stock_id; + + gtk_tree_model_get(GTK_TREE_MODEL(model), iter, ICON_STR_COL, &stock_id, -1); + g_object_set(renderer, "stock-id", stock_id, NULL); +} + +static gboolean dict_words_popup_by_click(GtkWidget *word_list, GdkEventButton *event, gpointer data) +{ + GtkTreePath *path; + + if (event->type == GDK_BUTTON_PRESS && event->button == 3) { + GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(word_list)); + if (gtk_tree_selection_get_selected(GTK_TREE_SELECTION(selection), NULL, NULL)) { + if (gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(word_list), (gint) event->x, + (gint) event->y, &path, NULL, NULL, NULL)) { + gtk_tree_selection_unselect_all(selection); + gtk_tree_selection_select_path(selection, path); + dict_words_popup(GTK_WIDGET(word_list), event); + return TRUE; + } + } + } +return FALSE; +} + +static gboolean dict_words_popup_by_keybd(GtkWidget *word_list, gpointer data) +{ + dict_words_popup(word_list, NULL); + return TRUE; +} + +static void dict_words_popup(GtkWidget *widget, GdkEventButton *event) +{ + GtkWidget *popup_menu = gtk_menu_new(); + GtkWidget *remove_word_item = gtk_image_menu_item_new_from_stock(GTK_STOCK_REMOVE, NULL); + gtk_widget_set_tooltip_text(GTK_WIDGET(remove_word_item), "Remove this word from the dictionary"); + g_signal_connect(G_OBJECT(remove_word_item), "activate", G_CALLBACK(remove_word_item_click), NULL); + gtk_menu_shell_append(GTK_MENU_SHELL(popup_menu), remove_word_item); + gtk_widget_show(remove_word_item); + gtk_widget_show(popup_menu); + gtk_menu_popup(GTK_MENU(popup_menu), NULL, NULL, NULL, NULL, + (event != NULL) ? event->button : 0, gdk_event_get_time((GdkEvent*)event)); +} + +static void remove_word_item_click(GtkWidget *widget, gpointer data) +{ + GtkTreeModel *model; + GtkTreeIter iter; + gboolean valid = FALSE, remove = TRUE; + gchar *word; + + GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(dict_words_list)); + if (gtk_tree_selection_get_selected(selection, &model, &iter)) { + gtk_tree_model_get(model, &iter, WORD_ITEM, &word, -1); + valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(user_store_model), &iter); + gchar *cur_word; + while (valid) { + gtk_tree_model_get(GTK_TREE_MODEL(user_store_model), &iter, WORD_COL, &cur_word, -1); + if (!strcmp(word, cur_word)) { + remove = FALSE; + g_free(cur_word); + break; + } + valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(user_store_model), &iter); + } + if (remove) { + gtk_list_store_append(user_store_model, &iter); + gtk_list_store_set(user_store_model, &iter, ICON_STR_COL, "gtk-remove", WORD_COL, word, -1); + } + } +} + +static gboolean dict_words_list_key_press(GtkWidget *widget, GdkEventKey *event, gpointer data) +{ + if ((event->type == GDK_KEY_PRESS)&&(event->keyval == GDK_Delete)) + remove_word_item_click(widget, data); + return FALSE; +} + +static gboolean user_words_list_key_press(GtkWidget *widget, GdkEventKey *event, gpointer data) +{ + GtkTreeIter iter; + + if ((event->type == GDK_KEY_PRESS)&&(event->keyval == GDK_Delete)) { + GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(user_words_list)); + if (gtk_tree_selection_get_selected(selection, NULL, &iter)) { + gtk_list_store_remove(GTK_LIST_STORE(user_store_model), &iter); + } + } + return FALSE; +} + +static void add_btn_click(GtkWidget *widget, gpointer add_entry) +{ + GtkTreeIter iter; + gpointer entry; + gboolean valid, add = FALSE; + gchar *word; + + if (add_entry) + entry = add_entry; + else + entry = widget; + word = (gchar *) gtk_entry_get_text(GTK_ENTRY(entry)); + add = strcmp(word, "")&&!is_in_dict(word, dict); + + if (add) { + /*check whether word is already in 'words to add' list*/ + valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(user_store_model), &iter); + gchar *cur_word; + while (valid) { + gtk_tree_model_get(GTK_TREE_MODEL(user_store_model), &iter, WORD_COL, &cur_word, -1); + if (!strcmp(word, cur_word)) { + add = FALSE; + g_free(cur_word); + break; + } + valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(user_store_model), &iter); + } + } + if (add) { + gtk_list_store_append(user_store_model, &iter); + gtk_list_store_set(user_store_model, &iter, ICON_STR_COL, "gtk-add", WORD_COL, word, -1); + gtk_entry_set_text(GTK_ENTRY(entry), ""); + } else { + if (strcmp(word, "")) { + gtk_label_set_text(GTK_LABEL(words_cnt_label), "<b>This word is in your dictionary!</b>"); + gtk_label_set_use_markup(GTK_LABEL(words_cnt_label), TRUE); + } + } +} + +static gboolean add_entry_key_press(GtkWidget *widget, GdkEventKey *event, gpointer data) +{ + if (event->type == GDK_KEY_PRESS) + if ((event->length)||(event->keyval == GDK_BackSpace)||(event->keyval == GDK_Delete)) + set_words_count(); + return FALSE; +} + static void cancel_btn_click(GtkWidget *widget, gpointer dict_win) { gtk_widget_destroy(GTK_WIDGET(dict_win)); @@ -195,9 +365,39 @@ static void cancel_btn_click(GtkWidget *widget, gpointer dict_win) static void ok_btn_click(GtkWidget *widget, gpointer dict_win) { - gtk_widget_destroy(GTK_WIDGET(dict_win)); -} + GtkTreeIter iter; + gboolean valid; + gchar *stock_id; + gchar *word; + FILE *fdict; + valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(user_store_model), &iter); + while (valid) { + gtk_tree_model_get(GTK_TREE_MODEL(user_store_model), &iter, ICON_STR_COL, &stock_id, -1); + if (!strcmp(stock_id, "gtk-add")) { + gtk_tree_model_get(GTK_TREE_MODEL(user_store_model), &iter, WORD_COL, &word, -1); + add_word(dict, word); + g_free(stock_id); + g_free(word); + } + if (!strcmp(stock_id, "gtk-remove")) { + gtk_tree_model_get(GTK_TREE_MODEL(user_store_model), &iter, WORD_COL, &word, -1); + del_word(&dict, word); + g_free(stock_id); + g_free(word); + } + valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(user_store_model), &iter); + } + if (!(fdict = fopen(dictfile, "w"))) + perror(dictfile); + else { + save_dict(fdict, dict); + fclose(fdict); + } + free(dict_words.by_az); + dict_words = get_sorted(dict); + gtk_widget_destroy(GTK_WIDGET(dict_win)); +} @@ -10,11 +10,11 @@ * * WordExtract is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with WordExtract. If not, see <http://www.gnu.org/licenses/>. + * along with WordExtract. If not, see <http://www.gnu.org/licenses/>. */ #ifndef DICTWIN_H diff --git a/engparser.c b/engparser.c index 098c9fc..af511e5 100644 --- a/engparser.c +++ b/engparser.c @@ -10,11 +10,11 @@ * * WordExtract is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with WordExtract. If not, see <http://www.gnu.org/licenses/>. + * along with WordExtract. If not, see <http://www.gnu.org/licenses/>. */ #include <stdio.h> @@ -23,6 +23,7 @@ #include "mainwin.h" #include "engparser.h" #include "word.h" +#include "dict.h" int lower_first_capital = 1; int excl_w_capital = 1; @@ -51,8 +52,9 @@ int parseengphrase(char *phrase) } } else { - if ((*word != '\0')&&!parse_eng_word(word, quote)&&!parse_eng_word(word, hyphen)) - to_list(word); + if ((*word != '\0')&&!parse_eng_word(word, quote)&& + !parse_eng_word(word, hyphen)&&!is_in_dict(word, dict)) + words = add_word(words, word); sentence_start = sentence_start||(phrase[k] == '.')||(phrase[k] == '!')||(phrase[k] == '?'); for (i = 0; i < WORDLENGTH; i++) word[i] = 0; @@ -98,7 +100,7 @@ int parse_eng_word(char *word, Parseoptions opt) return WORD_NOT_INCLUDED; if (opt.excl_w_middle&&mids) return WORD_NOT_INCLUDED; - if (opt.ecxl_w_ending&&ends&&!symbolled) + if (opt.excl_w_ending&&ends&&!symbolled) return WORD_NOT_INCLUDED; return WORD_INCLUDED; } diff --git a/engparser.h b/engparser.h index 241ef4c..ac0c4b0 100644 --- a/engparser.h +++ b/engparser.h @@ -10,11 +10,11 @@ * * WordExtract is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with WordExtract. If not, see <http://www.gnu.org/licenses/>. + * along with WordExtract. If not, see <http://www.gnu.org/licenses/>. */ #ifndef ENG_PARSER_H @@ -28,7 +28,7 @@ typedef struct { int excl_symbolled; int excl_w_starting; int excl_w_middle; - int ecxl_w_ending; + int excl_w_ending; int excl_word_after_symb; } Parseoptions; diff --git a/interface.c b/interface.c deleted file mode 100644 index ef0b732..0000000 --- a/interface.c +++ /dev/null @@ -1,383 +0,0 @@ -/* This file is a part of WordExtract project - * - * Copyright (C) 2009 Borisov Alexandr - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#include <stdlib.h> -#include <string.h> -#include <ctype.h> -#include "interface.h" -#include "callbacks.h" -#include "word.h" - -static GtkWidget *gtk_button_new_with_label_and_image(gchar *img_file, gchar *label); - -static GtkWidget *sentences_text; -static GtkWidget *find_label; -static GtkWidget *find_entry; -static GtkWidget *prev_btn; -static GtkWidget *next_btn; -static GtkWidget *clear_btn; -static GtkWidget *statusbar; -static int current_highlighted_end; -static int current_highlighted_start; -static gboolean gtk_text_iter_search_word(const GtkTextIter *, const gchar *str, - GtkTextSearchFlags, GtkTextIter *, - GtkTextIter *, const GtkTextIter *, int); - -void create_main_window() -{ - main_window = gtk_window_new(GTK_WINDOW_TOPLEVEL); - gtk_widget_set_size_request(main_window, 640, 480); - gtk_container_set_border_width(GTK_CONTAINER(main_window), 2); - gtk_window_set_title(GTK_WINDOW(main_window), "WordExtract"); - gtk_window_set_position(GTK_WINDOW(main_window), GTK_WIN_POS_CENTER); - g_signal_connect(G_OBJECT(main_window), "delete_event", G_CALLBACK(main_window_close), (gpointer) main_window); - g_signal_connect(G_OBJECT(main_window), "destroy", G_CALLBACK(main_window_destroy), NULL); - - GtkWidget *vbox; - vbox = gtk_vbox_new(FALSE, 0); - gtk_widget_show(vbox); - gtk_container_add(GTK_CONTAINER(main_window), vbox); - gtk_container_set_border_width(GTK_CONTAINER(vbox), 2); - - GtkWidget *tool_hbox; - tool_hbox = gtk_hbox_new(FALSE, 0); - gtk_box_pack_start(GTK_BOX(vbox), tool_hbox, FALSE, FALSE, 0); - gtk_widget_show(tool_hbox); - - GtkWidget *open_btn; - open_btn = gtk_button_new_from_stock(GTK_STOCK_OPEN); - gtk_box_pack_start(GTK_BOX(tool_hbox), open_btn, FALSE, FALSE, 0); - gtk_widget_set_tooltip_text(GTK_WIDGET(open_btn), "Open file to pick up words"); - gtk_widget_show(open_btn); - g_signal_connect(G_OBJECT(open_btn), "clicked", G_CALLBACK(open_btn_click), NULL); - - GtkWidget *save_btn; - save_btn = gtk_button_new_from_stock(GTK_STOCK_SAVE_AS); - gtk_box_pack_start(GTK_BOX(tool_hbox), save_btn, FALSE, FALSE, 0); - gtk_widget_set_tooltip_text(GTK_WIDGET(save_btn), "Save list of words to file"); - gtk_widget_show(save_btn); - - GtkWidget *preferences_btn; - preferences_btn = gtk_button_new_from_stock(GTK_STOCK_PREFERENCES); - gtk_box_pack_start (GTK_BOX (tool_hbox), preferences_btn, FALSE, FALSE, 0); - gtk_widget_set_tooltip_text(GTK_WIDGET(preferences_btn), "Application and analizing options"); - gtk_widget_show (preferences_btn); - - GtkWidget *dict_btn; - dict_btn = gtk_button_new_with_label_and_image("gtk-edit", "Dictionary"); - gtk_box_pack_start(GTK_BOX(tool_hbox), dict_btn, FALSE, FALSE, 0); - gtk_widget_set_tooltip_text(GTK_WIDGET(dict_btn), "View words in dictionary"); - gtk_widget_show(dict_btn); - - GtkWidget *quit_btn; - quit_btn = gtk_button_new_from_stock(GTK_STOCK_QUIT); - gtk_box_pack_end(GTK_BOX(tool_hbox), quit_btn, FALSE, FALSE, 0); - gtk_widget_show (quit_btn); - gtk_widget_set_tooltip_text(GTK_WIDGET(quit_btn), "Close this application"); - g_signal_connect(G_OBJECT(quit_btn), "clicked", G_CALLBACK(quit_btn_click), (gpointer) main_window); - - GtkWidget *about_btn; - about_btn = gtk_button_new_from_stock(GTK_STOCK_ABOUT); - gtk_box_pack_end(GTK_BOX(tool_hbox), about_btn, FALSE, FALSE, 0); - gtk_widget_set_tooltip_text(GTK_WIDGET(about_btn), "About this application"); - gtk_widget_show(about_btn); - g_signal_connect(G_OBJECT(about_btn), "clicked", G_CALLBACK(show_about), NULL); - - GtkWidget *hpaned; - hpaned = gtk_hpaned_new(); - gtk_box_pack_start(GTK_BOX(vbox), hpaned, TRUE, TRUE, 0); - gtk_paned_set_position(GTK_PANED(hpaned), 200); - gtk_widget_show(hpaned); - - GtkWidget *word_sc_win; - word_sc_win = gtk_scrolled_window_new(NULL, NULL); - gtk_paned_add1(GTK_PANED(hpaned), word_sc_win); - gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(word_sc_win), GTK_SHADOW_IN); - gtk_widget_show(word_sc_win); - - GtkWidget *list; - list = create_word_list(); - gtk_container_add(GTK_CONTAINER(word_sc_win), list); - gtk_widget_show(list); - - GtkWidget *text_vbox; - text_vbox = gtk_vbox_new(FALSE, 0); - gtk_paned_add2(GTK_PANED(hpaned), text_vbox); - gtk_container_set_border_width(GTK_CONTAINER(text_vbox), 2); - gtk_widget_show(text_vbox); - - GtkWidget *sentences_sc_win; - sentences_sc_win = gtk_scrolled_window_new(NULL, NULL); - gtk_box_pack_start(GTK_BOX(text_vbox), sentences_sc_win, TRUE, TRUE, 0); - gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sentences_sc_win), GTK_SHADOW_IN); - gtk_widget_show(sentences_sc_win); - - GtkTextBuffer *buffer; - sentences_text = gtk_text_view_new(); - buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(sentences_text)); - gtk_text_view_set_editable(GTK_TEXT_VIEW(sentences_text), FALSE); - gtk_text_buffer_create_tag(buffer, "yellow-bg", "background", "yellow", NULL); - gtk_text_buffer_create_tag(buffer, "green-bg", "background", "green", NULL); - gtk_container_add(GTK_CONTAINER(sentences_sc_win), sentences_text); - gtk_widget_show(sentences_text); - - GtkWidget *text_hbox; - text_hbox = gtk_hbox_new(FALSE, 0); - gtk_box_pack_end(GTK_BOX(text_vbox), text_hbox, FALSE, FALSE, 0); - gtk_widget_show(text_hbox); - - find_label = gtk_label_new("Find: "); - gtk_box_pack_start(GTK_BOX(text_hbox), find_label, FALSE, FALSE, 0); - gtk_widget_set_sensitive(GTK_WIDGET(find_label), FALSE); - gtk_widget_show(find_label); - - find_entry = gtk_entry_new_with_max_length(WORDLENGTH); - gtk_box_pack_start(GTK_BOX(text_hbox), find_entry, FALSE, FALSE, 0); - gtk_widget_set_sensitive(GTK_WIDGET(find_entry), FALSE); - g_signal_connect(G_OBJECT(find_entry), "activate", G_CALLBACK(on_find_text_change), NULL); - gtk_widget_show(find_entry); - - GtkWidget *image; - - prev_btn = gtk_button_new(); - image = gtk_image_new_from_stock(GTK_STOCK_GO_BACK, GTK_ICON_SIZE_BUTTON); - gtk_container_add(GTK_CONTAINER(prev_btn), image); - gtk_widget_show(image); - gtk_box_pack_start(GTK_BOX(text_hbox), prev_btn, FALSE, FALSE, 0); - gtk_widget_set_tooltip_text(GTK_WIDGET(prev_btn), "Previous sentence"); - gtk_widget_set_sensitive(GTK_WIDGET(prev_btn), FALSE); - g_signal_connect(G_OBJECT(prev_btn), "clicked", G_CALLBACK(find_prev_btn_click), (gpointer) find_entry); - gtk_widget_show(prev_btn); - - next_btn = gtk_button_new(); - image = gtk_image_new_from_stock(GTK_STOCK_GO_FORWARD, GTK_ICON_SIZE_BUTTON); - gtk_container_add(GTK_CONTAINER(next_btn), image); - gtk_widget_show(image); - gtk_box_pack_start(GTK_BOX(text_hbox), next_btn, FALSE, FALSE, 0); - gtk_widget_set_tooltip_text(GTK_WIDGET(next_btn), "Next sentence"); - gtk_widget_set_sensitive(GTK_WIDGET(next_btn), FALSE); - g_signal_connect(G_OBJECT(next_btn), "clicked", G_CALLBACK(find_next_btn_click), (gpointer) find_entry); - gtk_widget_show(next_btn); - - clear_btn = gtk_button_new(); - image = gtk_image_new_from_stock(GTK_STOCK_CLEAR, GTK_ICON_SIZE_BUTTON); - gtk_container_add(GTK_CONTAINER(clear_btn), image); - gtk_widget_show(image); - gtk_box_pack_start(GTK_BOX(text_hbox), clear_btn, FALSE, FALSE, 0); - gtk_widget_set_tooltip_text(GTK_WIDGET(clear_btn), "Cleanup highlighting"); - gtk_widget_set_sensitive(GTK_WIDGET(clear_btn), FALSE); - g_signal_connect(G_OBJECT(clear_btn), "clicked", G_CALLBACK(clear_btn_click), (gpointer) find_entry); - gtk_widget_show(clear_btn); - - statusbar = gtk_statusbar_new(); - gtk_box_pack_start(GTK_BOX(vbox), statusbar, FALSE, FALSE, 0); - gtk_widget_show(statusbar); -} - -static GtkWidget *gtk_button_new_with_label_and_image(gchar *img_name, gchar *label_text) -{ - GtkWidget *button; - GtkWidget *box; - GtkWidget *label; - GtkWidget *image; - - button = gtk_button_new(); - - box = gtk_hbox_new(FALSE, 2); - gtk_container_add(GTK_CONTAINER(button), box); - - image = gtk_image_new_from_stock(img_name, GTK_ICON_SIZE_BUTTON); - gtk_box_pack_start(GTK_BOX(box), image, FALSE, FALSE, 0); - - label = gtk_label_new_with_mnemonic(label_text); - gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 0); - - gtk_widget_show(image); - gtk_widget_show(label); - gtk_widget_show(box); - - return button; -} - -void add_sentence(char *sentence) -{ - GtkTextBuffer *buffer; - GtkTextIter iter; - - buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(sentences_text)); - gtk_text_buffer_get_end_iter(buffer, &iter); - gtk_text_buffer_insert(buffer, &iter, (gchar*) sentence, -1); -} - -void clear_sentences() -{ - GtkTextBuffer *buffer; - gchar text[] = "\0"; - - buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(sentences_text)); - gtk_text_buffer_set_text(buffer, text, -1); -} - -void search_sentences(const gchar *word) -{ - GtkTextBuffer *buffer; - GtkTextIter find_start, find_end; - GtkTextIter match_start, match_end; - int offset; - - buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(sentences_text)); - gtk_text_buffer_get_start_iter(buffer, &find_start); - gtk_text_buffer_get_end_iter(buffer, &find_end); - gtk_text_buffer_remove_tag_by_name(buffer, "green-bg", &find_start, &find_end); - gtk_text_buffer_remove_tag_by_name(buffer, "yellow-bg", &find_start, &find_end); - while (gtk_text_iter_search_word(&find_start, word, GTK_TEXT_SEARCH_TEXT_ONLY| - GTK_TEXT_SEARCH_VISIBLE_ONLY, &match_start, - &match_end, NULL, SEARCH_FORWARD)) { - gtk_text_buffer_apply_tag_by_name(buffer, "yellow-bg", &match_start, &match_end); - offset = gtk_text_iter_get_offset(&match_end); - gtk_text_buffer_get_iter_at_offset(buffer, &find_start, offset); - } - gtk_text_buffer_get_start_iter(buffer, &find_start); - gtk_text_buffer_get_end_iter(buffer, &find_end); - if (gtk_text_iter_search_word(&find_start, word, GTK_TEXT_SEARCH_TEXT_ONLY| - GTK_TEXT_SEARCH_VISIBLE_ONLY, &match_start, - &match_end, NULL, SEARCH_FORWARD)) { - gtk_text_buffer_apply_tag_by_name(buffer, "green-bg", &match_start, &match_end); - current_highlighted_end = gtk_text_iter_get_offset(&match_end); - current_highlighted_start = gtk_text_iter_get_offset(&match_start); - gtk_text_view_scroll_to_iter(GTK_TEXT_VIEW(sentences_text), &match_start, 0.0, TRUE, 0.5, 0.5); - } -} - -void enable_search() -{ - gtk_widget_set_sensitive(GTK_WIDGET(find_label), TRUE); - gtk_widget_set_sensitive(GTK_WIDGET(find_entry), TRUE); -} - -void change_search_navigation_state(gboolean state) -{ - gtk_widget_set_sensitive(GTK_WIDGET(prev_btn), state); - gtk_widget_set_sensitive(GTK_WIDGET(next_btn), state); - gtk_widget_set_sensitive(GTK_WIDGET(clear_btn), state); -} - -void set_find_text(gchar *text) -{ - gtk_entry_set_text(GTK_ENTRY(find_entry), text); -} - -void clear_search_tags() -{ - GtkTextBuffer *buffer; - GtkTextIter find_start, find_end; - - buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(sentences_text)); - gtk_text_buffer_get_start_iter(buffer, &find_start); - gtk_text_buffer_get_end_iter(buffer, &find_end); - gtk_text_buffer_remove_tag_by_name(buffer, "yellow-bg", &find_start, &find_end); - gtk_text_buffer_remove_tag_by_name(buffer, "green-bg", &find_start, &find_end); -} - -/* We won't need this abomination if GTK developers implement - * SEARCH_CASE_INSENSITIVE flag in GtkTextSearchFlags struct - * which is in their TODO list - */ -gboolean gtk_text_iter_search_word(const GtkTextIter *iter, const gchar *str, - GtkTextSearchFlags flags, GtkTextIter *match_start, - GtkTextIter *match_end, const GtkTextIter *limit, - const int direction) -{ - GtkTextIter match_start_wcap, match_end_wcap; - gboolean result = FALSE; - int offset, offset_wcap; - gchar *str_wcap; - - str_wcap = malloc((strlen(str)+1)*sizeof(gchar)); - strcpy(str_wcap, str); - /* We've lowered only first letter, so there are only two variants*/ - *str_wcap = toupper(*str_wcap); - if (direction == SEARCH_FORWARD) { - if (gtk_text_iter_forward_search(iter, str, flags, match_start, match_end, limit)) - offset = gtk_text_iter_get_offset(match_start); - else - offset = -1; - if (gtk_text_iter_forward_search(iter, str_wcap, flags, &match_start_wcap, &match_end_wcap, limit)) - offset_wcap = gtk_text_iter_get_offset(&match_start_wcap); - else - offset_wcap = -1; - if (((offset_wcap < offset)||(offset == -1))&&(offset_wcap != -1)) { - *match_start = match_start_wcap; - *match_end = match_end_wcap; - } - } else if (direction == SEARCH_BACKWARD) { - if (gtk_text_iter_backward_search(iter, str, flags, match_start, match_end, limit)) - offset = gtk_text_iter_get_offset(match_start); - else - offset = -1; - if (gtk_text_iter_backward_search(iter, str_wcap, flags, &match_start_wcap, &match_end_wcap, limit)) - offset_wcap = gtk_text_iter_get_offset(&match_start_wcap); - else - offset_wcap = -1; - if (offset < offset_wcap) { - *match_start = match_start_wcap; - *match_end = match_end_wcap; - } - } - free(str_wcap); - if ((offset_wcap != -1)||(offset != -1)) - result = TRUE; - return result; -} - -void find_other(const gchar *word, const int direction) -{ - GtkTextBuffer *buffer; - GtkTextIter find_start, find_end; - GtkTextIter match_start, match_end; - - buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(sentences_text)); - gtk_text_buffer_get_start_iter(buffer, &find_start); - gtk_text_buffer_get_end_iter(buffer, &find_end); - gtk_text_buffer_remove_tag_by_name(buffer, "green-bg", &find_start, &find_end); - if (direction == SEARCH_FORWARD) { - gtk_text_buffer_get_iter_at_offset(buffer, &find_start, current_highlighted_end); - } else if (direction == SEARCH_BACKWARD) { - gtk_text_buffer_get_iter_at_offset(buffer, &find_start, current_highlighted_start); - } - if (gtk_text_iter_search_word(&find_start, word, GTK_TEXT_SEARCH_TEXT_ONLY| - GTK_TEXT_SEARCH_VISIBLE_ONLY, &match_start, - &match_end, NULL, direction)) { - gtk_text_buffer_apply_tag_by_name(buffer, "green-bg", &match_start, &match_end); - current_highlighted_start = gtk_text_iter_get_offset(&match_start); - current_highlighted_end = gtk_text_iter_get_offset(&match_end); - gtk_text_view_scroll_to_iter(GTK_TEXT_VIEW(sentences_text), &match_start, 0.0, TRUE, 0.5, 0.5); - } else { - if (direction == SEARCH_FORWARD) { - gtk_text_buffer_get_end_iter(buffer, &find_end); - current_highlighted_start = gtk_text_iter_get_offset(&find_end); - current_highlighted_end = gtk_text_iter_get_offset(&find_end); - } else if (direction == SEARCH_BACKWARD) { - gtk_text_buffer_get_start_iter(buffer, &find_start); - current_highlighted_start = gtk_text_iter_get_offset(&find_start); - current_highlighted_end = gtk_text_iter_get_offset(&find_start); - } - } -} - - diff --git a/interface.h b/interface.h deleted file mode 100644 index 6fc00aa..0000000 --- a/interface.h +++ /dev/null @@ -1,41 +0,0 @@ -/* This file is a part of WordExtract project - * - * Copyright (C) 2009 Borisov Alexandr - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef INTERFACE_H -#define INTERFACE_H - -#include <gtk/gtk.h> -#include "listview.h" - -#define SEARCH_FORWARD 0 -#define SEARCH_BACKWARD 1 - -GtkWidget *main_window; -void create_main_window(); -void add_sentence(char *); -void clear_sentences(); -void search_sentences(const gchar *); -void enable_search(); -void change_search_navigation_state(gboolean); -void set_find_text(gchar *); -void clear_search_tags(); -void find_next(const gchar *word); -void find_prev(const gchar *word); -void find_other(const gchar *word, const int direction); - -#endif /*INTERFACE_H*/ @@ -10,11 +10,11 @@ * * WordExtract is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with WordExtract. If not, see <http://www.gnu.org/licenses/>. + * along with WordExtract. If not, see <http://www.gnu.org/licenses/>. */ #include <stdio.h> @@ -24,14 +24,17 @@ #include "mainwin.h" #include "dict.h" +Language lang; +SaveOpt save_user_words = {2, 40}; char optpath[PATH_LENGTH] = {0}; char dictfile[PATH_LENGTH] = {0}; -Language lang; static void fill_vars(); int main(int argc, char *argv[]) { + FILE *fdict; + gtk_init(&argc, &argv); fill_vars(); dict = load_dict(); @@ -39,7 +42,25 @@ int main(int argc, char *argv[]) create_main_window(); gtk_widget_show(main_window); gtk_main(); - free_words(dict); /*Where to put?*/ + + /*termination*/ + if (!(fdict = fopen(dictfile, "w"))) + perror(dictfile); + else { + save_dict(fdict, dict); + fclose(fdict); + } + if (dict_words.by_az) + free(dict_words.by_az); + if (user_words.by_az) + free(user_words.by_az); + if (dict) { + if (dict->lsibl) + free_words(dict->lsibl); + if (dict->rsibl) + free_words(dict->rsibl); + free(dict->word); + } return 0; } @@ -32,8 +32,14 @@ #define MAXPHRASE 100 typedef enum {ENG} Language; +typedef struct { + unsigned int columns; + unsigned int col_width; +} SaveOpt; +/*application settings*/ extern Language lang; +extern SaveOpt save_user_words; extern char optpath[PATH_LENGTH]; extern char dictfile[PATH_LENGTH]; @@ -10,20 +10,24 @@ * * WordExtract is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with WordExtract. If not, see <http://www.gnu.org/licenses/>. + * along with WordExtract. If not, see <http://www.gnu.org/licenses/>. */ +#include <gdk/gdkkeysyms.h> #include <stdlib.h> +#include <libgen.h> #include <string.h> #include <ctype.h> #include "mainwin.h" #include "dictwin.h" #include "confwin.h" +#include "main.h" #include "word.h" +#include "dict.h" #include "srt.h" #define SEARCH_FORWARD 0 @@ -39,6 +43,7 @@ enum {WORD_ITEM = 0, N_COLUMNS}; GtkWidget *main_window; static GtkWidget *sentences_text; +static GtkWidget *find_btn; static GtkWidget *prev_btn; static GtkWidget *next_btn; static GtkWidget *clear_btn; @@ -51,14 +56,18 @@ static GtkWidget *save_item; static GtkToolItem *save; static GtkWidget *find_label; static GtkWidget *find_entry; -/*vars to controll current word highlighting (green)*/ +/*vars to control current word highlighting (green)*/ static int current_highlighted_end; static int current_highlighted_start; +/*statusbar context id*/ +static guint id, find_id; +static void set_status_msg(); static gint main_window_close(GtkWidget *, GdkEvent *, gpointer); static void main_window_destroy(GtkWidget *, gpointer); static void open_item_click(GtkWidget *, gpointer); -static void save_item_click(GtkWidget *, gpointer); +static void save_words_item_click(GtkWidget *, gpointer); +static void save_text_item_click(GtkWidget *, gpointer); static void quit_item_click(GtkWidget *, gpointer); static void dict_item_click(GtkWidget *, gpointer); static void pref_item_click(GtkWidget *, gpointer); @@ -70,6 +79,7 @@ static void show_sent_item_click(GtkWidget *, gpointer ); static void add_to_dict_item_click(GtkWidget *, gpointer ); static void fill_list(char **); static void change_search_navigation_state(gboolean); +static gboolean find_entry_key_press(GtkWidget *, GdkEventKey *, gpointer); static void on_find_text_change(GtkWidget *, gpointer); static void find_prev_btn_click(GtkWidget *, gpointer); static void find_next_btn_click(GtkWidget *, gpointer); @@ -77,7 +87,7 @@ static void clear_btn_click(GtkWidget *, gpointer); static void search_sentences(const gchar *); static void set_find_text(gchar *); static void clear_search_tags(); -static gboolean gtk_text_iter_search_word(const GtkTextIter *, const gchar *str, +static gboolean gtk_text_iter_search_word(const GtkTextIter *, const gchar *, GtkTextSearchFlags, GtkTextIter *, GtkTextIter *, const GtkTextIter *, int); static void find_other(const gchar *, const int); @@ -91,33 +101,35 @@ void create_main_window() g_signal_connect(G_OBJECT(main_window), "delete_event", G_CALLBACK(main_window_close), (gpointer) main_window); g_signal_connect(G_OBJECT(main_window), "destroy", G_CALLBACK(main_window_destroy), NULL); - GtkWidget *vbox; - vbox = gtk_vbox_new(FALSE, 2); + GtkWidget *vbox = gtk_vbox_new(FALSE, 2); gtk_widget_show(vbox); gtk_container_add(GTK_CONTAINER(main_window), vbox); - GtkWidget *menu_bar; - GtkWidget *view_menu; - GtkWidget *help_menu; - GtkWidget *sep_item; - menu_bar = gtk_menu_bar_new(); - sep_item = gtk_separator_menu_item_new(); - - GtkWidget *file_menu; - GtkWidget *file_item; - GtkWidget *open_item; - GtkWidget *quit_item; - file_menu = gtk_menu_new(); - file_item = gtk_menu_item_new_with_mnemonic("_File"); - open_item = gtk_image_menu_item_new_from_stock(GTK_STOCK_OPEN, NULL); - gtk_widget_set_tooltip_text(GTK_WIDGET(open_item), "Open file to analize"); + GtkWidget *menu_bar = gtk_menu_bar_new(); + GtkWidget *sep_item = gtk_separator_menu_item_new(); + GtkWidget *file_menu = gtk_menu_new(); + GtkWidget *file_item = gtk_menu_item_new_with_mnemonic("_File"); + + GtkWidget *open_item = gtk_image_menu_item_new_from_stock(GTK_STOCK_OPEN, NULL); + gtk_widget_set_tooltip_text(GTK_WIDGET(open_item), "Open file to analyse"); g_signal_connect(G_OBJECT(open_item), "activate", G_CALLBACK(open_item_click), NULL); - save_item = gtk_image_menu_item_new_from_stock(GTK_STOCK_SAVE, NULL); - gtk_widget_set_has_tooltip(GTK_WIDGET(save_item), FALSE); - gtk_widget_set_tooltip_text(GTK_WIDGET(save_item), "Save list of words to file"); + save_item = gtk_image_menu_item_new_from_stock(GTK_STOCK_SAVE_AS, NULL); gtk_widget_set_sensitive(GTK_WIDGET(save_item), FALSE); - g_signal_connect(G_OBJECT(save_item), "activate", G_CALLBACK(save_item_click), NULL); - quit_item = gtk_image_menu_item_new_from_stock(GTK_STOCK_QUIT, NULL); + GtkWidget *save_menu = gtk_menu_new(); + GtkWidget *save_words_img = gtk_image_new_from_stock(GTK_STOCK_SAVE_AS, GTK_ICON_SIZE_MENU); + GtkWidget *save_words_item = gtk_image_menu_item_new_with_label("Words"); + gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(save_words_item), save_words_img); + gtk_widget_set_tooltip_text(GTK_WIDGET(save_words_item), "Save list of words to file"); + g_signal_connect(G_OBJECT(save_words_item), "activate", G_CALLBACK(save_words_item_click), NULL); + GtkWidget *save_text_img = gtk_image_new_from_stock(GTK_STOCK_SAVE_AS, GTK_ICON_SIZE_MENU); + GtkWidget *save_text_item = gtk_image_menu_item_new_with_label("Text"); + gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(save_text_item), save_text_img); + gtk_widget_set_tooltip_text(GTK_WIDGET(save_text_item), "Save text from which words were picked up"); + g_signal_connect(G_OBJECT(save_text_item), "activate", G_CALLBACK(save_text_item_click), NULL); + gtk_menu_item_set_submenu(GTK_MENU_ITEM(save_item), save_menu); + gtk_menu_shell_append(GTK_MENU_SHELL(save_menu), save_words_item); + gtk_menu_shell_append(GTK_MENU_SHELL(save_menu), save_text_item); + GtkWidget *quit_item = gtk_image_menu_item_new_from_stock(GTK_STOCK_QUIT, NULL); gtk_widget_set_tooltip_text(GTK_WIDGET(quit_item), "Close the program"); g_signal_connect(G_OBJECT(quit_item), "activate", G_CALLBACK(quit_item_click), NULL); gtk_menu_item_set_submenu(GTK_MENU_ITEM(file_item), file_menu); @@ -128,33 +140,25 @@ void create_main_window() gtk_menu_shell_append(GTK_MENU_SHELL(menu_bar), file_item); gtk_widget_show_all(file_item); - GtkWidget *view_item; - GtkWidget *dict_item; - GtkWidget *edit_img; - GtkWidget *pref_item; - view_menu = gtk_menu_new(); - view_item = gtk_menu_item_new_with_mnemonic("_View"); - - dict_item = gtk_image_menu_item_new_with_label("Dictionary"); + GtkWidget *edit_menu = gtk_menu_new(); + GtkWidget *edit_item = gtk_menu_item_new_with_mnemonic("_Edit"); + GtkWidget *dict_item = gtk_image_menu_item_new_with_label("Dictionary"); gtk_widget_set_tooltip_text(GTK_WIDGET(dict_item), "View and edit your dictionary"); - edit_img = gtk_image_new_from_stock(GTK_STOCK_EDIT, GTK_ICON_SIZE_MENU); + GtkWidget *edit_img = gtk_image_new_from_stock(GTK_STOCK_EDIT, GTK_ICON_SIZE_MENU); gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(dict_item), edit_img); g_signal_connect(G_OBJECT(dict_item), "activate", G_CALLBACK(dict_item_click), NULL); - - pref_item = gtk_image_menu_item_new_from_stock(GTK_STOCK_PREFERENCES, NULL); + GtkWidget *pref_item = gtk_image_menu_item_new_from_stock(GTK_STOCK_PREFERENCES, NULL); gtk_widget_set_tooltip_text(GTK_WIDGET(pref_item), "Change application settings"); g_signal_connect(G_OBJECT(pref_item), "activate", G_CALLBACK(pref_item_click), NULL); - gtk_menu_item_set_submenu(GTK_MENU_ITEM(view_item), view_menu); - gtk_menu_shell_append(GTK_MENU_SHELL(view_menu), dict_item); - gtk_menu_shell_append(GTK_MENU_SHELL(view_menu), pref_item); - gtk_menu_shell_append(GTK_MENU_SHELL(menu_bar), view_item); - gtk_widget_show_all(view_item); - - GtkWidget *help_item; - GtkWidget *about_item; - help_menu = gtk_menu_new(); - help_item = gtk_menu_item_new_with_mnemonic("_Help"); - about_item = gtk_image_menu_item_new_from_stock(GTK_STOCK_ABOUT, NULL); + gtk_menu_item_set_submenu(GTK_MENU_ITEM(edit_item), edit_menu); + gtk_menu_shell_append(GTK_MENU_SHELL(edit_menu), dict_item); + gtk_menu_shell_append(GTK_MENU_SHELL(edit_menu), pref_item); + gtk_menu_shell_append(GTK_MENU_SHELL(menu_bar), edit_item); + gtk_widget_show_all(edit_item); + + GtkWidget *help_menu = gtk_menu_new(); + GtkWidget *help_item = gtk_menu_item_new_with_mnemonic("_Help"); + GtkWidget *about_item = gtk_image_menu_item_new_from_stock(GTK_STOCK_ABOUT, NULL); gtk_widget_set_tooltip_text(GTK_WIDGET(about_item), "About the program"); g_signal_connect(G_OBJECT(about_item), "activate", G_CALLBACK(about_item_click), NULL); gtk_menu_item_set_submenu(GTK_MENU_ITEM(help_item), help_menu); @@ -165,53 +169,44 @@ void create_main_window() gtk_box_pack_start(GTK_BOX(vbox), menu_bar, FALSE, FALSE, 2); gtk_widget_show(menu_bar); - GtkWidget *toolbar; - toolbar = gtk_toolbar_new(); + GtkWidget *toolbar = gtk_toolbar_new(); gtk_toolbar_set_style(GTK_TOOLBAR(toolbar), GTK_TOOLBAR_ICONS); - GtkToolItem *open; - open = gtk_tool_button_new_from_stock(GTK_STOCK_OPEN); - gtk_widget_set_tooltip_text(GTK_WIDGET(open), "Open file to analize"); + GtkToolItem *open = gtk_tool_button_new_from_stock(GTK_STOCK_OPEN); + gtk_widget_set_tooltip_text(GTK_WIDGET(open), "Open file to analyse"); g_signal_connect(G_OBJECT(open), "clicked", G_CALLBACK(open_item_click), NULL); gtk_toolbar_insert(GTK_TOOLBAR(toolbar), open, -1); save = gtk_tool_button_new_from_stock(GTK_STOCK_SAVE); gtk_widget_set_has_tooltip(GTK_WIDGET(save), FALSE); gtk_widget_set_tooltip_text(GTK_WIDGET(save), "Save list of words to file"); gtk_widget_set_sensitive(GTK_WIDGET(save), FALSE); - g_signal_connect(G_OBJECT(save), "clicked", G_CALLBACK(save_item_click), NULL); + g_signal_connect(G_OBJECT(save), "clicked", G_CALLBACK(save_words_item_click), NULL); gtk_toolbar_insert(GTK_TOOLBAR(toolbar), save, -1); - GtkToolItem *tool_sep1; - tool_sep1 = gtk_separator_tool_item_new(); + GtkToolItem *tool_sep1 = gtk_separator_tool_item_new(); gtk_toolbar_insert(GTK_TOOLBAR(toolbar), tool_sep1, -1); - GtkToolItem *dict; - dict = gtk_tool_button_new_from_stock(GTK_STOCK_EDIT); + GtkToolItem *dict = gtk_tool_button_new_from_stock(GTK_STOCK_EDIT); gtk_widget_set_tooltip_text(GTK_WIDGET(dict), "View and edit your dictionary"); g_signal_connect(G_OBJECT(dict), "clicked", G_CALLBACK(dict_item_click), NULL); gtk_toolbar_insert(GTK_TOOLBAR(toolbar), dict, -1); - GtkToolItem *tool_sep2; - tool_sep2 = gtk_separator_tool_item_new(); + GtkToolItem *tool_sep2 = gtk_separator_tool_item_new(); gtk_toolbar_insert(GTK_TOOLBAR(toolbar), tool_sep2, -1); - GtkToolItem *quit; - quit = gtk_tool_button_new_from_stock(GTK_STOCK_QUIT); + GtkToolItem *quit = gtk_tool_button_new_from_stock(GTK_STOCK_QUIT); gtk_widget_set_tooltip_text(GTK_WIDGET(quit), "Close the program"); g_signal_connect(G_OBJECT(quit), "clicked", G_CALLBACK(quit_item_click), NULL); gtk_toolbar_insert(GTK_TOOLBAR(toolbar), quit, -1); gtk_box_pack_start(GTK_BOX(vbox), toolbar, FALSE, FALSE, 2); gtk_widget_show_all(toolbar); - GtkWidget *hpaned; - hpaned = gtk_hpaned_new(); + GtkWidget *hpaned = gtk_hpaned_new(); gtk_box_pack_start(GTK_BOX(vbox), hpaned, TRUE, TRUE, 0); gtk_paned_set_position(GTK_PANED(hpaned), 200); gtk_widget_show(hpaned); - GtkWidget *word_sc_win; - word_sc_win = gtk_scrolled_window_new(NULL, NULL); + GtkWidget *word_sc_win = gtk_scrolled_window_new(NULL, NULL); + gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(word_sc_win), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_paned_add1(GTK_PANED(hpaned), word_sc_win); gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(word_sc_win), GTK_SHADOW_IN); gtk_widget_show(word_sc_win); - GtkCellRenderer *renderer; - GtkTreeViewColumn *column; word_list = gtk_tree_view_new(); gtk_tree_selection_set_mode(gtk_tree_view_get_selection(GTK_TREE_VIEW(word_list)), GTK_SELECTION_SINGLE); gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(word_list), FALSE); @@ -220,36 +215,34 @@ void create_main_window() g_signal_connect(G_OBJECT(word_list), "popup-menu", G_CALLBACK(popup_by_keybd), NULL); store_model = gtk_list_store_new(N_COLUMNS, G_TYPE_STRING); gtk_tree_view_set_model(GTK_TREE_VIEW(word_list), GTK_TREE_MODEL(store_model)); - renderer = gtk_cell_renderer_text_new(); + g_object_unref(store_model); + GtkCellRenderer *renderer = gtk_cell_renderer_text_new(); g_object_set(renderer, "editable", TRUE, NULL); - column = gtk_tree_view_column_new_with_attributes("List Items", renderer, "text", WORD_ITEM, NULL); + GtkTreeViewColumn *column = gtk_tree_view_column_new_with_attributes("List Items", renderer, "text", WORD_ITEM, NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(word_list), column); gtk_container_add(GTK_CONTAINER(word_sc_win), word_list); gtk_widget_show(word_list); - GtkWidget *text_vbox; - text_vbox = gtk_vbox_new(FALSE, 0); + GtkWidget *text_vbox = gtk_vbox_new(FALSE, 0); gtk_paned_add2(GTK_PANED(hpaned), text_vbox); gtk_container_set_border_width(GTK_CONTAINER(text_vbox), 2); gtk_widget_show(text_vbox); - GtkWidget *sentences_sc_win; - sentences_sc_win = gtk_scrolled_window_new(NULL, NULL); + GtkWidget *sentences_sc_win = gtk_scrolled_window_new(NULL, NULL); + gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sentences_sc_win), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_box_pack_start(GTK_BOX(text_vbox), sentences_sc_win, TRUE, TRUE, 0); gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sentences_sc_win), GTK_SHADOW_IN); gtk_widget_show(sentences_sc_win); - GtkTextBuffer *buffer; sentences_text = gtk_text_view_new(); - buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(sentences_text)); + GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(sentences_text)); gtk_text_view_set_editable(GTK_TEXT_VIEW(sentences_text), FALSE); gtk_text_buffer_create_tag(buffer, "yellow-bg", "background", "yellow", NULL); gtk_text_buffer_create_tag(buffer, "green-bg", "background", "green", NULL); gtk_container_add(GTK_CONTAINER(sentences_sc_win), sentences_text); gtk_widget_show(sentences_text); - GtkWidget *text_hbox; - text_hbox = gtk_hbox_new(FALSE, 0); + GtkWidget *text_hbox = gtk_hbox_new(FALSE, 0); gtk_box_pack_end(GTK_BOX(text_vbox), text_hbox, FALSE, FALSE, 0); gtk_widget_show(text_hbox); @@ -262,9 +255,18 @@ void create_main_window() gtk_box_pack_start(GTK_BOX(text_hbox), find_entry, FALSE, FALSE, 0); gtk_widget_set_sensitive(GTK_WIDGET(find_entry), FALSE); g_signal_connect(G_OBJECT(find_entry), "activate", G_CALLBACK(on_find_text_change), NULL); + g_signal_connect(G_OBJECT(find_entry), "key-press-event", G_CALLBACK(find_entry_key_press), NULL); gtk_widget_show(find_entry); - GtkWidget *image; + find_btn = gtk_button_new(); + GtkWidget *image = gtk_image_new_from_stock(GTK_STOCK_FIND, GTK_ICON_SIZE_BUTTON); + gtk_container_add(GTK_CONTAINER(find_btn), image); + gtk_widget_show(image); + gtk_box_pack_start(GTK_BOX(text_hbox), find_btn, FALSE, FALSE, 0); + gtk_widget_set_tooltip_text(GTK_WIDGET(find_btn), "Find word"); + gtk_widget_set_sensitive(GTK_WIDGET(find_btn), FALSE); + g_signal_connect(G_OBJECT(find_btn), "clicked", G_CALLBACK(on_find_text_change), NULL); + gtk_widget_show(find_btn); prev_btn = gtk_button_new(); image = gtk_image_new_from_stock(GTK_STOCK_GO_BACK, GTK_ICON_SIZE_BUTTON); @@ -298,15 +300,24 @@ void create_main_window() statusbar = gtk_statusbar_new(); gtk_box_pack_start(GTK_BOX(vbox), statusbar, FALSE, FALSE, 0); + id = gtk_statusbar_get_context_id(GTK_STATUSBAR(statusbar), "main_context"); + find_id = gtk_statusbar_get_context_id(GTK_STATUSBAR(statusbar), "find_context"); + gtk_statusbar_push(GTK_STATUSBAR(statusbar), id, "Open file to pick up words from it..."); gtk_widget_show(statusbar); } +static void set_status_msg() +{ + char words_cnt_str[40] = {0}; + sprintf(words_cnt_str, "<b> Words in your dictionary: %d</b>", dict_words.count); + gtk_statusbar_pop(GTK_STATUSBAR(statusbar), find_id); +} + static gint main_window_close(GtkWidget *widget, GdkEvent *event, gpointer main_window) { - GtkWidget *dialog; gint response = TRUE; - dialog = gtk_message_dialog_new(main_window, GTK_DIALOG_DESTROY_WITH_PARENT, + GtkWidget *dialog = gtk_message_dialog_new(main_window, GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO, QUIT_MSG_TEXT); gtk_window_set_title(GTK_WINDOW(dialog), QUIT_MSG_CAPTION); if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_YES) @@ -323,21 +334,17 @@ static void main_window_destroy(GtkWidget *widget, gpointer data) static void open_item_click(GtkWidget *widget, gpointer data) { - GtkWidget *filedialog; - GtkWidget *errmsg; - GtkFileFilter *filter; char *filename; char *errstr; FILE *subtitle; - char **word_list; - filter = gtk_file_filter_new(); + GtkFileFilter *filter = gtk_file_filter_new(); gtk_file_filter_add_mime_type(filter, "application/x-subrip"); gtk_file_filter_set_name(filter, "SubRip subtitles (*srt)"); - filedialog = gtk_file_chooser_dialog_new("Open File for analizing", GTK_WINDOW(main_window), - GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, - GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, - GTK_RESPONSE_ACCEPT, NULL); + GtkWidget *filedialog = gtk_file_chooser_dialog_new("Open File for analysing", + GTK_WINDOW(main_window), GTK_FILE_CHOOSER_ACTION_OPEN, + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, + GTK_RESPONSE_ACCEPT, NULL); gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(filedialog), filter); if (gtk_dialog_run(GTK_DIALOG(filedialog)) == GTK_RESPONSE_ACCEPT) { filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(filedialog)); @@ -346,7 +353,7 @@ static void open_item_click(GtkWidget *widget, gpointer data) errstr = malloc(strlen(filename) + strlen(ERR_READING_FILE)); strcpy(errstr, ERR_READING_FILE); strcat(errstr, filename); - errmsg = gtk_message_dialog_new(GTK_WINDOW(main_window), + GtkWidget *errmsg = gtk_message_dialog_new(GTK_WINDOW(main_window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, errstr); gtk_window_set_title(GTK_WINDOW(errmsg), ERR_MSG_CAPTION); @@ -356,39 +363,41 @@ static void open_item_click(GtkWidget *widget, gpointer data) return ; } if (words != NULL) { - /*we won't free() 'words' variable, it's statical*/ - free_words(words->lsibl); - free_words(words->rsibl); - free(words->word); + free(user_words.by_az); + free_words(words); words = NULL; gtk_list_store_clear(store_model); clear_sentences(); } else { gtk_widget_set_sensitive(GTK_WIDGET(find_label), TRUE); gtk_widget_set_sensitive(GTK_WIDGET(find_entry), TRUE); + gtk_widget_set_sensitive(GTK_WIDGET(find_btn), TRUE); gtk_widget_set_sensitive(GTK_WIDGET(save_item), TRUE); gtk_widget_set_sensitive(GTK_WIDGET(save), TRUE); } process_srt(subtitle); - word_list = get_sorted(words); - fill_list(word_list); - free(word_list); + user_words = get_sorted(words); + fill_list(user_words.by_az); fclose(subtitle); + gchar *file = malloc(strlen(filename)+1); + file = basename(filename); + gchar *status_msg = malloc(strlen(file)+40); + sprintf(status_msg, "%d words were picked up from '%s'", user_words.count, file); + gtk_statusbar_pop(GTK_STATUSBAR(statusbar), id); + gtk_statusbar_push(GTK_STATUSBAR(statusbar), id, status_msg); } gtk_widget_destroy(filedialog); } -static void save_item_click(GtkWidget *widget, gpointer data) +static void save_words_item_click(GtkWidget *widget, gpointer data) { - GtkWidget *filedialog; - GtkWidget *errmsg; FILE *savefile; - char *filename; - char *errstr; + gchar *filename; + gchar *errstr; - filedialog = gtk_file_chooser_dialog_new("Save list of words as...", GTK_WINDOW(main_window), - GTK_FILE_CHOOSER_ACTION_SAVE, GTK_STOCK_CANCEL, - GTK_RESPONSE_CANCEL, GTK_STOCK_SAVE, + GtkWidget *filedialog = gtk_file_chooser_dialog_new("Save list of words as...", + GTK_WINDOW(main_window), GTK_FILE_CHOOSER_ACTION_SAVE, + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, NULL); if (gtk_dialog_run(GTK_DIALOG(filedialog)) == GTK_RESPONSE_ACCEPT) { filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(filedialog)); @@ -397,7 +406,7 @@ static void save_item_click(GtkWidget *widget, gpointer data) errstr = malloc(strlen(filename) + strlen(ERR_SAVING_FILE)); strcpy(errstr, ERR_SAVING_FILE); strcat(errstr, filename); - errmsg = gtk_message_dialog_new(GTK_WINDOW(main_window), + GtkWidget *errmsg = gtk_message_dialog_new(GTK_WINDOW(main_window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, errstr); gtk_window_set_title(GTK_WINDOW(errmsg), ERR_MSG_CAPTION); @@ -406,15 +415,52 @@ static void save_item_click(GtkWidget *widget, gpointer data) free(errstr); return ; } + save_words(savefile, user_words, save_user_words); + fclose(savefile); } gtk_widget_destroy(filedialog); } -static void quit_item_click(GtkWidget *widget, gpointer data) +static void save_text_item_click(GtkWidget *widget, gpointer data) { - GtkWidget *dialog; + FILE *savefile; + gchar *filename; + gchar *errstr; + gchar *text; - dialog = gtk_message_dialog_new(GTK_WINDOW(main_window), GTK_DIALOG_DESTROY_WITH_PARENT, + GtkWidget *filedialog = gtk_file_chooser_dialog_new("Save text as...", + GTK_WINDOW(main_window), GTK_FILE_CHOOSER_ACTION_SAVE, + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_SAVE, + GTK_RESPONSE_ACCEPT, NULL); + if (gtk_dialog_run(GTK_DIALOG(filedialog)) == GTK_RESPONSE_ACCEPT) { + filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(filedialog)); + if (!(savefile = fopen(filename, "w"))) { + gtk_widget_destroy(filedialog); + errstr = malloc(strlen(filename) + strlen(ERR_SAVING_FILE)); + strcpy(errstr, ERR_SAVING_FILE); + strcat(errstr, filename); + GtkWidget *errmsg = gtk_message_dialog_new(GTK_WINDOW(main_window), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, errstr); + gtk_window_set_title(GTK_WINDOW(errmsg), ERR_MSG_CAPTION); + gtk_dialog_run(GTK_DIALOG(errmsg)); + gtk_widget_destroy(errmsg); + return ; + } + GtkTextIter start, end; + GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(sentences_text)); + gtk_text_buffer_get_start_iter(buffer, &start); + gtk_text_buffer_get_end_iter(buffer, &end); + text = gtk_text_buffer_get_text(buffer, &start, &end, FALSE); + fprintf(savefile, text); + fclose(savefile); + } + gtk_widget_destroy(filedialog); +} + +static void quit_item_click(GtkWidget *widget, gpointer data) +{ + GtkWidget *dialog = gtk_message_dialog_new(GTK_WINDOW(main_window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO, QUIT_MSG_TEXT); gtk_window_set_title(GTK_WINDOW(dialog), QUIT_MSG_CAPTION); if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_YES) { @@ -439,16 +485,21 @@ static void about_item_click(GtkWidget *widget, gpointer data) { const gchar comment[] = {"WordExtract is a subtitle parser\n which shows all unique words\n from files."}; const gchar copyright[] = {"Copyright \xc2\xa9 2009 by Borisov Alexandr"}; - const gchar gplv3[] = {"This program is free software: you can redistribute it and/or modify\n" - "it under the terms of the GNU General Public License as published by\n" - "the Free Software Foundation, either version 3 of the License, or\n" - "(at your option) any later version.\n\n" - "This program is distributed in the hope that it will be useful,\n" - "but WITHOUT ANY WARRANTY; without even the implied warranty of\n" - "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" - "GNU General Public License for more details.\n\n" - "You should have received a copy of the GNU General Public License\n" - "along with this program. If not, see <http://www.gnu.org/licenses/>."}; + const gchar gplv3[] = {"WordExtract is free software: you can\n" + "redistribute it and/or modify it under the\n" + "terms of the GNU General Public License as\n" + "published by the Free Software Foundation,\n" + "either version 3 of the License, or (at your\n" + "option) any later version.\n\n" + "WordExtract is distributed in the hope that\n" + "it will be useful, but WITHOUT ANY WARRANTY;\n" + "without even the implied warranty of\n" + "MERCHANTABILITY or FITNESS FOR A PARTICULAR\n" + "PURPOSE. See the GNU General Public License\n" + "for more details.\n\n" + "You should have received a copy of the GNU\n" + "General Public License along with WordExtract.\n" + "If not, see <http://www.gnu.org/licenses/>."}; const gchar *authors[] = {"Borisov Alexandr aka b0ric", NULL}; gtk_show_about_dialog(GTK_WINDOW(main_window), "name", "WordExtract", @@ -465,11 +516,10 @@ static void about_item_click(GtkWidget *widget, gpointer data) static gboolean popup_by_click(GtkWidget *word_list, GdkEventButton *event, gpointer data) { - GtkTreeSelection *selection; GtkTreePath *path; if (event->type == GDK_BUTTON_PRESS && event->button == 3) { - selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(word_list)); + GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(word_list)); if (gtk_tree_selection_get_selected(GTK_TREE_SELECTION(selection), NULL, NULL)) { if (gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(word_list), (gint) event->x, (gint) event->y, &path, NULL, NULL, NULL)) { @@ -491,26 +541,21 @@ static gboolean popup_by_keybd(GtkWidget *word_list, gpointer data) static void word_list_popup(GtkWidget *widget, GdkEventButton *event) { - GtkWidget *popup_menu; - popup_menu = gtk_menu_new(); - GtkWidget *show_sent_item; - show_sent_item = gtk_image_menu_item_new_with_label("Show Sentence"); + GtkWidget *popup_menu = gtk_menu_new(); + GtkWidget *show_sent_item = gtk_image_menu_item_new_with_label("Show Sentence"); gtk_menu_shell_append(GTK_MENU_SHELL(popup_menu), show_sent_item); gtk_widget_show(show_sent_item); g_signal_connect(G_OBJECT(show_sent_item), "activate", G_CALLBACK(show_sent_item_click), NULL); gtk_widget_set_tooltip_text(GTK_WIDGET(show_sent_item), "Show sentenses word appears in"); - GtkWidget *find_image; - find_image = gtk_image_new_from_stock("gtk-find", GTK_ICON_SIZE_MENU); + GtkWidget *find_image = gtk_image_new_from_stock("gtk-find", GTK_ICON_SIZE_MENU); gtk_widget_show(find_image); gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(show_sent_item), find_image); - GtkWidget *add_to_dict_item; - add_to_dict_item = gtk_image_menu_item_new_with_label("Add To Dictionary"); + GtkWidget *add_to_dict_item = gtk_image_menu_item_new_with_label("Add To Dictionary"); gtk_widget_show(add_to_dict_item); gtk_menu_shell_append(GTK_MENU_SHELL(popup_menu), add_to_dict_item); g_signal_connect(add_to_dict_item, "activate", G_CALLBACK(add_to_dict_item_click), NULL); gtk_widget_set_tooltip_text(GTK_WIDGET(add_to_dict_item), "Add word to my dictionary"); - GtkWidget *add_image; - add_image = gtk_image_new_from_stock("gtk-add", GTK_ICON_SIZE_MENU); + GtkWidget *add_image = gtk_image_new_from_stock("gtk-add", GTK_ICON_SIZE_MENU); gtk_widget_show(add_image); gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(add_to_dict_item), add_image); gtk_widget_show(popup_menu); @@ -520,12 +565,11 @@ static void word_list_popup(GtkWidget *widget, GdkEventButton *event) static void show_sent_item_click(GtkWidget *widget, gpointer data) { - GtkTreeSelection *selection; GtkTreeModel *model; GtkTreeIter iter; gchar *word; - selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(word_list)); + GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(word_list)); if (gtk_tree_selection_get_selected(selection, &model, &iter)) { gtk_tree_model_get(model, &iter, 0, &word, -1); set_find_text(word); @@ -537,7 +581,16 @@ static void show_sent_item_click(GtkWidget *widget, gpointer data) static void add_to_dict_item_click(GtkWidget *widget, gpointer data) { + GtkTreeModel *model; + GtkTreeIter iter; + gchar *word; + GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(word_list)); + if (gtk_tree_selection_get_selected(selection, &model, &iter)) { + gtk_tree_model_get(model, &iter, 0, &word, -1); + add_word(dict, word); + g_free(word); + } } static void fill_list(char **word_list) @@ -562,15 +615,22 @@ static void change_search_navigation_state(gboolean state) void add_sentence(char *sentence) { - GtkTextBuffer *buffer; GtkTextIter iter; - buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(sentences_text)); + GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(sentences_text)); gtk_text_buffer_get_end_iter(buffer, &iter); gtk_text_buffer_insert(buffer, &iter, (gchar*) sentence, -1); } -static void on_find_text_change(GtkWidget *widget, gpointer datd) +static gboolean find_entry_key_press(GtkWidget *entry, GdkEventKey *event, gpointer data) +{ + if (event->type == GDK_KEY_PRESS) + if ((event->length)||(event->keyval == GDK_BackSpace)||(event->keyval == GDK_Delete)) + set_status_msg(); + return FALSE; +} + +static void on_find_text_change(GtkWidget *widget, gpointer data) { const gchar *find_text; @@ -600,6 +660,7 @@ static void clear_btn_click(GtkWidget *widget, gpointer data) { clear_search_tags(); gtk_entry_set_text(GTK_ENTRY(find_entry), ""); + set_status_msg(); change_search_navigation_state(FALSE); } @@ -614,12 +675,11 @@ void clear_sentences() static void search_sentences(const gchar *word) { - GtkTextBuffer *buffer; GtkTextIter find_start, find_end; GtkTextIter match_start, match_end; - int offset; + int offset, cnt = 0; - buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(sentences_text)); + GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(sentences_text)); gtk_text_buffer_get_start_iter(buffer, &find_start); gtk_text_buffer_get_end_iter(buffer, &find_end); gtk_text_buffer_remove_tag_by_name(buffer, "green-bg", &find_start, &find_end); @@ -630,7 +690,16 @@ static void search_sentences(const gchar *word) gtk_text_buffer_apply_tag_by_name(buffer, "yellow-bg", &match_start, &match_end); offset = gtk_text_iter_get_offset(&match_end); gtk_text_buffer_get_iter_at_offset(buffer, &find_start, offset); + cnt++; + } + + if (!cnt) { + char status_msg[50] = {0}; + sprintf(status_msg, "Word '%s' was not found", word); + gtk_statusbar_pop(GTK_STATUSBAR(statusbar), find_id); + gtk_statusbar_push(GTK_STATUSBAR(statusbar), find_id, (gchar *) status_msg); } + gtk_text_buffer_get_start_iter(buffer, &find_start); gtk_text_buffer_get_end_iter(buffer, &find_end); if (gtk_text_iter_search_word(&find_start, word, GTK_TEXT_SEARCH_TEXT_ONLY| @@ -650,14 +719,13 @@ static void set_find_text(gchar *text) static void clear_search_tags() { - GtkTextBuffer *buffer; - GtkTextIter find_start, find_end; + GtkTextIter start, end; - buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(sentences_text)); - gtk_text_buffer_get_start_iter(buffer, &find_start); - gtk_text_buffer_get_end_iter(buffer, &find_end); - gtk_text_buffer_remove_tag_by_name(buffer, "yellow-bg", &find_start, &find_end); - gtk_text_buffer_remove_tag_by_name(buffer, "green-bg", &find_start, &find_end); + GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(sentences_text)); + gtk_text_buffer_get_start_iter(buffer, &start); + gtk_text_buffer_get_end_iter(buffer, &end); + gtk_text_buffer_remove_tag_by_name(buffer, "yellow-bg", &start, &end); + gtk_text_buffer_remove_tag_by_name(buffer, "green-bg", &start, &end); } /* We won't need this abomination if GTK developers implement @@ -676,7 +744,7 @@ static gboolean gtk_text_iter_search_word(const GtkTextIter *iter, const gchar * str_wcap = malloc((strlen(str)+1)*sizeof(gchar)); strcpy(str_wcap, str); - /* We've lowered only first letter, so there are only two variants*/ + /* We've lowered only first letter, so there are only two cases*/ *str_wcap = toupper(*str_wcap); if (direction == SEARCH_FORWARD) { if (gtk_text_iter_forward_search(iter, str, flags, match_start, match_end, limit)) @@ -713,11 +781,10 @@ static gboolean gtk_text_iter_search_word(const GtkTextIter *iter, const gchar * static void find_other(const gchar *word, const int direction) { - GtkTextBuffer *buffer; GtkTextIter find_start, find_end; GtkTextIter match_start, match_end; - buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(sentences_text)); + GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(sentences_text)); gtk_text_buffer_get_start_iter(buffer, &find_start); gtk_text_buffer_get_end_iter(buffer, &find_end); gtk_text_buffer_remove_tag_by_name(buffer, "green-bg", &find_start, &find_end); @@ -10,11 +10,11 @@ * * WordExtract is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with WordExtract. If not, see <http://www.gnu.org/licenses/>. + * along with WordExtract. If not, see <http://www.gnu.org/licenses/>. */ #ifndef MAINWIN_H diff --git a/subtitle.h b/subtitle.h deleted file mode 100644 index 579cfb1..0000000 --- a/subtitle.h +++ /dev/null @@ -1,32 +0,0 @@ -/* This file is a part of WordExtract project - * - * Copyright (C) 2009 Borisov Alexandr - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef SUBTITLE_H -#define SUBTITLE_H - -/* maximum subtitle line and phrase length - * it's not allocated dinamically 'cause it costs a lot of resources and - * it can't be more than mean human reading speed in a half of a minute - * it's about 100 letters + formatting - */ -#define MAXLINE 300 -#define MAXPHRASE 100 - -typedef enum {ENG} Language; - -#endif /*SUBTITLE_H*/ @@ -20,21 +20,28 @@ #include <stdlib.h> #include <string.h> #include "mainwin.h" +#include "main.h" #include "word.h" #include "dict.h" Word *words; -static char **sorted = NULL; +SortedWords user_words; +static SortedWords sorted = {0, NULL}; + +static Word *find_word(Word *, const char *); +/*third argument of find_parent() should be NULL when func is to be called*/ +static void find_parent(Word *, const Word *, Word **); static void sort_words(const Word *); +static Word *get_the_rightest(Word *); static inline char *wordcpy(char *); -static inline void free_word_record(Word *); +static inline void free_word(Word *); unsigned int get_words_count(const Word *root) { unsigned int cnt = 0; - if (root == NULL) + if (!root) return 0; else { cnt += get_words_count(root->lsibl); @@ -44,19 +51,55 @@ unsigned int get_words_count(const Word *root) } } -int to_list(char *word) +void del_word(Word **root, char *word) { - if (!is_in_dict(word, dict)) { - words = add_word_record(words, word); + Word *node, *parent = NULL; + Word **parent_leaf = NULL; + + node = find_word(*root, word); + find_parent(*root, node, &parent); + if ((parent)&&(parent->lsibl == node)) + parent_leaf = &parent->lsibl; + else if ((parent)&&(parent->rsibl == node)) + parent_leaf = &parent->rsibl; + /*NOTE that (root == node) is a special case (without parent)*/ + if ((!node->lsibl)&&(!node->rsibl)) { + if (parent) + *parent_leaf = NULL; + else + *root = NULL; + free_word(node); + return ; + } + if ((node->lsibl)&&(!node->rsibl)) { + if (parent) + *parent_leaf = node->lsibl; + else + *root = node->lsibl; + free_word(node); + } else if ((!node->lsibl)&&(node->rsibl)) { + if (parent) + *parent_leaf = node->rsibl; + else + *root = node->rsibl; + free_word(node); + } else { + Word *temp; + temp = get_the_rightest(node->lsibl); + temp->rsibl = node->rsibl; + if (parent) + *parent_leaf = node->lsibl; + else + *root = node->lsibl; + free_word(node); } - return 0; } -Word *add_word_record(Word *root, char *word) +Word *add_word(Word *root, char *word) { int cond; - if (root == NULL) { + if (!root) { root = malloc(sizeof(Word)); root->word = wordcpy(word); root->lsibl = root->rsibl = NULL; @@ -64,43 +107,115 @@ Word *add_word_record(Word *root, char *word) else { cond = strcmp(word, root->word); if (cond > 0) - root->rsibl = add_word_record(root->rsibl, word); + root->rsibl = add_word(root->rsibl, word); else if (cond < 0) - root->lsibl = add_word_record(root->lsibl, word); + root->lsibl = add_word(root->lsibl, word); } return root; } -char **get_sorted(Word *root) +static Word *find_word(Word *root, const char *word) +{ + int cond; + + if (root) { + cond = strcmp(word, root->word); + if (cond > 0) + return find_word(root->rsibl, word); + else if (cond < 0) + return find_word(root->lsibl, word); + else + return root; + } else + return NULL; +} + +static void find_parent(Word *root, const Word *sibling, Word **parent) +{ + if (root) { + if (*parent) + return ; + if (root->lsibl != sibling) + find_parent(root->lsibl, sibling, parent); + else { + *parent = root; + return ; + } + if (*parent) + return ; + if (root->rsibl != sibling) + find_parent(root->rsibl, sibling, parent); + else{ + *parent = root; + return ; + } + } +} + +SortedWords get_sorted(Word *root) { unsigned int cnt; cnt = get_words_count(root); - sorted = malloc(cnt*sizeof(char*)); - sort_words(root); - return (sorted - cnt); + sorted.count = cnt; + sorted.by_az = NULL; + if (cnt) { + sorted.by_az = malloc(cnt*sizeof(char*)); + sort_words(root); + sorted.by_az = sorted.by_az - cnt; + } + return sorted; } static void sort_words(const Word *root) { - if (root->lsibl != NULL) + if (root) { sort_words(root->lsibl); - *sorted = root->word; - sorted++; - if (root->rsibl != NULL) + *sorted.by_az = root->word; + sorted.by_az++; sort_words(root->rsibl); + } +} + +void save_words(FILE *tofile, SortedWords words, SaveOpt options) +{ + int i, j; + char format[10] = {0}; + + sprintf(format, "%%-%us", options.col_width); + i = 0; + while (i < words.count) { + for (j = 0; (j < options.columns)&&(i < words.count); j++) { + if (j == options.columns-1) + fprintf(tofile, "%s\n", *words.by_az); + else + fprintf(tofile, format, *words.by_az); + words.by_az++; + i++; + } + } +} + +static Word *get_the_rightest(Word *root) +{ + if (root->rsibl) + return get_the_rightest(root->rsibl); + else + return root; + /*it's useless but GCC wants it to be*/ + return NULL; } void free_words(Word *root) { - if (root->lsibl != NULL) + if (root->lsibl) free_words(root->lsibl); - if (root->rsibl != NULL) + if (root->rsibl) free_words(root->rsibl); - free_word_record(root); + free_word(root); } -static inline void free_word_record(Word *record) +static inline void free_word(Word *record) { free(record->word); free(record); @@ -10,11 +10,11 @@ * * WordExtract is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with WordExtract. If not, see <http://www.gnu.org/licenses/>. + * along with WordExtract. If not, see <http://www.gnu.org/licenses/>. */ #ifndef WORD_H @@ -25,19 +25,29 @@ */ #define WORDLENGTH 25 -struct word { +#include "main.h" + +struct words { char *word; - struct word *lsibl; - struct word *rsibl; + struct words *lsibl; + struct words *rsibl; }; -typedef struct word Word; +typedef struct words Word; +typedef struct { + unsigned int count; + char **by_az; +} SortedWords; +/*binary tree of words from parsed file*/ extern Word *words; +/*sorted array of words*/ +extern SortedWords user_words; -int to_list(char *); -Word *add_word_record(Word *, char *); +Word *add_word(Word *, char *); +void del_word(Word **, char *); unsigned int get_words_count(const Word *); void free_words(Word *); -char **get_sorted(Word *); +SortedWords get_sorted(Word *); +void save_words(FILE *, SortedWords, SaveOpt); #endif /*WORD_H*/ |