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*/  | 
