diff options
Diffstat (limited to 'mainwin.c')
-rw-r--r-- | mainwin.c | 386 |
1 files changed, 386 insertions, 0 deletions
diff --git a/mainwin.c b/mainwin.c new file mode 100644 index 0000000..bd41de7 --- /dev/null +++ b/mainwin.c @@ -0,0 +1,386 @@ +/* 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 "mainwin.h" +#include "listview.h" +#include "dictwin.h" +#include "callbacks.h" +#include "word.h" + +GtkWidget *main_window; + +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_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, 2); + gtk_widget_show(vbox); + gtk_container_add(GTK_CONTAINER(main_window), vbox); + + 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"); + g_signal_connect(G_OBJECT(dict_btn), "clicked", G_CALLBACK(dict_btn_click), NULL); + 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); + } + } +} + + |