1 /*
2 * Copyright (C) 2020 The HIME team, Taiwan
3 * Copyright (C) 2005-2011 Edward Der-Hua Liu, Hsin-Chu, Taiwan
4 * Copyright (C) 2012 Favonia <favonia@gmail.com>
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation version 2.1
9 * of the License.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #include "hime.h"
22
23 #include "gtab.h"
24 #include "hime-conf.h"
25
26 struct {
27 char *keystr;
28 int keynum;
29 } imkeys[] = {
30 {"Control-Space", Control_Space},
31 {"Shift-Space", Shift_Space},
32 {"Alt-Space", Alt_Space},
33 {"Windows-Space", Windows_Space},
34 {NULL, 0},
35 };
36
37 extern char *default_input_method_str;
38
39 /* XXX UI states hold uncommited preference.
40 * That's why we need these global variables. */
41 static GtkWidget *gtablist_widget = NULL;
42 static GtkWidget *vbox;
43 static GtkWidget *sw;
44 static GtkWidget *treeview;
45 static GtkWidget *check_button_phonetic_speak, *opt_speaker_opts, *check_button_hime_bell_off;
46 static GtkWidget *opt_im_toggle_keys, *check_button_hime_remote_client,
47 *check_button_hime_shift_space_eng_full,
48 *check_button_hime_init_im_enabled,
49 *check_button_hime_init_full_mode,
50 *check_button_hime_eng_phrase_enabled,
51 *check_button_hime_win_sym_click_close,
52 *check_button_hime_punc_auto_send;
53
54 static GtkWidget *check_button_hime_single_state;
55 extern gboolean button_order;
56
57 char *pho_speaker[16];
58 int pho_speakerN;
59
60 typedef struct
61 {
62 gchar *name;
63 GdkPixbuf *icon;
64 gchar *key;
65 gchar *file;
66 gboolean cycle;
67 gboolean default_inmd;
68 gboolean use;
69 gboolean editable;
70 INMD *pinmd;
71 } Item;
72
73 enum {
74 COLUMN_NAME,
75 COLUMN_ICON,
76 COLUMN_KEY,
77 COLUMN_FILE,
78 COLUMN_CYCLE,
79 COLUMN_DEFAULT_INMD,
80 COLUMN_USE,
81 COLUMN_EDITABLE,
82 COLUMN_PINMD,
83 NUM_COLUMNS
84 };
85
86 static GArray *articles = NULL;
87 int hime_switch_keys_lookup (int key);
88
89 #if 0
90 /* unused */
91 static int qcmp_key(const void *aa, const void *bb)
92 {
93 Item *a=(Item *)aa, *b=(Item *)bb;
94
95 return hime_switch_keys_lookup(a->key[0]) - hime_switch_keys_lookup(b->key[0]);
96 }
97 #endif
98
99 extern char *TableDir;
100 void get_icon_path (char *iconame, char fname[]);
101
102 static void
add_items(void)103 add_items (void) {
104 Item foo;
105
106 g_return_if_fail (articles != NULL);
107
108 load_gtab_list (FALSE);
109
110 int i;
111 for (i = 0; i < inmdN; i++) {
112 INMD *pinmd = &inmd[i];
113 char *name = pinmd->cname;
114 if (!name)
115 continue;
116
117 char key[2];
118 char *file = pinmd->filename;
119 char *icon = pinmd->icon;
120
121 key[0] = pinmd->key_ch;
122 key[1] = 0;
123
124 foo.name = g_strdup (name);
125 char icon_path[128];
126 get_icon_path (icon, icon_path);
127 GError *err = NULL;
128 foo.icon = gdk_pixbuf_new_from_file (icon_path, &err);
129 foo.key = g_strdup (key);
130 foo.file = g_strdup (file);
131 // dbg("%d] %d\n",i,pinmd->in_cycle);
132 foo.default_inmd = default_input_method == i;
133 foo.use = !pinmd->disabled;
134 foo.cycle = pinmd->in_cycle && foo.use;
135 foo.editable = FALSE;
136 foo.pinmd = pinmd;
137 g_array_append_vals (articles, &foo, 1);
138 }
139
140 // g_array_sort (articles,qcmp_key);
141 }
142
143 static GtkTreeModel *
create_model(void)144 create_model (void) {
145 gint i = 0;
146 GtkListStore *model;
147 GtkTreeIter iter;
148
149 /* create array */
150 articles = g_array_sized_new (FALSE, FALSE, sizeof (Item), 1);
151
152 add_items ();
153
154 /* create list store */
155 model = gtk_list_store_new (NUM_COLUMNS, G_TYPE_STRING, GDK_TYPE_PIXBUF,
156 G_TYPE_STRING,
157 G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN,
158 G_TYPE_BOOLEAN,
159 G_TYPE_BOOLEAN, G_TYPE_POINTER);
160
161 /* add items */
162 for (i = 0; i < articles->len; i++) {
163 gtk_list_store_append (model, &iter);
164
165 gtk_list_store_set (model, &iter,
166 COLUMN_NAME,
167 g_array_index (articles, Item, i).name,
168 COLUMN_ICON,
169 g_array_index (articles, Item, i).icon,
170 COLUMN_KEY,
171 g_array_index (articles, Item, i).key,
172 COLUMN_FILE,
173 g_array_index (articles, Item, i).file,
174 COLUMN_CYCLE,
175 g_array_index (articles, Item, i).cycle,
176 COLUMN_DEFAULT_INMD,
177 g_array_index (articles, Item, i).default_inmd,
178 COLUMN_USE,
179 g_array_index (articles, Item, i).use,
180 COLUMN_EDITABLE,
181 g_array_index (articles, Item, i).editable,
182 COLUMN_PINMD,
183 g_array_index (articles, Item, i).pinmd,
184 -1);
185 }
186
187 return GTK_TREE_MODEL (model);
188 }
189
190 extern char gtab_list[];
191
save_gtab_list()192 static void save_gtab_list () {
193 char ttt[128];
194 get_hime_user_fname (gtab_list, ttt);
195
196 FILE *fp;
197
198 if ((fp = fopen (ttt, "w")) == NULL)
199 p_err ("cannot write to %s\n", ttt);
200
201 int i;
202 for (i = 0; i < inmdN; i++) {
203 INMD *pinmd = &inmd[i];
204 char *name = pinmd->cname;
205 if (!name)
206 continue;
207
208 char *file = pinmd->filename;
209 char *icon = pinmd->icon;
210 char *disabled = pinmd->disabled ? "!" : "";
211
212 fprintf (fp, "%s%s %c %s %s\n", disabled, name, pinmd->key_ch, file, icon);
213 }
214
215 fclose (fp);
216 }
217
save_gtablist_conf()218 void save_gtablist_conf () {
219 if (gtablist_widget == NULL) {
220 fprintf (stderr, "save_gtablist_conf: gtablist_widget is NULL!\n");
221 return;
222 }
223
224 GtkTreeModel *model = gtk_tree_view_get_model ((GtkTreeView *) treeview);
225
226 GtkTreeIter iter;
227 if (!gtk_tree_model_get_iter_first (model, &iter))
228 return;
229
230 do {
231 char *tkey;
232 gtk_tree_model_get (model, &iter, COLUMN_KEY, &tkey, -1);
233 gboolean cycle, default_inmd, use;
234 gtk_tree_model_get (model, &iter, COLUMN_CYCLE, &cycle, -1);
235 gtk_tree_model_get (model, &iter, COLUMN_DEFAULT_INMD, &default_inmd, -1);
236 gtk_tree_model_get (model, &iter, COLUMN_USE, &use, -1);
237 INMD *pinmd;
238 gtk_tree_model_get (model, &iter, COLUMN_PINMD, &pinmd, -1);
239 pinmd->in_cycle = cycle;
240 pinmd->disabled = !use;
241 } while (gtk_tree_model_iter_next (model, &iter));
242
243 dbg ("default_input_method_str %s\n", default_input_method_str);
244 save_hime_conf_str (DEFAULT_INPUT_METHOD, default_input_method_str);
245
246 int idx;
247 idx = gtk_combo_box_get_active (GTK_COMBO_BOX (opt_im_toggle_keys));
248 save_hime_conf_int (HIME_IM_TOGGLE_KEYS, imkeys[idx].keynum);
249
250 free (hime_str_im_cycle);
251
252 int i;
253 char tt[512];
254 int ttN = 0;
255 for (i = 0; i < inmdN; i++) {
256 if (inmd[i].in_cycle) {
257 dbg ("in %d %c\n", i, inmd[i].key_ch);
258 tt[ttN++] = inmd[i].key_ch;
259 }
260 }
261 tt[ttN] = 0;
262 hime_str_im_cycle = strdup (tt);
263 save_hime_conf_str (HIME_STR_IM_CYCLE, hime_str_im_cycle);
264 dbg ("hime_str_im_cycle ttN:%d '%s' '%s'\n", ttN, hime_str_im_cycle, tt);
265
266 save_hime_conf_int (HIME_REMOTE_CLIENT,
267 gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (check_button_hime_remote_client)));
268 save_hime_conf_int (HIME_SHIFT_SPACE_ENG_FULL,
269 gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (check_button_hime_shift_space_eng_full)));
270
271 save_hime_conf_int (HIME_INIT_IM_ENABLED,
272 gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (check_button_hime_init_im_enabled)));
273
274 save_hime_conf_int (HIME_INIT_FULL_MODE,
275 gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (check_button_hime_init_full_mode)));
276
277 save_hime_conf_int (HIME_ENG_PHRASE_ENABLED,
278 gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (check_button_hime_eng_phrase_enabled)));
279
280 save_hime_conf_int (HIME_WIN_SYM_CLICK_CLOSE,
281 gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (check_button_hime_win_sym_click_close)));
282
283 save_hime_conf_int (HIME_BELL_OFF,
284 gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (check_button_hime_bell_off)));
285
286 save_hime_conf_int (HIME_PUNC_AUTO_SEND,
287 gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (check_button_hime_punc_auto_send)));
288 save_hime_conf_int (HIME_SINGLE_STATE,
289 gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (check_button_hime_single_state)));
290 if (opt_speaker_opts) {
291 idx = gtk_combo_box_get_active (GTK_COMBO_BOX (opt_speaker_opts));
292 save_hime_conf_str (PHONETIC_SPEAK_SEL, pho_speaker[idx]);
293 }
294
295 save_gtab_list ();
296
297 save_hime_conf_int (PHONETIC_SPEAK,
298 gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (check_button_phonetic_speak)));
299
300 save_omni_config ();
301 /* caleb- did not found where "reload" is used.
302 * caleb- think the send_hime_message() here does nothing.
303 */
304 send_hime_message (GDK_DISPLAY (), "reload");
305 }
306
destroy_gtablist_widget()307 void destroy_gtablist_widget () {
308 gtk_widget_destroy (gtablist_widget);
309 gtablist_widget = NULL;
310 }
311
312 int hime_switch_keys_lookup (int key);
313 #if 1
toggled(GtkCellRendererToggle * cell,gchar * path_string,gpointer data)314 static gboolean toggled (GtkCellRendererToggle *cell, gchar *path_string, gpointer data) {
315 GtkTreeModel *model = GTK_TREE_MODEL (data);
316 GtkTreeIter iter;
317 GtkTreePath *path = gtk_tree_path_new_from_string (path_string);
318 gboolean cycle;
319
320 dbg ("toggled\n");
321
322 gtk_tree_model_get_iter (model, &iter, path);
323 gtk_tree_model_get (model, &iter, COLUMN_CYCLE, &cycle, -1);
324
325 cycle ^= 1;
326 gtk_list_store_set (GTK_LIST_STORE (model), &iter, COLUMN_CYCLE, cycle, -1);
327
328 if (cycle) {
329 gtk_list_store_set (GTK_LIST_STORE (model), &iter, COLUMN_USE, TRUE, -1);
330 }
331
332 gtk_tree_path_free (path);
333
334 return TRUE;
335 }
336 #endif
337
clear_col_default_inmd(GtkTreeModel * model)338 static void clear_col_default_inmd (GtkTreeModel *model) {
339 GtkTreeIter iter;
340
341 if (!gtk_tree_model_get_iter_first (model, &iter))
342 return;
343
344 do {
345 char *tkey;
346 gtk_tree_model_get (model, &iter, COLUMN_KEY, &tkey, -1);
347 gtk_list_store_set (GTK_LIST_STORE (model), &iter, COLUMN_DEFAULT_INMD, 0, -1);
348
349 } while (gtk_tree_model_iter_next (model, &iter));
350 }
351
toggled_default_inmd(GtkCellRendererToggle * cell,gchar * path_string,gpointer data)352 static gboolean toggled_default_inmd (GtkCellRendererToggle *cell, gchar *path_string, gpointer data) {
353 GtkTreeModel *model = GTK_TREE_MODEL (data);
354 clear_col_default_inmd (model);
355 GtkTreeIter iter;
356 GtkTreePath *path = gtk_tree_path_new_from_string (path_string);
357
358 // dbg("toggled_default_inmd\n");
359 gtk_tree_model_get_iter (model, &iter, path);
360 char *key;
361 gtk_tree_model_get (model, &iter, COLUMN_KEY, &key, -1);
362 char *file;
363 gtk_tree_model_get (model, &iter, COLUMN_FILE, &file, -1);
364 char tt[128];
365 snprintf (tt, sizeof (tt), "%s %s", key, file);
366 free (default_input_method_str);
367 default_input_method_str = strdup (tt);
368 dbg ("default_input_method_str %s\n", default_input_method_str);
369 // default_input_method = hime_switch_keys_lookup(key[0]);
370
371 gtk_list_store_set (GTK_LIST_STORE (model), &iter, COLUMN_DEFAULT_INMD, TRUE, -1);
372 gtk_list_store_set (GTK_LIST_STORE (model), &iter, COLUMN_USE, TRUE, -1);
373
374 gtk_tree_path_free (path);
375
376 return TRUE;
377 }
378
toggled_use(GtkCellRendererToggle * cell,gchar * path_string,gpointer data)379 static gboolean toggled_use (GtkCellRendererToggle *cell, gchar *path_string, gpointer data) {
380 GtkTreeModel *model = GTK_TREE_MODEL (data);
381 // clear_all(model);
382 GtkTreeIter iter;
383 GtkTreePath *path = gtk_tree_path_new_from_string (path_string);
384
385 // dbg("toggled_default_inmd\n");
386 gtk_tree_model_get_iter (model, &iter, path);
387 gboolean cycle, default_inmd, use;
388 gtk_tree_model_get (model, &iter, COLUMN_CYCLE, &cycle, -1);
389 gtk_tree_model_get (model, &iter, COLUMN_DEFAULT_INMD, &default_inmd, -1);
390 gtk_tree_model_get (model, &iter, COLUMN_USE, &use, -1);
391 use = !use;
392 gboolean must_on = default_inmd;
393 dbg ("toggle %d %d %d\n", cycle, default_inmd, use);
394
395 if (must_on && !use) {
396 return TRUE;
397 }
398
399 gtk_list_store_set (GTK_LIST_STORE (model), &iter, COLUMN_USE, use, -1);
400 if (!use)
401 gtk_list_store_set (GTK_LIST_STORE (model), &iter, COLUMN_CYCLE, FALSE, -1);
402
403 gtk_tree_path_free (path);
404
405 return TRUE;
406 }
407
408 static void
add_columns(GtkTreeView * treeview)409 add_columns (GtkTreeView *treeview) {
410 GtkCellRenderer *renderer;
411 GtkTreeModel *model = gtk_tree_view_get_model (treeview);
412
413 /* name column */
414
415 renderer = gtk_cell_renderer_text_new ();
416 g_object_set_data (G_OBJECT (renderer), "column", (gint *) COLUMN_NAME);
417 gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (treeview),
418 -1, _ ("Name"), renderer,
419 "text", COLUMN_NAME,
420 "editable", COLUMN_EDITABLE,
421 NULL);
422
423 renderer = gtk_cell_renderer_pixbuf_new ();
424 g_object_set_data (G_OBJECT (renderer), "column", (gint *) COLUMN_ICON);
425 gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (treeview),
426 -1, "圖示", renderer,
427 "pixbuf", COLUMN_ICON,
428 // "editable", COLUMN_EDITABLE,
429 NULL);
430
431 renderer = gtk_cell_renderer_text_new ();
432 g_object_set_data (G_OBJECT (renderer), "column", (gint *) COLUMN_KEY);
433
434 gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (treeview),
435 -1, _ ("Ctrl-Alt-Toggle Key"), renderer,
436 "text", COLUMN_KEY,
437 "editable", COLUMN_EDITABLE,
438 NULL);
439
440 // cycle column
441 renderer = gtk_cell_renderer_toggle_new ();
442 g_signal_connect (G_OBJECT (renderer), "toggled",
443 G_CALLBACK (toggled), model);
444
445 g_object_set (G_OBJECT (renderer), "xalign", 0.0, NULL);
446
447 gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (treeview), -1,
448 _ ("Ctrl-Shift selections"),
449 renderer, "active", COLUMN_CYCLE,
450 NULL);
451
452 // default_inmd column
453 renderer = gtk_cell_renderer_toggle_new ();
454 gtk_cell_renderer_toggle_set_radio (GTK_CELL_RENDERER_TOGGLE (renderer), TRUE);
455 g_signal_connect (G_OBJECT (renderer), "toggled",
456 G_CALLBACK (toggled_default_inmd), model);
457
458 g_object_set (G_OBJECT (renderer), "xalign", 0.0, NULL);
459
460 gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (treeview),
461 -1, _ ("Default"),
462
463 renderer,
464 "active", COLUMN_DEFAULT_INMD,
465 NULL);
466
467 // use
468 renderer = gtk_cell_renderer_toggle_new ();
469 g_signal_connect (G_OBJECT (renderer), "toggled",
470 G_CALLBACK (toggled_use), model);
471
472 g_object_set (G_OBJECT (renderer), "xalign", 0.0, NULL);
473
474 gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (treeview),
475 -1, _ ("Enable"),
476 renderer,
477 "active", COLUMN_USE,
478 NULL);
479
480 renderer = gtk_cell_renderer_text_new ();
481 g_object_set_data (G_OBJECT (renderer), "column", (gint *) COLUMN_FILE);
482
483 gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (treeview),
484 -1, _ ("File Name"), renderer,
485 "text", COLUMN_FILE,
486 "editable", COLUMN_EDITABLE,
487 NULL);
488 }
489
set_selection_by_key(int key)490 void set_selection_by_key (int key) {
491 if (!treeview)
492 return;
493
494 GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
495 GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW (treeview));
496 GtkTreeIter iter;
497 gboolean found = FALSE;
498
499 if (!gtk_tree_model_get_iter_first (model, &iter))
500 return;
501
502 do {
503 char *tkey;
504
505 gtk_tree_model_get (model, &iter, COLUMN_KEY, &tkey, -1);
506
507 if (atoi (tkey) == key) {
508 found = TRUE;
509 break;
510 }
511 } while (gtk_tree_model_iter_next (model, &iter));
512
513 if (found)
514 gtk_tree_selection_select_iter (selection, &iter);
515 }
516
create_im_toggle_keys()517 static GtkWidget *create_im_toggle_keys () {
518
519 GtkWidget *hbox = gtk_hbox_new (FALSE, 1);
520 GtkWidget *label = gtk_label_new (_ ("Toggle input window"));
521 gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
522
523 opt_im_toggle_keys = gtk_combo_box_text_new ();
524 gtk_box_pack_start (GTK_BOX (hbox), opt_im_toggle_keys, FALSE, FALSE, 0);
525
526 int i, current_idx = 0;
527
528 for (i = 0; imkeys[i].keystr; i++) {
529 if (imkeys[i].keynum == hime_im_toggle_keys)
530 current_idx = i;
531 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (opt_im_toggle_keys), imkeys[i].keystr);
532 }
533
534 gtk_combo_box_set_active (GTK_COMBO_BOX (opt_im_toggle_keys), current_idx);
535
536 return hbox;
537 }
538
539 int get_current_speaker_idx ();
540
create_speaker_opts()541 static GtkWidget *create_speaker_opts () {
542 GtkWidget *hbox = gtk_hbox_new (FALSE, 1);
543
544 opt_speaker_opts = gtk_combo_box_text_new ();
545 gtk_box_pack_start (GTK_BOX (hbox), opt_speaker_opts, FALSE, FALSE, 0);
546
547 int i;
548 int current_idx = get_current_speaker_idx ();
549
550 for (i = 0; i < pho_speakerN; i++) {
551 if (imkeys[i].keynum == hime_im_toggle_keys)
552 current_idx = i;
553 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (opt_speaker_opts), pho_speaker[i]);
554 }
555
556 gtk_combo_box_set_active (GTK_COMBO_BOX (opt_speaker_opts), current_idx);
557
558 return hbox;
559 }
560
561 #include <dirent.h>
562
create_gtablist_widget()563 GtkWidget *create_gtablist_widget () {
564 if (gtablist_widget != NULL)
565 fprintf (stderr, "create_gtablist_widget: gtablist_widget was not NULL!\n");
566
567 load_settings ();
568
569 GtkWidget *box = gtk_vbox_new (FALSE, 0);
570 gtk_orientable_set_orientation (GTK_ORIENTABLE (box), GTK_ORIENTATION_VERTICAL);
571 gtablist_widget = box;
572
573 vbox = gtk_vbox_new (FALSE, 0);
574 gtk_orientable_set_orientation (GTK_ORIENTABLE (vbox), GTK_ORIENTATION_VERTICAL);
575 gtk_box_pack_start (GTK_BOX (box), vbox, TRUE, TRUE, 0);
576
577 sw = gtk_scrolled_window_new (NULL, NULL);
578 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw),
579 GTK_SHADOW_ETCHED_IN);
580 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
581 GTK_POLICY_NEVER,
582 GTK_POLICY_AUTOMATIC);
583 gtk_box_pack_start (GTK_BOX (vbox), sw, TRUE, TRUE, 0);
584
585 /* create model */
586 GtkTreeModel *model = create_model ();
587
588 /* create tree view */
589 treeview = gtk_tree_view_new_with_model (model);
590 gtk_widget_set_hexpand (treeview, TRUE);
591 gtk_widget_set_vexpand (treeview, TRUE);
592 g_object_unref (G_OBJECT (model));
593 gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (treeview), TRUE);
594
595 GtkTreeSelection *tree_selection =
596 gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
597 gtk_tree_selection_set_mode (tree_selection, GTK_SELECTION_SINGLE);
598
599 add_columns (GTK_TREE_VIEW (treeview));
600
601 gtk_container_add (GTK_CONTAINER (sw), treeview);
602
603 {
604 // Trying to get correct size of dialog_data->treeview, then put it into a gtk_scrolled_window
605 /* XXX Favonia: is this necessary? */
606 gtk_widget_show_all (gtablist_widget);
607
608 GtkRequisition requisition;
609 gtk_widget_get_child_requisition (treeview, &requisition);
610 gtk_widget_set_size_request (vbox, requisition.width, 240);
611 }
612
613 vbox = gtk_vbox_new (FALSE, 0);
614 gtk_orientable_set_orientation (GTK_ORIENTABLE (vbox), GTK_ORIENTATION_VERTICAL);
615 gtk_box_pack_start (GTK_BOX (box), vbox, FALSE, FALSE, 0);
616
617 gtk_box_pack_start (GTK_BOX (vbox), create_im_toggle_keys (), FALSE, FALSE, 0);
618
619 GtkWidget *hbox_hime_remote_client = gtk_hbox_new (FALSE, 10);
620 gtk_box_pack_start (GTK_BOX (vbox), hbox_hime_remote_client, FALSE, FALSE, 0);
621 check_button_hime_remote_client = gtk_check_button_new_with_label (_ ("Remote client support (port 9999-)"));
622 gtk_box_pack_start (GTK_BOX (hbox_hime_remote_client), check_button_hime_remote_client, FALSE, FALSE, 0);
623 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check_button_hime_remote_client),
624 hime_remote_client);
625
626 GtkWidget *hbox_hime_init_im_enabled = gtk_hbox_new (FALSE, 10);
627 gtk_box_pack_start (GTK_BOX (vbox), hbox_hime_init_im_enabled, FALSE, FALSE, 0);
628 check_button_hime_init_im_enabled = gtk_check_button_new_with_label (_ ("Toggle On inputing mode by default (non-XIM only)"));
629 gtk_box_pack_start (GTK_BOX (hbox_hime_init_im_enabled), check_button_hime_init_im_enabled, FALSE, FALSE, 0);
630 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check_button_hime_init_im_enabled),
631 hime_init_im_enabled);
632
633 GtkWidget *hbox_hime_init_full_mode = gtk_hbox_new (FALSE, 10);
634 gtk_box_pack_start (GTK_BOX (vbox), hbox_hime_init_full_mode, FALSE, FALSE, 0);
635 check_button_hime_init_full_mode = gtk_check_button_new_with_label (_ ("Toggle Full-shape mode by default"));
636 gtk_box_pack_start (GTK_BOX (hbox_hime_init_full_mode), check_button_hime_init_full_mode, FALSE, FALSE, 0);
637 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check_button_hime_init_full_mode),
638 hime_init_full_mode);
639
640 GtkWidget *hbox_hime_shift_space_eng_full = gtk_hbox_new (FALSE, 10);
641 gtk_box_pack_start (GTK_BOX (vbox), hbox_hime_shift_space_eng_full, FALSE, FALSE, 0);
642 check_button_hime_shift_space_eng_full = gtk_check_button_new_with_label (_ ("Toggle half-/double-width with Shift-Space"));
643 gtk_box_pack_start (GTK_BOX (hbox_hime_shift_space_eng_full), check_button_hime_shift_space_eng_full, FALSE, FALSE, 0);
644 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check_button_hime_shift_space_eng_full),
645 hime_shift_space_eng_full);
646
647 GtkWidget *hbox_hime_single_state = gtk_hbox_new (FALSE, 10);
648 gtk_box_pack_start (GTK_BOX (vbox), hbox_hime_single_state, FALSE, FALSE, 0);
649 check_button_hime_single_state = gtk_check_button_new_with_label (_ ("Share input method state for all processes"));
650 gtk_box_pack_start (GTK_BOX (hbox_hime_single_state), check_button_hime_single_state, FALSE, FALSE, 0);
651 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check_button_hime_single_state),
652 hime_single_state);
653
654 GtkWidget *hbox_hime_eng_phrase_enabled = gtk_hbox_new (FALSE, 10);
655 gtk_box_pack_start (GTK_BOX (vbox), hbox_hime_eng_phrase_enabled, FALSE, FALSE, 0);
656 check_button_hime_eng_phrase_enabled = gtk_check_button_new_with_label (_ ("Enable Alt-Shift phrases in alphabet-numeric mode"));
657 gtk_box_pack_start (GTK_BOX (hbox_hime_eng_phrase_enabled), check_button_hime_eng_phrase_enabled, FALSE, FALSE, 0);
658 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check_button_hime_eng_phrase_enabled),
659 hime_eng_phrase_enabled);
660
661 GtkWidget *hbox_phonetic_speak = gtk_hbox_new (FALSE, 10);
662 gtk_box_pack_start (GTK_BOX (vbox), hbox_phonetic_speak, FALSE, FALSE, 0);
663 check_button_phonetic_speak = gtk_check_button_new_with_label (_ ("Enable text-to-speech"));
664 gtk_box_pack_start (GTK_BOX (hbox_phonetic_speak), check_button_phonetic_speak, FALSE, FALSE, 0);
665 gtk_toggle_button_set_active (
666 GTK_TOGGLE_BUTTON (check_button_phonetic_speak), phonetic_speak);
667
668 GtkWidget *hbox_hime_win_sym_click_close = gtk_hbox_new (FALSE, 10);
669 gtk_box_pack_start (GTK_BOX (vbox), hbox_hime_win_sym_click_close, FALSE, FALSE, 0);
670 check_button_hime_win_sym_click_close = gtk_check_button_new_with_label (_ ("Close symbols window after selection"));
671 gtk_box_pack_start (GTK_BOX (hbox_hime_win_sym_click_close), check_button_hime_win_sym_click_close, FALSE, FALSE, 0);
672 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check_button_hime_win_sym_click_close),
673 hime_win_sym_click_close);
674
675 GtkWidget *hbox_hime_bell_off = gtk_hbox_new (FALSE, 10);
676 gtk_box_pack_start (GTK_BOX (vbox), hbox_hime_bell_off, FALSE, FALSE, 0);
677 check_button_hime_bell_off = gtk_check_button_new_with_label (_ ("Disable beep"));
678 gtk_box_pack_start (GTK_BOX (hbox_hime_bell_off), check_button_hime_bell_off, FALSE, FALSE, 0);
679 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check_button_hime_bell_off),
680 hime_bell_off);
681
682 GtkWidget *hbox_hime_punc_auto_send = gtk_hbox_new (FALSE, 10);
683 gtk_box_pack_start (GTK_BOX (vbox), hbox_hime_punc_auto_send, FALSE, FALSE, 0);
684 check_button_hime_punc_auto_send = gtk_check_button_new_with_label (_ ("Auto-commit words ended with punctuation"));
685 gtk_box_pack_start (GTK_BOX (hbox_hime_punc_auto_send), check_button_hime_punc_auto_send, FALSE, FALSE, 0);
686 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check_button_hime_punc_auto_send),
687 hime_punc_auto_send);
688
689 DIR *dir;
690 if ((dir = opendir (HIME_OGG_DIR "/ㄧ"))) {
691 struct dirent *dire;
692
693 pho_speakerN = 0;
694 while ((dire = readdir (dir))) {
695 char *name = dire->d_name;
696
697 if (name[0] == '.')
698 continue;
699 pho_speaker[pho_speakerN++] = strdup (name);
700 }
701 closedir (dir);
702
703 dbg ("pho_speakerN:%d\n", pho_speakerN);
704 }
705
706 if (pho_speakerN) {
707 GtkWidget *labelspeaker = gtk_label_new (_ ("speaker"));
708 gtk_box_pack_start (GTK_BOX (hbox_phonetic_speak), labelspeaker, FALSE, FALSE, 0);
709 gtk_container_add (GTK_CONTAINER (hbox_phonetic_speak), create_speaker_opts ());
710 }
711
712 return gtablist_widget;
713 }
714