#include "gcin.h" #include "gcin-conf.h" #include "gtab.h" struct { char *keystr; int keynum; } imkeys[] = { {"Control-Space", Control_Space}, {"Shift-Space", Shift_Space}, {"Alt-Space", Alt_Space}, {"Windows-Space", Windows_Space}, { NULL, 0}, }; static GtkWidget *gtablist_window = NULL; static GtkWidget *vbox; static GtkWidget *hbox; static GtkWidget *sw; static GtkWidget *treeview; static GtkWidget *button, *check_button_phonetic_speak, *opt_speaker_opts; static GtkWidget *opt_im_toggle_keys, *check_button_gcin_remote_client, *check_button_gcin_shift_space_eng_full; *check_button_gcin_init_im_enabled; *check_button_gcin_eng_phrase_enabled; char *pho_speaker[16]; int pho_speakerN; typedef struct { gchar *name; GdkPixbuf *icon; gchar *key; gchar *file; gboolean used; gboolean default_inmd; gboolean editable; } Item; enum { COLUMN_NAME, COLUMN_ICON, COLUMN_KEY, COLUMN_FILE, COLUMN_USE, COLUMN_DEFAULT_INMD, COLUMN_EDITABLE, NUM_COLUMNS }; static GArray *articles = NULL; static int qcmp_key(const void *aa, const void *bb) { Item *a=(Item *)aa, *b=(Item *)bb; return gcin_switch_keys_lookup(a->key[0]) - gcin_switch_keys_lookup(b->key[0]); } extern char *TableDir; void get_icon_path(char *iconame, char fname[]); extern char gcin_switch_keys[]; static void add_items (void) { Item foo; g_return_if_fail (articles != NULL); load_gtab_list(); int i; for (i=1; i <= MAX_GTAB_NUM_KEY; i++) { INMD *pinmd = &inmd[i]; char *name = pinmd->cname; if (!name) continue; char key[2]; char *file = pinmd->filename; char *icon = pinmd->icon; key[0] = gcin_switch_keys[i]; key[1]=0; foo.name = g_strdup(name); char icon_path[128]; get_icon_path(icon, icon_path); GError *err = NULL; foo.icon = gdk_pixbuf_new_from_file(icon_path, &err); foo.key = g_strdup(key); foo.file = g_strdup(file); foo.used = (gcin_flags_im_enabled & (1 << i)) != 0; foo.default_inmd = default_input_method == i; foo.editable = FALSE; g_array_append_vals (articles, &foo, 1); } g_array_sort (articles,qcmp_key); } static GtkTreeModel * create_model (void) { gint i = 0; GtkListStore *model; GtkTreeIter iter; /* create array */ articles = g_array_sized_new (FALSE, FALSE, sizeof (Item), 1); add_items (); /* create list store */ model = gtk_list_store_new (NUM_COLUMNS,G_TYPE_STRING, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN); /* add items */ for (i = 0; i < articles->len; i++) { gtk_list_store_append (model, &iter); gtk_list_store_set (model, &iter, COLUMN_NAME, g_array_index (articles, Item, i).name, COLUMN_ICON, g_array_index (articles, Item, i).icon, COLUMN_KEY, g_array_index (articles, Item, i).key, COLUMN_FILE, g_array_index (articles, Item, i).file, COLUMN_USE, g_array_index (articles, Item, i).used, COLUMN_DEFAULT_INMD, g_array_index (articles, Item, i).default_inmd, COLUMN_EDITABLE, g_array_index (articles, Item, i).editable, -1); } return GTK_TREE_MODEL (model); } #define DEFAULT_INPUT_METHOD "default-input-method" static void cb_ok (GtkWidget *button, gpointer data) { save_gcin_conf_int(DEFAULT_INPUT_METHOD, default_input_method); int idx = gtk_option_menu_get_history (GTK_OPTION_MENU (opt_im_toggle_keys)); save_gcin_conf_int(GCIN_IM_TOGGLE_KEYS, imkeys[idx].keynum); save_gcin_conf_int(GCIN_FLAGS_IM_ENABLED, gcin_flags_im_enabled); save_gcin_conf_int(GCIN_REMOTE_CLIENT, gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(check_button_gcin_remote_client))); save_gcin_conf_int(GCIN_SHIFT_SPACE_ENG_FULL, gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(check_button_gcin_shift_space_eng_full))); save_gcin_conf_int(GCIN_INIT_IM_ENABLED, gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(check_button_gcin_init_im_enabled))); save_gcin_conf_int(GCIN_ENG_PHRASE_ENABLED, gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(check_button_gcin_eng_phrase_enabled))); if (opt_speaker_opts) { idx = gtk_option_menu_get_history (GTK_OPTION_MENU (opt_speaker_opts)); save_gcin_conf_str(PHONETIC_SPEAK_SEL, pho_speaker[idx]); } save_gcin_conf_int(PHONETIC_SPEAK, gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(check_button_phonetic_speak))); gtk_widget_destroy(gtablist_window); gtablist_window = NULL; send_gcin_message(GDK_DISPLAY(), "reload"); } static void cb_cancel (GtkWidget *widget, gpointer data) { gtk_widget_destroy(gtablist_window); gtablist_window = NULL; } static gboolean toggled (GtkCellRendererToggle *cell, gchar *path_string, gpointer data) { GtkTreeModel *model = GTK_TREE_MODEL (data); GtkTreeIter iter; GtkTreePath *path = gtk_tree_path_new_from_string (path_string); gboolean value; printf("toggled\n"); gtk_tree_model_get_iter (model, &iter, path); gtk_tree_model_get (model, &iter, COLUMN_USE, &value, -1); int i = gtk_tree_path_get_indices (path)[0]; char *key=g_array_index (articles, Item, i).key; int in_no = gcin_switch_keys_lookup(key[0]); if (in_no < 0) return; gcin_flags_im_enabled ^= 1 << in_no; value ^= 1; gtk_list_store_set (GTK_LIST_STORE (model), &iter, COLUMN_USE, value, -1); gtk_tree_path_free (path); return TRUE; } static void clear_all(GtkTreeModel *model) { GtkTreeIter iter; if (!gtk_tree_model_get_iter_first(model, &iter)) return; do { char *tkey; gtk_tree_model_get(model,&iter, COLUMN_KEY, &tkey, -1); gtk_list_store_set (GTK_LIST_STORE (model), &iter, COLUMN_DEFAULT_INMD, 0, -1); } while (gtk_tree_model_iter_next(model, &iter)); } static gboolean toggled_default_inmd(GtkCellRendererToggle *cell, gchar *path_string, gpointer data) { GtkTreeModel *model = GTK_TREE_MODEL (data); clear_all(model); GtkTreeIter iter; GtkTreePath *path = gtk_tree_path_new_from_string (path_string); // dbg("toggled_default_inmd\n"); gtk_tree_model_get_iter (model, &iter, path); int i = gtk_tree_path_get_indices (path)[0]; char *key=g_array_index (articles, Item, i).key; default_input_method = gcin_switch_keys_lookup(key[0]); dbg("default_input_method %d %c\n", default_input_method, key[0]); if (default_input_method < 0) default_input_method = 6; gtk_list_store_set (GTK_LIST_STORE (model), &iter, COLUMN_DEFAULT_INMD, TRUE, -1); gtk_tree_path_free (path); return TRUE; } static void add_columns (GtkTreeView *treeview) { GtkCellRenderer *renderer; GtkTreeModel *model = gtk_tree_view_get_model (treeview); /* name column */ renderer = gtk_cell_renderer_text_new (); g_object_set_data (G_OBJECT (renderer), "column", (gint *)COLUMN_NAME); gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (treeview), -1, _("名稱"), renderer, "text", COLUMN_NAME, "editable", COLUMN_EDITABLE, NULL); renderer = gtk_cell_renderer_pixbuf_new(); g_object_set_data (G_OBJECT (renderer), "column", (gint *)COLUMN_ICON); gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (treeview), -1, _("icon"), renderer, "pixbuf", COLUMN_ICON, // "editable", COLUMN_EDITABLE, NULL); renderer = gtk_cell_renderer_text_new (); g_object_set_data (G_OBJECT (renderer), "column", (gint *)COLUMN_KEY); gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (treeview), -1, _("Ctrl-Alt-鍵"), renderer, "text", COLUMN_KEY, "editable", COLUMN_EDITABLE, NULL); renderer = gtk_cell_renderer_text_new (); g_object_set_data (G_OBJECT (renderer), "column", (gint *)COLUMN_FILE); gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (treeview), -1, _("檔案名"), renderer, "text", COLUMN_FILE, "editable", COLUMN_EDITABLE, NULL); // use column renderer = gtk_cell_renderer_toggle_new (); g_signal_connect (G_OBJECT (renderer), "toggled", G_CALLBACK (toggled), model); g_object_set (G_OBJECT (renderer), "xalign", 0.0, NULL); gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (treeview), -1, _("Ctrl-Shift 循環"), renderer, "active", COLUMN_USE, NULL); // default_inmd column renderer = gtk_cell_renderer_toggle_new (); g_signal_connect (G_OBJECT (renderer), "toggled", G_CALLBACK (toggled_default_inmd), model); g_object_set (G_OBJECT (renderer), "xalign", 0.0, NULL); gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (treeview), -1, _("第一次內定"), renderer, "active", COLUMN_DEFAULT_INMD, NULL); } static void callback_win_delete() { gtk_widget_destroy(gtablist_window); gtablist_window = NULL; } void set_selection_by_key(int key) { if (!treeview) return; GtkTreeSelection *selection=gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview)); GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(treeview)); GtkTreeIter iter; gboolean found=FALSE; if (!gtk_tree_model_get_iter_first(model, &iter)) return; do { char *tkey; gtk_tree_model_get(model,&iter, COLUMN_KEY, &tkey,-1); if (atoi(tkey) == key) { found=TRUE; break; } } while (gtk_tree_model_iter_next(model, &iter)); if (found) gtk_tree_selection_select_iter(selection,&iter); } static GtkWidget *create_im_toggle_keys() { GtkWidget *hbox = gtk_hbox_new (FALSE, 1); GtkWidget *label = gtk_label_new(_("輸入視窗(開啟/關閉)切換")); gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0); opt_im_toggle_keys = gtk_option_menu_new (); gtk_box_pack_start (GTK_BOX (hbox), opt_im_toggle_keys, FALSE, FALSE, 0); GtkWidget *menu_im_toggle_keys = gtk_menu_new (); int i, current_idx=0; for(i=0; imkeys[i].keystr; i++) { GtkWidget *item = gtk_menu_item_new_with_label (imkeys[i].keystr); if (imkeys[i].keynum == gcin_im_toggle_keys) current_idx = i; gtk_menu_shell_append (GTK_MENU_SHELL (menu_im_toggle_keys), item); } gtk_option_menu_set_menu (GTK_OPTION_MENU (opt_im_toggle_keys), menu_im_toggle_keys); gtk_option_menu_set_history (GTK_OPTION_MENU (opt_im_toggle_keys), current_idx); return hbox; } static GtkWidget *create_speaker_opts() { GtkWidget *hbox = gtk_hbox_new (FALSE, 1); opt_speaker_opts = gtk_option_menu_new (); gtk_box_pack_start (GTK_BOX (hbox), opt_speaker_opts, FALSE, FALSE, 0); GtkWidget *menu_speaker_opts = gtk_menu_new (); int i; int current_idx = get_current_speaker_idx(); for(i=0; i DIR *dir; if (dir=opendir(GCIN_OGG_DIR"/ㄧ")) { struct dirent *dire; pho_speakerN = 0; while (dire=readdir(dir)) { char *name = dire->d_name; if (name[0]=='.') continue; pho_speaker[pho_speakerN++]=strdup(name); } closedir(dir); dbg("pho_speakerN:%d\n", pho_speakerN); if (pho_speakerN) { GtkWidget *labelspeaker = gtk_label_new(_("發音選擇")); gtk_box_pack_start (GTK_BOX (hbox_phonetic_speak), labelspeaker, FALSE, FALSE, 0); gtk_container_add (GTK_CONTAINER (hbox_phonetic_speak), create_speaker_opts()); } } hbox = gtk_hbox_new (TRUE, 4); gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); button = gtk_button_new_from_stock (GTK_STOCK_CANCEL); g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (cb_cancel), treeview); gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0); button = gtk_button_new_from_stock (GTK_STOCK_OK); g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (cb_ok), model); gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0); gtk_window_set_default_size (GTK_WINDOW (gtablist_window), 520, 450); g_signal_connect (G_OBJECT (gtablist_window), "delete_event", G_CALLBACK (gtk_main_quit), NULL); gtk_widget_show_all (gtablist_window); set_selection_by_key(default_input_method); #if 0 g_signal_connect (G_OBJECT(tree_selection), "changed", G_CALLBACK (callback_row_selected), NULL); #endif }