diff options
author | b0ric <b0risov.alexandr@rambler.ru> | 2009-08-08 20:18:38 +0300 |
---|---|---|
committer | b0ric <b0risov.alexandr@rambler.ru> | 2009-08-08 20:18:38 +0300 |
commit | 343357ed1e7907cf4b488058053df280ae63c7bb (patch) | |
tree | 201915ed25612180af3745131be66ce19edf1a0b | |
parent | 88db5cdceabf042f5e5d5695bf984900f8396225 (diff) |
Now words are shown in alphabetical order
-rw-r--r-- | Makefile | 19 | ||||
-rw-r--r-- | callbacks.c | 18 | ||||
-rw-r--r-- | callbacks.h | 1 | ||||
-rw-r--r-- | dict.c | 50 | ||||
-rw-r--r-- | dict.h | 4 | ||||
-rw-r--r-- | dictwin.c | 107 | ||||
-rw-r--r-- | dictwin.h | 24 | ||||
-rw-r--r-- | engparser.c | 14 | ||||
-rw-r--r-- | engparser.h | 15 | ||||
-rw-r--r-- | listview.c | 18 | ||||
-rw-r--r-- | listview.h | 1 | ||||
-rw-r--r-- | main.c | 61 | ||||
-rw-r--r-- | main.h | 40 | ||||
-rw-r--r-- | mainwin.c | 386 | ||||
-rw-r--r-- | mainwin.h | 41 | ||||
-rw-r--r-- | srt.c | 2 | ||||
-rw-r--r-- | srt.h | 3 | ||||
-rw-r--r-- | word.c | 45 | ||||
-rw-r--r-- | word.h | 4 |
19 files changed, 758 insertions, 95 deletions
@@ -2,31 +2,34 @@ CC=gcc CFLAGS=-Wall -g `pkg-config --cflags gtk+-2.0` LDLIBS=`pkg-config --libs gtk+-2.0` -wordextract: main.o interface.o listview.o callbacks.o dict.o srt.o engparser.o word.o - $(CC) $(LDLIBS) main.o interface.o listview.o callbacks.o dict.o srt.o engparser.o word.o -o wordextract +wordextract: main.o mainwin.o listview.o dictwin.o callbacks.o dict.o srt.o engparser.o word.o + $(CC) $(LDLIBS) main.o mainwin.o listview.o dictwin.o callbacks.o dict.o srt.o engparser.o word.o -o wordextract -main.o: main.c interface.h dict.h srt.h subtitle.h +main.o: main.c main.h mainwin.h dict.h srt.h $(CC) $(CFLAGS) -c main.c -interface.o: interface.c interface.h listview.h - $(CC) $(CFLAGS) -c interface.c +mainwin.o: mainwin.c mainwin.h listview.h dictwin.h + $(CC) $(CFLAGS) -c mainwin.c listview.o: listview.c listview.h $(CC) $(CFLAGS) -c listview.c +dictwin.o: dictwin.c dictwin.h + $(CC) $(CFLAGS) -c dictwin.c + callbacks.o: callbacks.c callbacks.h $(CC) $(CFLAGS) -c callbacks.c -dict.o: dict.c dict.h +dict.o: dict.c dict.h main.h $(CC) $(CFLAGS) -c dict.c -srt.o: srt.c srt.h subtitle.h engparser.h +srt.o: srt.c srt.h main.h engparser.h $(CC) $(CFLAGS) -c srt.c enrparser.o: engparser.c engparser.h word.h $(CC) $(CFLAGS) -c engparser.c -word.o: word.c word.h interface.h +word.o: word.c word.h mainwin.h $(CC) $(CFLAGS) -c word.c install: wordextract diff --git a/callbacks.c b/callbacks.c index 89325f7..d3fe1bc 100644 --- a/callbacks.c +++ b/callbacks.c @@ -20,8 +20,10 @@ #include <stdlib.h> #include <string.h> #include "callbacks.h" -#include "subtitle.h" -#include "interface.h" +#include "main.h" +#include "mainwin.h" +#include "listview.h" +#include "dictwin.h" #include "srt.h" #include "word.h" @@ -30,8 +32,6 @@ #define ERR_READING_FILE "Error reading file" #define ERR_MSG_CAPTION "Error" -extern Word *words; - gint main_window_close(GtkWidget *widget, GdkEvent *event, gpointer main_window) { GtkWidget *dialog; @@ -60,6 +60,7 @@ void open_btn_click(GtkWidget *widget, gpointer parent) char *filename; char *errstr; FILE *subtitle; + char **word_list; filter = gtk_file_filter_new(); gtk_file_filter_add_mime_type(filter, "application/x-subrip"); @@ -96,12 +97,19 @@ void open_btn_click(GtkWidget *widget, gpointer parent) else enable_search(); process_srt(subtitle); - print_words(words); + word_list = get_sorted(); + fill_list(word_list); + free(word_list); fclose(subtitle); } gtk_widget_destroy(filedialog); } +void dict_btn_click(GtkWidget *widget, gpointer data) +{ + create_dict_win(); +} + void show_about(GtkWidget *widget, gpointer data) { const gchar *authors[] = {"Borisov Alexandr aka b0ric", NULL}; diff --git a/callbacks.h b/callbacks.h index 03c90a4..d28a756 100644 --- a/callbacks.h +++ b/callbacks.h @@ -22,6 +22,7 @@ gint main_window_close(GtkWidget *, GdkEvent *, gpointer); void main_window_destroy(GtkWidget *, gpointer); void open_btn_click(GtkWidget *, gpointer); +void dict_btn_click(GtkWidget *, gpointer); void show_about(GtkWidget *widget, gpointer data); void quit_btn_click(GtkWidget *, gpointer); void on_find_text_change(GtkWidget *, gpointer); @@ -16,18 +16,34 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include <sys/stat.h> #include <stdio.h> +#include <stdlib.h> #include <string.h> #include "dict.h" +#include "main.h" -Word *load_dict(FILE *dict) +Word *dict; + +static void create_dict_file(char *path); + +Word *load_dict() { + FILE *fdict; Word *root = NULL; char word[WORDLENGTH] = {0}; int i; - while (!feof(dict)) { - fgets(word, WORDLENGTH, dict); + if (!(fdict = fopen(dictfile, "r"))) { + perror(dictfile); + create_dict_file(optpath); + if (!(fdict = fopen(dictfile, "r"))) { + perror(dictfile); + exit(1); + } + } + while (!feof(fdict)) { + fgets(word, WORDLENGTH, fdict); if (strcmp(word, "\0") == 0) /*to not process final blank line*/ break; word[strlen(word)-1] = '\0'; @@ -35,6 +51,7 @@ Word *load_dict(FILE *dict) for (i = 0; i < WORDLENGTH; i++) word[i] = 0; } + fclose(fdict); return root; } @@ -44,8 +61,7 @@ int is_in_dict(char *word, Word *dic_rec) if (dic_rec == NULL) return NOT_IN_DICT; - else { - + else { if ((cond = strcmp(word, dic_rec->word)) == 0) return IN_DICT; else if (cond > 0) @@ -55,3 +71,27 @@ 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; + struct stat st; + FILE *fdict; + char file[PATH_LENGTH] = {0}; + + if (stat(path, &st)) { + fprintf(stderr, "%s: Creating directory\n", path); + if (mkdir(path, mode_0755)) { + perror(path); + exit(1); + } + } + strcat(file, path); + strcat(file, DICT_FILE); + fprintf(stderr, "%s: Creating blank dictionary file\n", file); + if (!(fdict = fopen(file, "w"))) { + perror(file); + exit(1); + } + fclose(fdict); +} + @@ -25,9 +25,9 @@ #define IN_DICT 1 #define NOT_IN_DICT 0 -Word *dict; +extern Word *dict; -Word *load_dict(FILE *); +Word *load_dict(); int is_in_dict(char *, Word *); #endif /*DICT_H*/ diff --git a/dictwin.c b/dictwin.c new file mode 100644 index 0000000..9569a35 --- /dev/null +++ b/dictwin.c @@ -0,0 +1,107 @@ +/* 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 <gtk/gtk.h> +#include "dictwin.h" +#include "mainwin.h" +#include "dict.h" + +static void fill_dict(GtkTextBuffer *, Word *); + +void create_dict_win() +{ + GtkWidget *dict_win; + + dict_win = gtk_window_new(GTK_WINDOW_TOPLEVEL); + gtk_widget_set_size_request(dict_win, 500, 375); + gtk_container_set_border_width(GTK_CONTAINER(dict_win), 0); + gtk_window_set_title(GTK_WINDOW(dict_win), "My Dictionary"); + gtk_window_set_transient_for(GTK_WINDOW(dict_win), GTK_WINDOW(main_window)); + gtk_window_set_position(GTK_WINDOW(dict_win), GTK_WIN_POS_CENTER_ON_PARENT); + 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); + gtk_container_add(GTK_CONTAINER(dict_win), vbox); + gtk_container_set_border_width(GTK_CONTAINER(vbox), 2); + gtk_widget_show(vbox); + + GtkWidget *dict_sc; + dict_sc = gtk_scrolled_window_new(NULL, NULL); + gtk_box_pack_start(GTK_BOX(vbox), dict_sc, TRUE, TRUE, 0); + gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(dict_sc), GTK_SHADOW_IN); + gtk_widget_show(dict_sc); + + GtkWidget *dict_text; + GtkTextBuffer *buffer; + dict_text = gtk_text_view_new(); + gtk_container_add(GTK_CONTAINER(dict_sc), dict_text); + buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(dict_text)); + fill_dict(buffer, dict); + gtk_widget_show(dict_text); + + GtkWidget *hbox; + 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); + 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); + gtk_box_pack_end(GTK_BOX(btn_hbox), cancel_btn, TRUE, TRUE, 0); + gtk_widget_show(cancel_btn); + + GtkWidget *save_btn; + save_btn = gtk_button_new_from_stock(GTK_STOCK_SAVE); + gtk_box_pack_end(GTK_BOX(btn_hbox), save_btn, TRUE, TRUE, 0); + gtk_widget_show(save_btn); + + gtk_widget_show(dict_win); +} + +static void fill_dict(GtkTextBuffer *buffer, Word *dict) +{ + GtkTextIter iter; + + if (dict != NULL) { + if (dict->lsibl != NULL) + fill_dict(buffer, dict->lsibl); + if (dict->rsibl != NULL) + fill_dict(buffer, dict->rsibl); + gtk_text_buffer_get_end_iter(buffer, &iter); + gtk_text_buffer_insert(buffer, &iter, (gchar*) dict->word, -1); + gtk_text_buffer_insert(buffer, &iter, "\n", -1); + } +} + + + + + + + + + + + + diff --git a/dictwin.h b/dictwin.h new file mode 100644 index 0000000..ee629b7 --- /dev/null +++ b/dictwin.h @@ -0,0 +1,24 @@ +/* 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 DICTWIN_H +#define DICTWIN_H + +void create_dict_win(); + +#endif /*DICTWIN_H*/ diff --git a/engparser.c b/engparser.c index e5b17e6..ec9baba 100644 --- a/engparser.c +++ b/engparser.c @@ -19,30 +19,18 @@ #include <stdio.h> #include <ctype.h> #include <string.h> -#include "interface.h" +#include "mainwin.h" #include "engparser.h" #include "word.h" -/*---------OPTIONS---------*/ int lower_first_capital = 1; int excl_w_capital = 1; - Parseoptions hyphen = {'-', 0, 1, 0, 1, 0}; Parseoptions quote = {'\'', 0, 1, 1, 0, 0}; - /* It deletes first and last symbol in the word*/ static void del_first_n_last(char *word); -/* - * Recieves: line terminated by "\n\0" - * - * Words with "-" we'll be processed as a whole word - * And also we suppose that each sentence starts with capital letter - * and other words in the middle of the sentence which starts with - * capital letter is name (peoples, towns, I, etc...). - * Single quoted sentences are not allowed. It's gramatically incorrect - */ int parseengphrase(char *phrase) { extern Parseoptions hyphen; diff --git a/engparser.h b/engparser.h index f58b3cb..516193b 100644 --- a/engparser.h +++ b/engparser.h @@ -31,6 +31,21 @@ typedef struct { int excl_word_after_symb; } Parseoptions; +/* Parsing options */ +extern int lower_first_capital; +extern int excl_w_capital; +extern Parseoptions hyphen; +extern Parseoptions quote; + +/* + * Recieves: line terminated by "\n\0" + * + * Words with "-" we'll be processed as a whole word + * And also we suppose that each sentence starts with capital letter + * and other words in the middle of the sentence which starts with + * capital letter is name (peoples, towns, I, etc...). + * Single quoted sentences are not allowed. It's gramatically incorrect + */ int parseengphrase(char *); int parse_eng_word(char *word, Parseoptions opt); @@ -16,7 +16,9 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "interface.h" +#include <gtk/gtk.h> +#include "mainwin.h" +#include "word.h" enum {WORD_ITEM = 0, N_COLUMNS}; @@ -101,6 +103,19 @@ void add_word_to_list(char *word) gtk_list_store_set(store_model, &iter, WORD_ITEM, word, -1); } +void fill_list(char **word_list) +{ + GtkTreeIter iter; + int cnt, i; + + cnt = get_words_count(words); + for (i = 0; i < cnt; i++) { + gtk_list_store_append(store_model, &iter); + gtk_list_store_set(store_model, &iter, WORD_ITEM, *word_list, -1); + word_list++; + } +} + static void word_list_popup(GtkWidget *widget, GdkEventButton *event) { GtkWidget *popup_menu; @@ -159,4 +174,3 @@ void add_to_dict_item_click(GtkWidget *widget, gpointer data) } - @@ -22,5 +22,6 @@ GtkWidget *create_word_list(); void clear_word_list(); void add_word_to_list(char *); +void fill_list(char **); #endif /*LIST_VIEW_H*/ @@ -16,79 +16,36 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include <sys/stat.h> #include <stdio.h> #include <stdlib.h> #include <string.h> -#include "interface.h" -#include "subtitle.h" +#include "main.h" +#include "mainwin.h" #include "dict.h" -#define PROGNAME "wordextract" -#define OPT_FOLDER "/.wordextract" -#define PATH_LENGTH 50 - +char optpath[PATH_LENGTH] = {0}; +char dictfile[PATH_LENGTH] = {0}; Language lang; -static void create_dict_file(char *); -static void open_and_load_dict(); +static void fill_vars(); int main(int argc, char *argv[]) { - gtk_init(&argc, &argv); - open_and_load_dict(); + fill_vars(); + dict = load_dict(); lang = ENG; create_main_window(); gtk_widget_show(main_window); gtk_main(); - - free_words(dict); + free_words(dict); /*Where to put?*/ return 0; } -void create_dict_file(char *path) -{ - mode_t mode_0755 = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH; - struct stat st; - FILE *fdict; - char file[PATH_LENGTH] = {0}; - - if (stat(path, &st)) { - fprintf(stderr, "%s: Creating directory\n", path); - if (mkdir(path, mode_0755)) { - perror(path); - exit(1); - } - } - strcat(file, path); - strcat(file, DICT_FILE); - fprintf(stderr, "%s: Creating blank dictionary file\n", file); - if (!(fdict = fopen(file, "w"))) { - perror(file); - exit(1); - } - fclose(fdict); -} - -void open_and_load_dict() +void fill_vars() { - FILE *fdict; - char optpath[PATH_LENGTH] = {0}; - char dictfile[PATH_LENGTH] = {0}; - strcpy(optpath, getenv("HOME")); strcat(optpath, OPT_FOLDER); strcat(dictfile, optpath); strcat(dictfile, DICT_FILE); - if (!(fdict = fopen(dictfile, "r"))) { - perror(dictfile); - create_dict_file(optpath); - if (!(fdict = fopen(dictfile, "r"))) { - perror(dictfile); - exit(1); - } - } - dict = load_dict(fdict); - fclose(fdict); } @@ -0,0 +1,40 @@ +/* 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 MAIN_H +#define MAIN_H + +#define PATH_LENGTH 50 +#define PROGNAME "wordextract" +#define OPT_FOLDER "/.wordextract" +/* 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; + +extern Language lang; + +extern char optpath[PATH_LENGTH]; +extern char dictfile[PATH_LENGTH]; + +#endif /*MAIN_H*/ 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); + } + } +} + + diff --git a/mainwin.h b/mainwin.h new file mode 100644 index 0000000..89ed5f6 --- /dev/null +++ b/mainwin.h @@ -0,0 +1,41 @@ +/* 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 MAINWIN_H +#define MAINWIN_H + +#include <gtk/gtk.h> + +#define SEARCH_FORWARD 0 +#define SEARCH_BACKWARD 1 + +extern 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 /*MAINWIN_H*/ @@ -18,7 +18,7 @@ #include <stdio.h> #include <ctype.h> -#include "subtitle.h" +#include "main.h" #include "srt.h" #include "engparser.h" @@ -19,9 +19,6 @@ #ifndef SRT_H #define SRT_H -//language setting -extern Language lang; - int process_srt(FILE *); int process_srt_line(char *); @@ -19,12 +19,17 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> -#include "interface.h" +#include "mainwin.h" +#include "listview.h" #include "word.h" #include "dict.h" -static inline char *wordcpy(char *word); -static inline void free_word_record(Word *record); +Word *words; +static char **sorted = NULL; + +static void sort_words(const Word *); +static inline char *wordcpy(char *); +static inline void free_word_record(Word *); int to_list(char *word) { @@ -53,6 +58,40 @@ Word *add_word_record(Word *root, char *word) return root; } +char **get_sorted() +{ + unsigned int cnt; + + cnt = get_words_count(words); + sorted = malloc(cnt*sizeof(char*)); + sort_words(words); + return (sorted - cnt); +} + +static void sort_words(const Word *root) +{ + if (root->lsibl != NULL) + sort_words(root->lsibl); + *sorted = root->word; + sorted++; + if (root->rsibl != NULL) + sort_words(root->rsibl); +} + +unsigned int get_words_count(const Word *root) +{ + unsigned int cnt = 0; + + if (root == NULL) + return 0; + else { + cnt += get_words_count(root->lsibl); + cnt += get_words_count(root->rsibl); + cnt++; + return cnt; + } +} + void free_words(Word *root) { if (root->lsibl != NULL) @@ -31,11 +31,13 @@ struct word { }; typedef struct word Word; -Word *words; +extern Word *words; int to_list(char *); void print_words(Word *); Word *add_word_record(Word *, char *); +unsigned int get_words_count(const Word *); void free_words(Word *); +char **get_sorted(); #endif /*WORD_H*/ |