bf8abba7d990375fd7563feda98e425691aedbf2
[platform/core/uifw/ise-engine-hangul.git] / src / scim_hangul_imengine_setup.cpp
1 /** @file scim_hangul_imengine_setup.cpp
2  * implementation of Setup Module of hangul imengine module.
3  */
4
5 /*
6  * Smart Common Input Method
7  * 
8  * Copyright (C) 2004-2006 Choe Hwanjin
9  * Copyright (c) 2004-2006 James Su <suzhe@turbolinux.com.cn>
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2 of the License, or
14  * (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
24  *
25  * $Id: scim_hangul_imengine_setup.cpp,v 1.8 2006/10/23 12:42:47 hwanjin Exp $
26  *
27  */
28
29 #define Uses_SCIM_CONFIG_BASE
30
31 #include <gtk/gtk.h>
32
33 #ifdef HAVE_CONFIG_H
34   #include <config.h>
35 #endif
36
37 #include <scim.h>
38 //#include <gtk/scimkeyselection.h>
39 #include <string.h>
40
41 #ifdef HAVE_GETTEXT
42   #include <libintl.h>
43   #define _(String) dgettext(GETTEXT_PACKAGE,String)
44   #define N_(String) (String)
45 #else
46   #define _(String) (String)
47   #define N_(String) (String)
48   #define bindtextdomain(Package,Directory)
49   #define textdomain(domain)
50   #define bind_textdomain_codeset(domain,codeset)
51 #endif
52
53 using namespace scim;
54
55 #define scim_module_init hangul_imengine_setup_LTX_scim_module_init
56 #define scim_module_exit hangul_imengine_setup_LTX_scim_module_exit
57
58 #define scim_setup_module_create_ui       hangul_imengine_setup_LTX_scim_setup_module_create_ui
59 #define scim_setup_module_get_category    hangul_imengine_setup_LTX_scim_setup_module_get_category
60 #define scim_setup_module_get_name        hangul_imengine_setup_LTX_scim_setup_module_get_name
61 #define scim_setup_module_get_description hangul_imengine_setup_LTX_scim_setup_module_get_description
62 #define scim_setup_module_load_config     hangul_imengine_setup_LTX_scim_setup_module_load_config
63 #define scim_setup_module_save_config     hangul_imengine_setup_LTX_scim_setup_module_save_config
64 #define scim_setup_module_query_changed   hangul_imengine_setup_LTX_scim_setup_module_query_changed
65
66
67 #define SCIM_CONFIG_IMENGINE_HANGUL_USE_DVORAK                  "/IMEngine/Hangul/UseDvorak"
68 #define SCIM_CONFIG_IMENGINE_HANGUL_SHOW_CANDIDATE_COMMENT      "/IMEngine/Hangul/ShowCandidateComment"
69 #define SCIM_CONFIG_IMENGINE_HANGUL_HANGUL_HANJA_KEY            "/IMEngine/Hangul/HangulHanjaKey"
70
71 #define SCIM_CONFIG_SHOW_CANDIDATE_COMMENT "/IMEngine/Hangul/ShowCandidateComment"
72 #define SCIM_CONFIG_LAYOUT                 "/IMEngine/Hangul/KeyboardLayout"
73 #define SCIM_CONFIG_HANGUL_KEY             "/IMEngine/Hangul/HangulKey"
74 #define SCIM_CONFIG_HANJA_KEY              "/IMEngine/Hangul/HanjaKey"
75 #define SCIM_CONFIG_HANJA_MODE_KEY         "/IMEngine/Hangul/HanjaModeKey"
76 #define SCIM_CONFIG_USE_ASCII_MODE         "/IMEngine/Hangul/UseAsciiMode"
77 #define SCIM_CONFIG_COMMIT_BY_WORD         "/IMEngine/Hangul/CommitByWord"
78
79
80 static GtkWidget * create_setup_window ();
81 static void        load_config (const ConfigPointer &config);
82 static void        save_config (const ConfigPointer &config);
83 static bool        query_changed ();
84
85 // Module Interface.
86 extern "C" {
87     void scim_module_init (void)
88     {
89         bindtextdomain (GETTEXT_PACKAGE, SCIM_HANGUL_LOCALEDIR);
90         bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
91     }
92
93     void scim_module_exit (void)
94     {
95     }
96
97     GtkWidget * scim_setup_module_create_ui (void)
98     {
99         static GtkWidget *setup_ui = NULL;
100         if (setup_ui == NULL)
101             setup_ui = create_setup_window ();
102         return setup_ui;
103     }
104
105     String scim_setup_module_get_category (void)
106     {
107         return String ("IMEngine");
108     }
109
110     String scim_setup_module_get_name (void)
111     {
112         return String (_("Hangul"));
113     }
114
115     String scim_setup_module_get_description (void)
116     {
117         return String (_("A Hangul IMEngine Module."));
118     }
119
120     void scim_setup_module_load_config (const ConfigPointer &config)
121     {
122         load_config (config);
123     }
124
125     void scim_setup_module_save_config (const ConfigPointer &config)
126     {
127         save_config (config);
128     }
129
130     bool scim_setup_module_query_changed ()
131     {
132         return query_changed ();
133     }
134 } // extern "C"
135
136 // Internal data structure
137 struct KeyBindingData
138 {
139     const char *key;
140     const char *label;
141     const char *title;
142     const char *tooltip;
143     GtkWidget  *entry;
144     GtkWidget  *button;
145     String      data;
146 };
147
148 static GtkWidget *keyboard_layout_combo = NULL;
149 static GtkWidget *use_ascii_mode_button = NULL;
150 static GtkWidget *commit_by_word_button = NULL;
151 static GtkWidget *show_candidate_comment_button = NULL;
152
153 static bool __have_changed                 = false;
154
155 static KeyBindingData key_bindings[] =
156 {
157     {
158         // key
159         SCIM_CONFIG_HANGUL_KEY,
160         // label
161         N_("Hangul keys:"),
162         // title
163         N_("Select Hangul keys"),
164         // tooltip
165         N_("The key events to change input mode between hangul and ascii."
166            "Click on the button on the right to edit it."),
167         // entry
168         NULL,
169         // button
170         NULL,
171         // data
172         "Hangul,"
173         "Shift+space"
174     },
175     {
176         // key
177         SCIM_CONFIG_HANJA_KEY,
178         // label
179         N_("Hangul to Hanja keys:"),
180         // title
181         N_("Select Hangul to Hanja keys"),
182         // tooltip
183         N_("The key events to convert Hangul to Hanja character. "
184            "Click on the button on the right to edit it."),
185         // entry
186         NULL,
187         // button
188         NULL,
189         // data
190         "Hangul_Hanja,"
191         "F9"
192     },
193     {
194         // key
195         SCIM_CONFIG_HANJA_MODE_KEY,
196         // label
197         N_("Hanja mode keys:"),
198         // title
199         N_("Select a key to toggle hanja mode keys"),
200         // tooltip
201         N_("The key events to toggle Hanja mode. "
202            "Click on the button on the right to edit it."),
203         // entry
204         NULL,
205         // button
206         NULL,
207         // data
208         ""
209     }
210 };
211
212 // Declaration of internal functions.
213 static void
214 on_default_editable_changed          (GtkEditable     *editable,
215                                       gpointer         user_data);
216
217 static void
218 on_default_toggle_button_toggled     (GtkToggleButton *togglebutton,
219                                       gpointer         user_data);
220
221 static void
222 on_default_key_selection_clicked     (GtkButton       *button,
223                                       gpointer         user_data);
224
225 static void
226 on_default_combo_box_changed         (GtkComboBox *combobox,
227                                       gpointer     user_data);
228
229 static GtkWidget *
230 create_options_page(GtkTooltips *tooltip);
231
232 static GtkWidget *
233 create_keyboard_page(GtkTooltips *tooltip);
234
235 // Function implementations.
236 static GtkWidget *
237 create_options_page(GtkTooltips *tooltips)
238 {
239     GtkWidget *vbox;
240     GtkWidget *button;
241
242     vbox = gtk_vbox_new (FALSE, 12);
243     gtk_container_set_border_width(GTK_CONTAINER(vbox), 12);
244
245     button = gtk_check_button_new_with_mnemonic (_("_Use ascii input mode"));
246     gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0);
247     gtk_tooltips_set_tip(tooltips, button,
248                           _("Whether to enable to change the input mode "
249                             "between hangul and ascii mode."), NULL);
250     g_signal_connect(G_OBJECT(button), "toggled",
251                      G_CALLBACK(on_default_toggle_button_toggled), NULL);
252     use_ascii_mode_button = button;
253
254     button = gtk_check_button_new_with_mnemonic (_("_Show candidate comment"));
255     gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0);
256     gtk_tooltips_set_tip(tooltips, button,
257                           _("Whether to show the comment of candidates or not."), NULL);
258     g_signal_connect(G_OBJECT(button), "toggled",
259                      G_CALLBACK(on_default_toggle_button_toggled), NULL);
260     show_candidate_comment_button = button;
261
262     button = gtk_check_button_new_with_mnemonic (_("_Commit by word"));
263     gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0);
264     gtk_tooltips_set_tip(tooltips, button,
265                           _("Whether not to commit until any non-hangul character is inputed."), NULL);
266     g_signal_connect(G_OBJECT(button), "toggled",
267                      G_CALLBACK(on_default_toggle_button_toggled), NULL);
268     commit_by_word_button = button;
269
270     return vbox;
271 }
272
273 static GtkWidget *
274 create_keyboard_page(GtkTooltips *tooltips)
275 {
276     unsigned int i;
277
278     GtkWidget *vbox1 = gtk_vbox_new(FALSE, 12);
279     gtk_container_set_border_width(GTK_CONTAINER(vbox1), 12);
280
281     GtkWidget *label = gtk_label_new("");
282     gtk_label_set_use_markup(GTK_LABEL(label), TRUE);
283     gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
284     gtk_label_set_markup(GTK_LABEL(label),
285             _("<span weight=\"bold\">Keyboard layout</span>"));
286     gtk_box_pack_start(GTK_BOX(vbox1), label, FALSE, TRUE, 0);
287
288     GtkWidget *hbox = gtk_hbox_new(FALSE, 0);
289     gtk_box_pack_start(GTK_BOX(vbox1), hbox, FALSE, TRUE, 0);
290
291     label = gtk_label_new("    ");
292     gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, TRUE, 0);
293
294     GtkWidget *vbox2 = gtk_vbox_new(FALSE, 0);
295     gtk_box_pack_start(GTK_BOX(hbox), vbox2, FALSE, TRUE, 0);
296
297     GtkWidget *combo_box = gtk_combo_box_new_text();
298     gtk_box_pack_start(GTK_BOX(vbox2), combo_box, FALSE, TRUE, 0);
299     gtk_combo_box_append_text(GTK_COMBO_BOX(combo_box), _("2bul"));
300     gtk_combo_box_append_text(GTK_COMBO_BOX(combo_box), _("3bul 2bul-shifted"));
301     gtk_combo_box_append_text(GTK_COMBO_BOX(combo_box), _("3bul Final"));
302     gtk_combo_box_append_text(GTK_COMBO_BOX(combo_box), _("3bul 390"));
303     gtk_combo_box_append_text(GTK_COMBO_BOX(combo_box), _("3bul No-Shift"));
304     gtk_combo_box_append_text(GTK_COMBO_BOX(combo_box), _("3bul Yetgeul"));
305     g_signal_connect(G_OBJECT(combo_box), "changed",
306                      G_CALLBACK (on_default_combo_box_changed), NULL);
307     keyboard_layout_combo = combo_box;
308
309
310     label = gtk_label_new("");
311     gtk_label_set_use_markup(GTK_LABEL(label), TRUE);
312     gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
313     gtk_label_set_markup(GTK_LABEL(label),
314             _("<span weight=\"bold\">Key bindings</span>"));
315     gtk_box_pack_start(GTK_BOX(vbox1), label, FALSE, TRUE, 0);
316
317     hbox = gtk_hbox_new(FALSE, 0);
318     gtk_box_pack_start(GTK_BOX(vbox1), hbox, FALSE, TRUE, 0);
319
320     label = gtk_label_new("    ");
321     gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, TRUE, 0);
322
323     vbox2 = gtk_vbox_new(FALSE, 0);
324     gtk_box_pack_start(GTK_BOX(hbox), vbox2, TRUE, TRUE, 0);
325
326     GtkWidget *table = gtk_table_new (3, G_N_ELEMENTS(key_bindings), FALSE);
327     gtk_box_pack_start(GTK_BOX(vbox2), table, FALSE, TRUE, 0);
328
329     for (i = 0; i < G_N_ELEMENTS(key_bindings); ++ i) {
330         label = gtk_label_new (NULL);
331         gtk_label_set_text_with_mnemonic (GTK_LABEL (label), _(key_bindings[i].label));
332         gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
333         gtk_misc_set_padding (GTK_MISC (label), 4, 0);
334         gtk_table_attach (GTK_TABLE (table), label, 0, 1, i, i+1,
335                           (GtkAttachOptions) (GTK_FILL),
336                           (GtkAttachOptions) (GTK_FILL), 4, 4);
337
338         key_bindings[i].entry = gtk_entry_new ();
339         gtk_table_attach (GTK_TABLE (table), key_bindings[i].entry, 1, 2, i, i+1,
340                           (GtkAttachOptions) (GTK_FILL|GTK_EXPAND),
341                           (GtkAttachOptions) (GTK_FILL), 4, 4);
342         gtk_entry_set_editable (GTK_ENTRY (key_bindings[i].entry), FALSE);
343         gtk_entry_set_text (GTK_ENTRY (key_bindings[i].entry),
344                             key_bindings[i].data.c_str());
345
346         key_bindings[i].button = gtk_button_new_with_label ("...");
347         gtk_table_attach (GTK_TABLE (table), key_bindings[i].button, 2, 3, i, i+1,
348                           (GtkAttachOptions) (GTK_FILL),
349                           (GtkAttachOptions) (GTK_FILL), 4, 4);
350         gtk_label_set_mnemonic_widget (GTK_LABEL (label), key_bindings[i].button);
351
352         g_signal_connect(G_OBJECT(key_bindings[i].button), "clicked",
353                          G_CALLBACK (on_default_key_selection_clicked),
354                          &key_bindings[i]);
355         g_signal_connect(G_OBJECT(key_bindings[i].entry), "changed",
356                          G_CALLBACK (on_default_editable_changed), NULL);
357
358         gtk_tooltips_set_tip(tooltips, key_bindings[i].entry,
359                               _(key_bindings[i].tooltip), NULL);
360     }
361
362     return vbox1;
363 }
364
365 static GtkWidget *
366 create_setup_window ()
367 {
368     GtkWidget *notebook;
369     GtkWidget *label;
370     GtkWidget *page;
371     GtkTooltips *tooltips;
372
373     tooltips = gtk_tooltips_new ();
374
375     // Create the Notebook.
376     notebook = gtk_notebook_new ();
377
378     // Create the first page.
379     page = create_keyboard_page(tooltips);
380     label = gtk_label_new (_("Keyboard"));
381     gtk_notebook_append_page (GTK_NOTEBOOK (notebook), page, label);
382
383     // Create the second page.
384     page = create_options_page(tooltips);
385     label = gtk_label_new (_("Options"));
386     gtk_notebook_append_page (GTK_NOTEBOOK (notebook), page, label);
387
388     gtk_notebook_set_current_page(GTK_NOTEBOOK (notebook), 0);
389
390     gtk_widget_show_all(notebook);
391
392     return notebook;
393 }
394
395 static void
396 load_config (const ConfigPointer &config)
397 {
398     if (config.null())
399         return;
400
401     // keyboard layout option
402     String layout = config->read(String(SCIM_CONFIG_LAYOUT), String("2"));
403     int no = -1;
404     if (layout == "2") {
405         no = 0;
406     } else if (layout == "32") {
407         no = 1;
408     } else if (layout == "3f") {
409         no = 2;
410     } else if (layout == "39") {
411         no = 3;
412     } else if (layout == "3s") {
413         no = 4;
414     } else if (layout == "3y") {
415         no = 5;
416     }
417     gtk_combo_box_set_active(GTK_COMBO_BOX(keyboard_layout_combo), no);
418
419     // key bindings
420     for (unsigned int i = 0; i < G_N_ELEMENTS(key_bindings); ++ i) {
421         String text = 
422             config->read (String (key_bindings[i].key), key_bindings[i].data);
423         gtk_entry_set_text(GTK_ENTRY(key_bindings[i].entry), text.c_str());
424     }
425
426     bool stat;
427
428     // use ascii input mode
429     stat = config->read(String(SCIM_CONFIG_USE_ASCII_MODE), false);
430     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(use_ascii_mode_button), stat);
431
432     // show candidate comment option
433     stat = config->read(String(SCIM_CONFIG_SHOW_CANDIDATE_COMMENT), true);
434     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(show_candidate_comment_button), stat);
435
436     // commit by word or not
437     stat = config->read(String(SCIM_CONFIG_COMMIT_BY_WORD), false);
438     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(commit_by_word_button), stat);
439
440     __have_changed = false;
441 }
442
443 void
444 save_config (const ConfigPointer &config)
445 {
446     if (config.null())
447         return;
448
449     int no = gtk_combo_box_get_active(GTK_COMBO_BOX(keyboard_layout_combo));
450     String layout;
451     if (no == 0) {
452         layout = "2";
453     } else if (no == 1) {
454         layout = "32";
455     } else if (no == 2) {
456         layout = "3f";
457     } else if (no == 3) {
458         layout = "39";
459     } else if (no == 4) {
460         layout = "3s";
461     } else if (no == 5) {
462         layout = "3y";
463     }
464     config->write(String(SCIM_CONFIG_LAYOUT), layout);
465
466     for (unsigned int i = 0; i < G_N_ELEMENTS(key_bindings); ++ i) {
467         String text = gtk_entry_get_text(GTK_ENTRY(key_bindings[i].entry));
468         config->write(String (key_bindings[i].key), text);
469     }
470
471     gboolean stat;
472
473     // use ascii input mode
474     stat = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(use_ascii_mode_button));
475     config->write(String(SCIM_CONFIG_USE_ASCII_MODE), (bool)stat);
476
477     // show candidate comment
478     stat = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(show_candidate_comment_button));
479     config->write(String(SCIM_CONFIG_SHOW_CANDIDATE_COMMENT), (bool)stat);
480
481     // commit by word or not
482     stat = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(commit_by_word_button));
483     config->write(String(SCIM_CONFIG_COMMIT_BY_WORD), (bool)stat);
484
485     __have_changed = false;
486 }
487
488 bool
489 query_changed ()
490 {
491     return __have_changed;
492 }
493
494 static void
495 on_default_editable_changed (GtkEditable *editable,
496                              gpointer     user_data)
497 {
498     __have_changed = true;
499 }
500
501 static void
502 on_default_toggle_button_toggled (GtkToggleButton *togglebutton,
503                                   gpointer         user_data)
504 {
505     __have_changed = true;
506 }
507
508 static void
509 on_default_combo_box_changed(GtkComboBox *combobox,
510                              gpointer     user_data)
511 {
512     __have_changed = true;
513 }
514
515 static void
516 on_default_key_selection_clicked (GtkButton *button,
517                                   gpointer   user_data)
518 {
519     KeyBindingData *data = static_cast<KeyBindingData *> (user_data);
520
521     if (data) {
522         GtkWidget *dialog = NULL;// = scim_key_selection_dialog_new (_(data->title));
523         gint result;
524 /*
525         scim_key_selection_dialog_set_keys (
526             SCIM_KEY_SELECTION_DIALOG (dialog),
527             gtk_entry_get_text (GTK_ENTRY (data->entry)));
528 */
529         result = gtk_dialog_run (GTK_DIALOG (dialog));
530
531         if (result == GTK_RESPONSE_OK) {
532             const gchar *keys = "";//scim_key_selection_dialog_get_keys (
533                             //SCIM_KEY_SELECTION_DIALOG (dialog));
534
535             if (!keys) keys = "";
536
537             if (strcmp (keys, gtk_entry_get_text (GTK_ENTRY (data->entry))) != 0)
538                 gtk_entry_set_text (GTK_ENTRY (data->entry), keys);
539         }
540
541         gtk_widget_destroy (dialog);
542     }
543 }
544
545 /*
546 vi:ts=4:nowrap:expandtab
547 */