1 /*
2
3 Copyright (c) 2004-2013 uim Project https://github.com/uim/uim
4
5 All rights reserved.
6
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions
9 are met:
10
11 1. Redistributions of source code must retain the above copyright
12 notice, this list of conditions and the following disclaimer.
13 2. Redistributions in binary form must reproduce the above copyright
14 notice, this list of conditions and the following disclaimer in the
15 documentation and/or other materials provided with the distribution.
16 3. Neither the name of authors nor the names of its contributors
17 may be used to endorse or promote products derived from this software
18 without specific prior written permission.
19
20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
21 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE
24 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 SUCH DAMAGE.
31
32 */
33
34 #include <config.h>
35
36 #include <stdlib.h>
37 # include <gtk/gtk.h>
38 #if GTK_CHECK_VERSION(2, 90, 0)
39 # include <gdk/gdkkeysyms-compat.h>
40 #else
41 # include <gdk/gdkkeysyms.h>
42 #endif
43
44 #include "gettext.h"
45
46 #include "word.h"
47 #include "anthy.h"
48 #include "word-list-view-gtk.h"
49 #include "word-list-win-gtk.h"
50 #include "word-win-gtk.h"
51
52 static void word_list_window_class_init (WordListWindowClass *window);
53 static void word_list_window_init (WordListWindow *window);
54 static void word_list_window_dispose (GObject *object);
55 static void word_list_window_set_sensitive (WordListWindow *window);
56
57 /* call back functions for ui manager */
58 static void add_widget_cb (GtkUIManager *merge,
59 GtkWidget *widget,
60 GtkBox *box);
61
62 /* call back functions for actions */
63 static void file_exit_action_cb (GtkAction *action);
64 static void edit_add_word_action_cb (GtkAction *action,
65 WordListWindow *window);
66 static void edit_remove_word_action_cb (GtkAction *action,
67 WordListWindow *window);
68 static void edit_edit_word_action_cb (GtkAction *action,
69 WordListWindow *window);
70 static void popup_menu_action_cb (GtkAction *action,
71 WordListWindow *window);
72 static void help_about_action_cb (GtkAction *action,
73 WordListWindow *window);
74 static void activate_radio_action(GtkAction *action, GtkRadioAction *current,
75 gpointer data);
76
77 /* call back functions for WordListView */
78 static gboolean word_list_button_press_cb (GtkWidget *widget,
79 GdkEventButton *event,
80 WordListWindow *window);
81 static gboolean word_list_row_activated_cb(GtkWidget *widget,
82 GtkTreePath *path,
83 GtkTreeViewColumn *column,
84 WordListWindow *window);
85 static gboolean word_list_key_press_cb (GtkWidget *widget,
86 GdkEventKey *event,
87 WordListWindow *window);
88 static void word_list_selection_changed_cb (GtkTreeSelection *selection,
89 WordListWindow *window);
90
91 /* call back functions for WordWindow */
92 static void wordwin_response_cb (WordWindow *dialog,
93 WordListWindow *window);
94
95 static void dict_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
96 static void dict_set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
97
98 GtkWindowClass *parent_class = NULL;
99 GdkEventButton *current_button_event = NULL;
100
101 /* Main menu*/
102 GtkActionEntry menu_action_entries[] = {
103 { "DictionaryMenu", NULL, N_("_Dictionary") },
104 { "SelectMenu", NULL, N_("_Select") },
105 { "EditMenu", NULL, N_("_Edit") },
106 { "OptionMenu", NULL, N_("_Option") },
107 { "HelpMenu", NULL, N_("_Help") },
108 { "Quit", GTK_STOCK_QUIT, N_("_Quit"), "<control>Q",
109 N_("Quit uim-dict"), G_CALLBACK(file_exit_action_cb) },
110 { "AddWord", GTK_STOCK_ADD, N_("A_dd..."), "<control>A",
111 N_("Add a new word"), G_CALLBACK(edit_add_word_action_cb) },
112 { "RemoveWord", GTK_STOCK_REMOVE, N_("_Remove..."), "<control>D",
113 N_("Remove the selected word"), G_CALLBACK(edit_remove_word_action_cb) },
114 { "EditWord", GTK_STOCK_DND, N_("_Edit..."), "<control>E",
115 N_("Edit the selected word"), G_CALLBACK(edit_edit_word_action_cb) },
116 { "PopupMenu", NULL, N_("_Popup Menu"), NULL,
117 N_("Show popup menu"), G_CALLBACK(popup_menu_action_cb) },
118 { "About", NULL, N_("_About"), NULL,
119 N_("About uim-dict"), G_CALLBACK(help_about_action_cb) },
120 };
121 static guint n_menu_action_entries = G_N_ELEMENTS(menu_action_entries);
122
123 static GtkRadioActionEntry dictionary_entries[] = {
124 { "Anthy", NULL,
125 "_Anthy", NULL,
126 "Anthy private dictionary", DICT_ENUM_DICTIONARY_TYPE_ANTHY },
127 { "Canna", NULL,
128 "_Canna", NULL,
129 "Canna private dictionary", DICT_ENUM_DICTIONARY_TYPE_CANNA },
130 };
131 static guint n_dictionary_entries = G_N_ELEMENTS(dictionary_entries);
132
133 #define ACTIVATE_ACTION(window, action_name) \
134 { \
135 GtkAction *action; \
136 action = gtk_action_group_get_action((window)->action_group, (action_name)); \
137 if (action) { \
138 gtk_action_activate(action); \
139 } \
140 }
141
142 #define SET_ACTION_SENSITIVE(window, action_name, sensitive) \
143 { \
144 GtkAction *action; \
145 action = gtk_action_group_get_action((window)->action_group, (action_name)); \
146 if (action) { \
147 g_object_set(action, \
148 "sensitive", (sensitive), \
149 NULL); \
150 } \
151 }
152
word_list_window_get_type(void)153 GType word_list_window_get_type(void) {
154 static GType type = 0;
155
156 if (type == 0) {
157 static const GTypeInfo info = {
158 sizeof(WordListWindowClass),
159 NULL, /* base_init */
160 NULL, /* base_finalize */
161 (GClassInitFunc)word_list_window_class_init,
162 NULL, /* class_finalize */
163 NULL, /* class_data */
164 sizeof(WordWindow),
165 0, /* n_preallocs */
166 (GInstanceInitFunc)word_list_window_init /* instance_init */
167 };
168 type = g_type_register_static(GTK_TYPE_WINDOW,
169 "WordListWindow", &info, 0);
170 }
171 return type;
172 }
173
174 GType
dict_enum_dictionary_type_get_type(void)175 dict_enum_dictionary_type_get_type(void)
176 {
177 static GType etype = 0;
178 if (etype == 0) {
179 static const GEnumValue values[] = {
180 { DICT_ENUM_DICTIONARY_TYPE_ANTHY, "DICT_ENUM_DICTIONARY_TYPE_ANTHY", "anthy" },
181 { DICT_ENUM_DICTIONARY_TYPE_CANNA, "DICT_ENUM_DICTIONARY_TYPE_CANNA", "canna" },
182 { DICT_ENUM_DICTIONARY_TYPE_SKK, "DICT_ENUM_DICTIONARY_TYPE_SKK", "skk" },
183 { DICT_ENUM_DICTIONARY_TYPE_PRIME, "DICT_ENUM_DICTIONARY_TYPE_PRIME", "prime" },
184 { DICT_ENUM_DICTIONARY_TYPE_UNKOWN, "DICT_ENUM_DICTIONARY_TYPE_UNKOWN", "unknown" },
185 { 0, NULL, NULL }
186 };
187 etype = g_enum_register_static("DictEnumDictionaryType", values);
188 }
189 return etype;
190 }
191
192 static void
word_list_window_class_init(WordListWindowClass * klass)193 word_list_window_class_init (WordListWindowClass *klass)
194 {
195 GObjectClass *object_class;
196
197 parent_class = g_type_class_peek_parent(klass);
198 object_class = (GObjectClass *) klass;
199
200 object_class->dispose = word_list_window_dispose;
201
202 object_class->get_property = dict_get_property;
203 object_class->set_property = dict_set_property;
204
205 g_object_class_install_property(object_class,
206 PROP_DICTIONARY_TYPE,
207 g_param_spec_enum("dictionary-type",
208 _("dictionary type"),
209 _("dictionary type"),
210 DICT_TYPE_ENUM_DICTIONARY_TYPE,
211 DICT_ENUM_DICTIONARY_TYPE_ANTHY,
212 G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
213 }
214
215 static gchar *
translate_func(const gchar * path,gpointer data)216 translate_func(const gchar *path, gpointer data)
217 {
218 return _(path);
219 }
220
221 static void
warn_dict_open()222 warn_dict_open()
223 {
224 GtkWidget *dialog;
225 const gchar *message;
226
227 message = N_("Couldn't open the dictionary.\n");
228 dialog = gtk_message_dialog_new(NULL,
229 GTK_DIALOG_MODAL,
230 GTK_MESSAGE_WARNING,
231 GTK_BUTTONS_OK,
232 "%s", _(message));
233 gtk_dialog_run(GTK_DIALOG(dialog));
234 gtk_widget_destroy(GTK_WIDGET(dialog));
235 }
236
237 static void
word_list_window_init(WordListWindow * window)238 word_list_window_init (WordListWindow *window)
239 {
240 GtkWidget *word_list, *vbox, *statusbar;
241 GtkUIManager *ui;
242 GtkActionGroup *actions;
243
244 gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
245 gtk_window_set_default_size(GTK_WINDOW(window), 600, 450);
246 gtk_window_set_title(GTK_WINDOW(window), _("Edit the dictionary"));
247
248 #if GTK_CHECK_VERSION(3, 2, 0)
249 vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
250 #else
251 vbox = gtk_vbox_new(FALSE, 0);
252 #endif
253 gtk_container_add(GTK_CONTAINER(window), vbox);
254 gtk_widget_show(vbox);
255
256 window->action_group = actions = gtk_action_group_new("Actions");
257 #if ENABLE_NLS
258 gtk_action_group_set_translate_func(window->action_group,
259 translate_func, NULL, NULL);
260 #endif
261 gtk_action_group_add_actions(actions, menu_action_entries,
262 n_menu_action_entries, window);
263
264 gtk_action_group_add_radio_actions(actions, dictionary_entries,
265 n_dictionary_entries,
266 DICT_ENUM_DICTIONARY_TYPE_ANTHY,
267 G_CALLBACK(activate_radio_action),
268 window);
269
270 window->ui_manager = ui = gtk_ui_manager_new();
271 gtk_ui_manager_insert_action_group(ui, actions, 0);
272 g_signal_connect(ui, "add_widget",
273 G_CALLBACK(add_widget_cb),
274 vbox);
275 gtk_window_add_accel_group(GTK_WINDOW(window),
276 gtk_ui_manager_get_accel_group(ui));
277
278 gtk_ui_manager_add_ui_from_file(ui,
279 UIM_DATADIR "/helperdata/uim-dict-ui.xml",
280 NULL);
281 gtk_ui_manager_ensure_update(ui);
282
283 window->word_list = word_list = word_list_view_new();
284 word_list_view_set_visible_cclass_code_column(WORD_LIST_VIEW(word_list), TRUE);
285 word_list_view_set_visible_freq_column(WORD_LIST_VIEW(word_list), TRUE);
286 gtk_widget_show(word_list);
287 gtk_box_pack_start(GTK_BOX(vbox), word_list, TRUE, TRUE, 0);
288
289 g_signal_connect(G_OBJECT(gtk_bin_get_child(GTK_BIN(window->word_list))),
290 "button-press-event",
291 G_CALLBACK(word_list_button_press_cb), window);
292 g_signal_connect(G_OBJECT(gtk_bin_get_child(GTK_BIN(window->word_list))),
293 "row-activated",
294 G_CALLBACK(word_list_row_activated_cb), window);
295 g_signal_connect(G_OBJECT(gtk_bin_get_child(GTK_BIN(window->word_list))),
296 "key-press-event",
297 G_CALLBACK(word_list_key_press_cb), window);
298 g_signal_connect(G_OBJECT(WORD_LIST_VIEW(window->word_list)->selection),
299 "changed",
300 G_CALLBACK(word_list_selection_changed_cb), window);
301
302 window->statusbar = statusbar = gtk_statusbar_new();
303 gtk_box_pack_start(GTK_BOX(vbox), statusbar, FALSE, FALSE, 0);
304 gtk_widget_show(statusbar);
305
306 word_list_window_set_sensitive(window);
307 }
308
309 static void
word_list_window_dispose(GObject * object)310 word_list_window_dispose(GObject *object)
311 {
312 WordListWindow *window = WORD_LIST_WINDOW(object);
313
314 if (window->action_group) {
315 g_object_unref(window->action_group);
316 window->action_group = NULL;
317 }
318
319 if (window->ui_manager) {
320 g_object_unref(window->ui_manager);
321 window->ui_manager = NULL;
322 }
323
324 if (G_OBJECT_CLASS(parent_class)->dispose)
325 G_OBJECT_CLASS(parent_class)->dispose(object);
326 }
327
328 static void
dict_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)329 dict_get_property(GObject *object, guint prop_id, GValue *value,
330 GParamSpec *pspec)
331 {
332 switch (prop_id) {
333 case PROP_DICTIONARY_TYPE:
334 g_value_set_enum(value, dict_get_dictionary_type(GTK_WIDGET(object)));
335 break;
336 default:
337 break;
338 }
339 }
340
341 static void
dict_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)342 dict_set_property(GObject *object, guint prop_id, const GValue *value,
343 GParamSpec *pspec)
344 {
345 WordListWindow *window = WORD_LIST_WINDOW(object);
346 uim_dict *dict = NULL;
347 gchar message[128];
348
349 switch (prop_id) {
350 case PROP_DICTIONARY_TYPE:
351 window->dictionary_type = g_value_get_enum(value);
352
353 ACTIVATE_ACTION(window, dictionary_entries[window->dictionary_type].name);
354
355 switch (window->dictionary_type) {
356 case DICT_ENUM_DICTIONARY_TYPE_ANTHY:
357 dict = uim_dict_open(N_("Anthy private dictionary"));
358 break;
359 case DICT_ENUM_DICTIONARY_TYPE_CANNA:
360 word_list_view_set_visible_freq_column(WORD_LIST_VIEW(window->word_list), FALSE);
361 dict = uim_dict_open(N_("Canna private dictionary"));
362 break;
363 default:
364 break;
365 }
366 if (!dict) {
367 warn_dict_open();
368 break;
369 }
370 word_list_view_set_dict(WORD_LIST_VIEW(window->word_list), dict);
371
372 g_snprintf(message, sizeof(message), _("%s"), _(dict->identifier));
373 gtk_statusbar_push(GTK_STATUSBAR(window->statusbar), 0, _(dict->identifier));
374 break;
375 default:
376 break;
377 }
378 }
379
380 DictEnumDictionaryType
dict_get_dictionary_type(GtkWidget * window)381 dict_get_dictionary_type(GtkWidget *window)
382 {
383 WordListWindow *w = (WordListWindow *)window;
384
385 return w->dictionary_type;
386 }
387
word_list_window_new(int type)388 GtkWidget *word_list_window_new(int type)
389 {
390 return GTK_WIDGET(g_object_new(WORD_LIST_WINDOW_TYPE,
391 "dictionary-type", type, NULL));
392 }
393
394 static void
word_list_window_set_sensitive(WordListWindow * window)395 word_list_window_set_sensitive(WordListWindow *window)
396 {
397 gboolean selected;
398 WordListView *word_list;
399 GtkTreeSelection *selection;
400
401 word_list = WORD_LIST_VIEW(window->word_list);
402 selection = word_list->selection;
403
404 selected = gtk_tree_selection_get_selected(selection, NULL, NULL);
405
406 if (selected) {
407 SET_ACTION_SENSITIVE(window, "EditWord", TRUE);
408 SET_ACTION_SENSITIVE(window, "RemoveWord", TRUE);
409 } else {
410 SET_ACTION_SENSITIVE(window, "EditWord", FALSE);
411 SET_ACTION_SENSITIVE(window, "RemoveWord", FALSE);
412 }
413 }
414
415
416 /*
417 * call back functions for ui manager
418 */
419 static void
add_widget_cb(GtkUIManager * merge,GtkWidget * widget,GtkBox * box)420 add_widget_cb (GtkUIManager *merge, GtkWidget *widget, GtkBox *box)
421 {
422 gtk_box_pack_start (box, widget, FALSE, FALSE, 0);
423 }
424
425
426 /*
427 * call back functions for actions
428 */
429 static void
file_exit_action_cb(GtkAction * action)430 file_exit_action_cb(GtkAction *action)
431 {
432 gtk_main_quit();
433 }
434
435 static void
edit_add_word_action_cb(GtkAction * action,WordListWindow * window)436 edit_add_word_action_cb(GtkAction *action, WordListWindow *window)
437 {
438 GtkWidget *w;
439
440 w = word_window_new(WORD_WINDOW_MODE_ADD,
441 WORD_LIST_VIEW(window->word_list)->dict);
442 gtk_grab_add(w);
443 gtk_window_set_transient_for(GTK_WINDOW(w), GTK_WINDOW(window));
444 gtk_window_set_position(GTK_WINDOW(w), GTK_WIN_POS_CENTER_ON_PARENT);
445 g_signal_connect(G_OBJECT(w), "word-added",
446 G_CALLBACK(wordwin_response_cb), window);
447 gtk_widget_show(w);
448 }
449
450 static void
remove_confirm_dialog_response_cb(GtkDialog * dialog,gint arg,gboolean * ok)451 remove_confirm_dialog_response_cb(GtkDialog *dialog, gint arg,
452 gboolean *ok)
453 {
454 g_return_if_fail(ok);
455
456 *ok = FALSE;
457
458 switch (arg)
459 {
460 case GTK_RESPONSE_OK:
461 *ok = TRUE;
462 break;
463 default:
464 break;
465 }
466 }
467
468 static void
edit_remove_word_action_cb(GtkAction * action,WordListWindow * window)469 edit_remove_word_action_cb(GtkAction *action, WordListWindow *window)
470 {
471 GtkWidget *dialog;
472 GList *node, *list;
473 gboolean ok = FALSE;
474 const gchar *message = _("Are you sure to remove seleted words?");
475
476 list = word_list_view_get_selected_data_list(WORD_LIST_VIEW(window->word_list));
477 if (!list) return;
478
479 if (!g_list_next(list))
480 message = _("Are you sure to remove the selected word?");
481
482 dialog = gtk_message_dialog_new(NULL,
483 GTK_DIALOG_MODAL,
484 GTK_MESSAGE_QUESTION,
485 GTK_BUTTONS_OK_CANCEL,
486 "%s", message);
487 gtk_window_set_transient_for(GTK_WINDOW(dialog), GTK_WINDOW(window));
488 gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_CENTER_ON_PARENT);
489 g_signal_connect(G_OBJECT(dialog), "response",
490 G_CALLBACK(remove_confirm_dialog_response_cb), &ok);
491 gtk_dialog_run(GTK_DIALOG(dialog));
492 gtk_widget_destroy(dialog);
493 dialog = NULL;
494
495 if (!ok) return;
496
497 for (node = list; node; node = g_list_next(node)) {
498 uim_word *w = node->data;
499 int ret;
500
501 ret = uim_dict_remove_word(WORD_LIST_VIEW(window->word_list)->dict, w);
502
503 if (ret) {
504 word_list_view_refresh(WORD_LIST_VIEW(window->word_list));
505 dialog = gtk_message_dialog_new(NULL,
506 GTK_DIALOG_MODAL,
507 GTK_MESSAGE_INFO,
508 GTK_BUTTONS_CLOSE,
509 "%s", _("Word deletion succeeded."));
510 } else {
511 dialog = gtk_message_dialog_new(NULL,
512 GTK_DIALOG_MODAL,
513 GTK_MESSAGE_ERROR,
514 GTK_BUTTONS_CLOSE,
515 "%s", _("Word deletion failed."));
516 }
517 gtk_window_set_transient_for(GTK_WINDOW(dialog), GTK_WINDOW(window));
518 gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_CENTER_ON_PARENT);
519 gtk_dialog_run(GTK_DIALOG(dialog));
520 gtk_widget_destroy(dialog);
521 }
522 g_list_free(list);
523 }
524
525 static void
edit_edit_word_action_cb(GtkAction * action,WordListWindow * window)526 edit_edit_word_action_cb(GtkAction *action, WordListWindow *window)
527 {
528 GList *list;
529
530 list = word_list_view_get_selected_data_list(WORD_LIST_VIEW(window->word_list));
531
532 /* FIXME! it can edit only one word yet. */
533 if (list) {
534 GtkWidget *widget;
535
536 widget = word_window_new(WORD_WINDOW_MODE_EDIT,
537 WORD_LIST_VIEW(window->word_list)->dict);
538 gtk_grab_add(widget);
539 gtk_window_set_transient_for(GTK_WINDOW(widget), GTK_WINDOW(window));
540 gtk_window_set_position(GTK_WINDOW(widget), GTK_WIN_POS_CENTER_ON_PARENT);
541 word_window_set_word(WORD_WINDOW(widget), list->data);
542 g_signal_connect(G_OBJECT(widget), "word-added",
543 G_CALLBACK(wordwin_response_cb), window);
544
545 gtk_widget_show(widget);
546 }
547 g_list_free(list);
548 }
549
550 static void
popup_menu_action_cb(GtkAction * action,WordListWindow * window)551 popup_menu_action_cb(GtkAction *action, WordListWindow *window)
552 {
553 GtkWidget *popup_menu;
554
555 popup_menu = gtk_ui_manager_get_widget(window->ui_manager,
556 "/WordListPopup");
557 g_return_if_fail(popup_menu);
558
559 if (current_button_event) {
560 gtk_menu_popup(GTK_MENU(popup_menu),
561 NULL, NULL,
562 NULL, NULL,
563 current_button_event->button,
564 current_button_event->time);
565 } else {
566 gtk_menu_popup(GTK_MENU(popup_menu), NULL, NULL,
567 NULL, NULL, 0, GDK_CURRENT_TIME);
568 }
569 }
570
571 #if GTK_CHECK_VERSION(2, 6, 0) && !GTK_CHECK_VERSION(2, 18, 0)
572 static void
activate_url(GtkAboutDialog * about,const gchar * link,gpointer data)573 activate_url(GtkAboutDialog *about, const gchar *link, gpointer data)
574 {
575 /* g_print("show url %s\n", link); */
576 }
577 #endif
578
579 static void
help_about_action_cb(GtkAction * action,WordListWindow * window)580 help_about_action_cb(GtkAction *action, WordListWindow *window)
581 {
582 const gchar *name = N_("uim-dict");
583 #if GTK_CHECK_VERSION(2, 6, 0)
584 GdkPixbuf *pixbuf, *transparent;
585 const gchar *filename = UIM_PIXMAPSDIR "/uim-dict.png";
586 const gchar *authors[] = {
587 "Masahito Omote <omote@utyuuzin.net>",
588 "Takuro Ashie",
589 "Etsushi Kato",
590 NULL
591 };
592 const gchar *copyright = N_(
593 "Copyright (C) 2003-2004 Masahito Omote\n"
594 "Copyright (C) 2004-2013 uim Project\n"
595 "All rights reserved.");
596
597 transparent = NULL;
598 pixbuf = gdk_pixbuf_new_from_file(filename, NULL);
599 if (pixbuf) {
600 transparent = gdk_pixbuf_add_alpha(pixbuf, TRUE, 0xff, 0xff, 0xff);
601 g_object_unref(pixbuf);
602 }
603
604 #if !GTK_CHECK_VERSION(2, 18, 0)
605 gtk_about_dialog_set_url_hook (activate_url, NULL, NULL);
606 #endif
607 gtk_show_about_dialog (GTK_WINDOW(window),
608 "name", name,
609 "version", VERSION,
610 "copyright", copyright,
611 "website", "https://github.com/uim/uim",
612 "authors", authors,
613 "logo", transparent,
614 NULL);
615 g_object_unref(transparent);
616 #else
617 GtkWidget *about_dialog, *label1;
618 const gchar *copyright = N_(
619 "Copyright 2003-2004 Masahito Omote <omote@utyuuzin.net>\n"
620 "Copyright 2004-2013 uim Project https://github.com/uim/uim\n"
621 "All rights reserved.");
622 gchar *about_name =
623 g_strdup_printf("<span size=\"20000\">%s %s </span>\n\n<span size=\"14000\">%s </span>\n", _(name), VERSION, _(copyright));
624
625 about_dialog = gtk_dialog_new_with_buttons(_("About uim-dict"), NULL,
626 GTK_DIALOG_MODAL,
627 GTK_STOCK_OK,
628 GTK_RESPONSE_ACCEPT, NULL);
629 gtk_container_set_border_width(GTK_CONTAINER(about_dialog), 8);
630
631 label1 = gtk_label_new(NULL);
632 gtk_widget_show(label1);
633 gtk_label_set_markup(GTK_LABEL(label1), about_name);
634 g_free(about_name);
635 gtk_box_pack_start(
636 GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(about_dialog))),
637 label1, FALSE, FALSE, 0);
638
639 gtk_window_set_transient_for(GTK_WINDOW(about_dialog),
640 GTK_WINDOW(window));
641 gtk_window_set_position(GTK_WINDOW(about_dialog),
642 GTK_WIN_POS_CENTER_ON_PARENT);
643 gtk_dialog_run(GTK_DIALOG(about_dialog));
644
645 gtk_widget_destroy(about_dialog);
646 #endif
647 }
648
649 static void
activate_radio_action(GtkAction * action,GtkRadioAction * current,gpointer data)650 activate_radio_action(GtkAction *action, GtkRadioAction *current,
651 gpointer data)
652 {
653 WordListWindow *window;
654 gboolean active;
655 guint value;
656
657 window = WORD_LIST_WINDOW(data);
658 active = gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(current));
659 value = gtk_radio_action_get_current_value(GTK_RADIO_ACTION(current));
660
661 if (active) {
662 if (value != window->dictionary_type) {
663 GtkWidget *newwin;
664
665 newwin = word_list_window_new(value);
666
667 /* quit */
668 if (WORD_LIST_VIEW(WORD_LIST_WINDOW(newwin)->word_list)->dict == NULL) {
669 gtk_main_quit();
670 }
671
672 g_signal_handlers_disconnect_by_func(G_OBJECT(window),
673 (gpointer)(uintptr_t)dict_window_destroy_cb,
674 NULL);
675 gtk_widget_destroy(GTK_WIDGET(window));
676
677 g_signal_connect(G_OBJECT(newwin), "destroy",
678 G_CALLBACK(dict_window_destroy_cb), NULL);
679 gtk_widget_show(newwin);
680 }
681 }
682 }
683
684 /*
685 * call back functions for WordListView
686 */
687 static gboolean
word_list_button_press_cb(GtkWidget * widget,GdkEventButton * event,WordListWindow * window)688 word_list_button_press_cb(GtkWidget *widget, GdkEventButton *event,
689 WordListWindow *window)
690 {
691 if (event->button == 2 && event->type == GDK_BUTTON_PRESS) {
692 ACTIVATE_ACTION(window, "EditWord");
693 } else if (event->button == 3) {
694 current_button_event = event;
695 ACTIVATE_ACTION(window, "PopupMenu");
696 current_button_event = NULL;
697 }
698
699 return FALSE;
700 }
701
702 static gboolean
word_list_row_activated_cb(GtkWidget * widget,GtkTreePath * path,GtkTreeViewColumn * column,WordListWindow * window)703 word_list_row_activated_cb(GtkWidget *widget, GtkTreePath *path,
704 GtkTreeViewColumn *column, WordListWindow *window)
705 {
706 ACTIVATE_ACTION(window, "EditWord");
707
708 return FALSE;
709 }
710
711 static gboolean
word_list_key_press_cb(GtkWidget * widget,GdkEventKey * event,WordListWindow * window)712 word_list_key_press_cb(GtkWidget *widget, GdkEventKey *event,
713 WordListWindow *window)
714 {
715 switch (event->keyval) {
716 case GDK_Delete:
717 case GDK_BackSpace:
718 ACTIVATE_ACTION(window, "RemoveWord");
719 break;
720 default:
721 break;
722 }
723
724 return FALSE;
725 }
726
727 static void
word_list_selection_changed_cb(GtkTreeSelection * selection,WordListWindow * window)728 word_list_selection_changed_cb(GtkTreeSelection *selection,
729 WordListWindow *window)
730 {
731 word_list_window_set_sensitive(window);
732 }
733
734
735 /*
736 * call back functions for WordWindow
737 */
738 static void
wordwin_response_cb(WordWindow * dialog,WordListWindow * window)739 wordwin_response_cb(WordWindow *dialog, WordListWindow *window)
740 {
741 word_list_view_refresh(WORD_LIST_VIEW(window->word_list));
742 }
743