Update Setup dialog
authorChoe Hwanjin <choe.hwanjin@gmail.com>
Sun, 13 Dec 2009 14:36:15 +0000 (23:36 +0900)
committerChoe Hwanjin <choe.hwanjin@gmail.com>
Sun, 13 Dec 2009 14:36:15 +0000 (23:36 +0900)
 * Add hanja key configuration ui
 * Migrate to GtkBuilder: use intltool, change ui filename
 * Update po files
 * Issue #689
   http://code.google.com/p/ibus/issues/detail?id=689
   https://bugzilla.redhat.com/show_bug.cgi?id=493509

autogen.sh
configure.ac
po/POTFILES.in
po/ko.po
po/zh_CN.po
setup/Makefile.am
setup/keycapturedialog.py [new file with mode: 0644]
setup/main.py
setup/setup.ui [new file with mode: 0644]

index 704a524..d9c98bc 100755 (executable)
@@ -5,6 +5,7 @@ set -x
 touch ChangeLog
 autopoint
 libtoolize --automake --copy
+intltoolize --copy --force
 aclocal -I m4
 autoheader
 automake --add-missing --copy
index 4550ca0..91a1480 100644 (file)
@@ -48,6 +48,7 @@ AC_PROG_CXX
 AC_ISC_POSIX
 AC_HEADER_STDC
 AM_PROG_LIBTOOL
+IT_PROG_INTLTOOL([0.35.0])
 
 # check ibus
 PKG_CHECK_MODULES(IBUS, [
@@ -72,7 +73,7 @@ AC_SUBST(GETTEXT_PACKAGE)
 AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE,"$GETTEXT_PACKAGE", [Define to the read-only architecture-independent data directory.])
 
 AM_GNU_GETTEXT([external])
-AM_GNU_GETTEXT_VERSION(0.16.1)
+AM_GNU_GETTEXT_VERSION([0.17])
 
 
 # OUTPUT files
index 2c97c14..1d9b7d9 100644 (file)
@@ -1,4 +1,5 @@
+setup/keycapturedialog.py
 setup/main.py
-setup/setup.glade
+[type: gettext/glade]setup/setup.ui
 src/engine.c
 src/main.c
index f28865e..a8d265b 100644 (file)
--- a/po/ko.po
+++ b/po/ko.po
@@ -6,8 +6,8 @@
 msgid ""
 msgstr ""
 "Project-Id-Version: ibus-hangul\n"
-"Report-Msgid-Bugs-To: http://code.google.com/p/ibus/issues/entry\n"
-"POT-Creation-Date: 2009-10-31 16:11+0900\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2009-12-13 20:54+0900\n"
 "PO-Revision-Date: 2009-02-18 23:32+0900\n"
 "Last-Translator: Choe Hwanjin <choe.hwanjin@gmail.com>\n"
 "Language-Team: korean <ko@li.org>\n"
@@ -15,62 +15,93 @@ msgstr ""
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 
-#: setup/main.py:44
+#: ../setup/main.py:46 ../setup/setup.ui.h:4
+msgid "Hangul"
+msgstr "한글"
+
+#: ../setup/main.py:51
 msgid "Dubeolsik"
 msgstr "두벌식"
 
-#: setup/main.py:45
+#: ../setup/main.py:52
 msgid "Sebeolsik Final"
 msgstr "세벌식 최종"
 
-#: setup/main.py:46
+#: ../setup/main.py:53
 msgid "Sebeolsik 390"
 msgstr "세벌식 390"
 
-#: setup/main.py:47
+#: ../setup/main.py:54
 msgid "Sebeolsik No-shift"
 msgstr "세벌식 순아래"
 
-#: setup/main.py:48
+#: ../setup/main.py:55
 msgid "Sebeolsik 2 set"
 msgstr "세벌식 두벌배열"
 
-#: setup/main.py:49
+#: ../setup/main.py:56
 msgid "Romaja"
 msgstr "로마자"
 
-#: setup/setup.glade:8
-msgid "IBusHangul Setup"
-msgstr "IBus 한글 설정"
+#: ../setup/main.py:142
+msgid "Select Hanja key"
+msgstr "한자키를 선택하시오"
+
+#: ../setup/keycapturedialog.py:15
+msgid ""
+"Press any key which you want to use as hanja key. The key you pressed is "
+"displayed below.\n"
+"If you want to use it, click \"Ok\" or click \"Cancel\""
+msgstr ""
+"한자키로 사용하고자 하는 키를 입력하십시오. 그러면 그 키가 아래에 표시될 것입"
+"니다.\n"
+"그 키를 사용하시려면 \"확인\"을 누르시고, 사용하지 않으시려면 \"취소\"를누르"
+"십시오."
 
-#: setup/setup.glade:34
+#: ../setup/setup.ui.h:1
+msgid "<b>Hanja key</b>"
+msgstr "<b>한자키</b>"
+
+#: ../setup/setup.ui.h:2
 msgid "<b>Keyboard Layout</b>"
 msgstr "<b>자판 설정</b>"
 
-#: setup/setup.glade:58
+#: ../setup/setup.ui.h:3
+msgid "Advanced"
+msgstr "고급"
+
+#: ../setup/setup.ui.h:5
+msgid "Hanja"
+msgstr "한자"
+
+#: ../setup/setup.ui.h:6
+msgid "IBusHangul Setup"
+msgstr "IBus 한글 설정"
+
+#: ../setup/setup.ui.h:7
 msgid "_Hangul keyboard:"
 msgstr "한글 자판(_H)"
 
-#: src/engine.c:216
+#: ../src/engine.c:248
 msgid "Hanja lock"
 msgstr "한자 전용"
 
-#: src/engine.c:217
+#: ../src/engine.c:249
 msgid "Enable/Disable Hanja mode"
 msgstr "한자 전용 모드 선택합니다"
 
-#: src/engine.c:229
+#: ../src/engine.c:261
 msgid "Setup"
 msgstr "설정"
 
-#: src/engine.c:230
+#: ../src/engine.c:262
 msgid "Configure hangul engine"
 msgstr "한글 입력기를 설정합니다"
 
-#: src/main.c:52
+#: ../src/main.c:52
 msgid "Hangul input method"
 msgstr "한글 입력기"
 
-#: src/main.c:61 src/main.c:62
+#: ../src/main.c:61 ../src/main.c:62
 msgid "Hangul Input Method"
 msgstr "한글 입력기"
index 18baeeb..bcf176c 100644 (file)
@@ -7,8 +7,8 @@
 msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
-"Report-Msgid-Bugs-To: http://code.google.com/p/ibus/issues/entry\n"
-"POT-Creation-Date: 2009-10-31 16:11+0900\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2009-12-13 20:54+0900\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -16,62 +16,89 @@ msgstr ""
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 
-#: setup/main.py:44
+#: ../setup/main.py:46 ../setup/setup.ui.h:4
+msgid "Hangul"
+msgstr ""
+
+#: ../setup/main.py:51
 msgid "Dubeolsik"
 msgstr ""
 
-#: setup/main.py:45
+#: ../setup/main.py:52
 msgid "Sebeolsik Final"
 msgstr ""
 
-#: setup/main.py:46
+#: ../setup/main.py:53
 msgid "Sebeolsik 390"
 msgstr ""
 
-#: setup/main.py:47
+#: ../setup/main.py:54
 msgid "Sebeolsik No-shift"
 msgstr ""
 
-#: setup/main.py:48
+#: ../setup/main.py:55
 msgid "Sebeolsik 2 set"
 msgstr ""
 
-#: setup/main.py:49
+#: ../setup/main.py:56
 msgid "Romaja"
 msgstr ""
 
-#: setup/setup.glade:8
-msgid "IBusHangul Setup"
+#: ../setup/main.py:142
+msgid "Select Hanja key"
+msgstr ""
+
+#: ../setup/keycapturedialog.py:15
+msgid ""
+"Press any key which you want to use as hanja key. The key you pressed is "
+"displayed below.\n"
+"If you want to use it, click \"Ok\" or click \"Cancel\""
+msgstr ""
+
+#: ../setup/setup.ui.h:1
+msgid "<b>Hanja key</b>"
 msgstr ""
 
-#: setup/setup.glade:34
+#: ../setup/setup.ui.h:2
 msgid "<b>Keyboard Layout</b>"
 msgstr ""
 
-#: setup/setup.glade:58
+#: ../setup/setup.ui.h:3
+msgid "Advanced"
+msgstr ""
+
+#: ../setup/setup.ui.h:5
+msgid "Hanja"
+msgstr ""
+
+#: ../setup/setup.ui.h:6
+msgid "IBusHangul Setup"
+msgstr ""
+
+#: ../setup/setup.ui.h:7
 msgid "_Hangul keyboard:"
 msgstr ""
 
-#: src/engine.c:216
+#: ../src/engine.c:248
 msgid "Hanja lock"
 msgstr ""
 
-#: src/engine.c:217
+#: ../src/engine.c:249
 msgid "Enable/Disable Hanja mode"
 msgstr ""
 
-#: src/engine.c:229
+#: ../src/engine.c:261
 msgid "Setup"
 msgstr ""
 
-#: src/engine.c:230
+#: ../src/engine.c:262
 msgid "Configure hangul engine"
 msgstr ""
 
-#: src/main.c:52
+#: ../src/main.c:52
 msgid "Hangul input method"
 msgstr ""
 
-#: src/main.c:61 src/main.c:62
+#: ../src/main.c:61 ../src/main.c:62
 msgid "Hangul Input Method"
 msgstr ""
index 37edd3d..02111ec 100644 (file)
@@ -20,7 +20,7 @@
 
 setup_hangul_PYTHON = \
        main.py \
-       setup.glade \
+       setup.ui \
        $(NULL)
 
 nodist_setup_hangul_PYTHON = config.py
@@ -39,7 +39,6 @@ EXTRA_DIST = \
 
 test:
        $(ENV) DBUS_DEBUG=true \
-                  LANG=en_US \
-                  PYTHONPATH=$(abs_top_srcdir):$(pyexecdir) \
-                  $(PYTHON) $(srcdir)/main.py
+              PYTHONPATH=$(abs_top_srcdir):$(pyexecdir) \
+              $(PYTHON) $(srcdir)/main.py
 
diff --git a/setup/keycapturedialog.py b/setup/keycapturedialog.py
new file mode 100644 (file)
index 0000000..a6c9cff
--- /dev/null
@@ -0,0 +1,42 @@
+import gtk
+import gtk.gdk as gdk
+import gettext
+
+_ = lambda a : gettext.dgettext("ibus-hangul", a)
+
+class KeyCaptureDialog ():
+    def __init__ (self, title, parent):
+       self.__key_str = ''
+       self.__dialog = gtk.MessageDialog(parent,
+                       gtk.DIALOG_MODAL,
+                       gtk.MESSAGE_INFO,
+                       gtk.BUTTONS_OK_CANCEL,
+                       "")
+       self.__dialog.set_markup(_("Press any key which you want to use as hanja key. "
+                "The key you pressed is displayed below.\n"
+                "If you want to use it, click \"Ok\" or click \"Cancel\""))
+
+       self.__dialog.format_secondary_markup(" ")
+       self.__dialog.connect("key-press-event", self.on_keypress, None)
+
+    def destroy(self):
+       self.__dialog.destroy()
+
+    def run(self):
+       return self.__dialog.run()
+
+    def get_key_string(self):
+       return self.__key_str
+
+    def on_keypress(self, widget, event, data = None):
+       self.__key_str = ""
+       if event.state & gdk.CONTROL_MASK :
+           self.__key_str += "Control+"
+       if event.state & gdk.MOD1_MASK :
+           self.__key_str += "Alt+"
+       if event.state & gdk.SHIFT_MASK :
+           self.__key_str += "Shift+"
+
+       self.__key_str += gdk.keyval_name(event.keyval)
+           
+       self.__dialog.format_secondary_markup('<span size="large" weight="bold">%s</span>' % self.__key_str)
index 574ef82..62284eb 100644 (file)
@@ -22,24 +22,30 @@ import sys
 import os
 import gobject
 import gtk
-import gtk.glade as glade
 import ibus
+import locale
 import gettext
 import config
+from keycapturedialog import KeyCaptureDialog
 
 _ = lambda a : gettext.dgettext("ibus-hangul", a)
 
 class Setup ():
     def __init__ (self):
+       locale.bindtextdomain("ibus-hangul", config.localedir)
+       locale.bind_textdomain_codeset("ibus-hangul", "UTF-8")
+
         self.__bus = ibus.Bus()
         self.__config = self.__bus.get_config()
        self.__config.connect("value-changed", self.on_value_changed, None)
 
-       glade.bindtextdomain("ibus-hangul", config.localedir)
-       glade_file = os.path.join(os.path.dirname(__file__), "setup.glade")
-       self.__xml = glade.XML(glade_file, domain="ibus-hangul")
+       ui_file = os.path.join(os.path.dirname(__file__), "setup.ui")
+       self.__builder = gtk.Builder()
+       self.__builder.set_translation_domain("ibus-hangul")
+       self.__builder.add_from_file(ui_file)
 
-       self.__hangul_keyboard = self.__xml.get_widget("HangulKeyboard")
+       # Hangul tab
+       self.__hangul_keyboard = self.__builder.get_object("HangulKeyboard")
        model = gtk.ListStore(str, str, int)
        model.append([_("Dubeolsik"), "2", 0])
        model.append([_("Sebeolsik Final"), "3f", 1])
@@ -47,7 +53,11 @@ class Setup ():
        model.append([_("Sebeolsik No-shift"), "3s", 3])
        model.append([_("Sebeolsik 2 set"), "32", 4])
        model.append([_("Romaja"), "ro", 5])
+
        self.__hangul_keyboard.set_model(model)
+       renderer = gtk.CellRendererText()
+       self.__hangul_keyboard.pack_start(renderer)
+       self.__hangul_keyboard.add_attribute(renderer, "text", 0)
 
        current = self.__read("HangulKeyboard", "2")
        for i in model:
@@ -55,13 +65,43 @@ class Setup ():
                self.__hangul_keyboard.set_active(i[2])
                break
 
-       self.__window = self.__xml.get_widget("dialog")
+
+       # hanja tab
+       button = self.__builder.get_object("HanjaKeyListAddButton")
+       button.connect("clicked", self.on_hanja_key_add, None)
+
+       button = self.__builder.get_object("HanjaKeyListRemoveButton")
+       button.connect("clicked", self.on_hanja_key_remove, None)
+
+       model = gtk.ListStore(str)
+
+       keylist_str = self.__read("HanjaKeys", "Hangul_Hanja,F9")
+       self.__hanja_key_list_str = keylist_str.split(',')
+       for i in self.__hanja_key_list_str:
+           model.append([i])
+
+       self.__hanja_key_list = self.__builder.get_object("HanjaKeyList")
+       self.__hanja_key_list.set_model(model)
+       column = gtk.TreeViewColumn()
+       column.set_title("key")
+       renderer = gtk.CellRendererText()
+       column.pack_start(renderer)
+       column.add_attribute(renderer, "text", 0)
+       self.__hanja_key_list.append_column(column)
+
+
+       # advanced tab
+       notebook = self.__builder.get_object("SetupNotebook")
+       notebook.remove_page(2)
+
+       # setup dialog
+       self.__window = self.__builder.get_object("SetupDialog")
        icon_file = os.path.join(config.datadir, "ibus-hangul", "icons", "ibus-hangul.svg")
        self.__window.set_icon_from_file(icon_file)
        self.__window.connect("response", self.on_response, None)
        self.__window.show()
 
-       ok_button = self.__xml.get_widget("button_ok")
+       ok_button = self.__builder.get_object("button_cancel")
        ok_button.grab_focus()
 
     def run(self):
@@ -75,14 +115,52 @@ class Setup ():
        i = self.__hangul_keyboard.get_active()
        self.__write("HangulKeyboard", model[i][1])
 
+       model = self.__hanja_key_list.get_model()
+       str = ""
+       iter = model.get_iter_first()
+       while iter:
+           if len(str) > 0:
+               str += ","
+               str += model.get_value(iter, 0)
+           else:
+               str += model.get_value(iter, 0)
+           iter = model.iter_next(iter)
+       self.__write("HanjaKeys", str)
+
     def on_response(self, widget, id, data = None):
-       if (id == gtk.RESPONSE_APPLY):
+       if id == gtk.RESPONSE_APPLY:
            self.apply()
            widget.emit_stop_by_name("response")
+       if id == gtk.RESPONSE_NONE:
+           widget.emit_stop_by_name("response")
 
     def on_ok(self):
        self.apply()
 
+    def on_hanja_key_add(self, widget, data = None):
+       dialog = KeyCaptureDialog(_("Select Hanja key"), self.__window)
+       res = dialog.run()
+       if res == gtk.RESPONSE_OK:
+           key_str = dialog.get_key_string()
+           if len(key_str) > 0:
+               model = self.__hanja_key_list.get_model()
+               iter = model.get_iter_first()
+               while iter:
+                   str = model.get_value(iter, 0)
+                   if str == key_str:
+                       model.remove(iter)
+                       break
+                   iter = model.iter_next(iter)
+
+               model.append([key_str])
+       dialog.destroy()
+
+    def on_hanja_key_remove(self, widget, data = None):
+       selection = self.__hanja_key_list.get_selection()
+       (model, iter) = selection.get_selected()
+       if model and iter:
+           model.remove(iter)
+
     def on_value_changed(self, config, section, name, value, data):
        if section == "engine/Hangul":
            if name == "HangulKeyboard":
@@ -91,6 +169,8 @@ class Setup ():
                    if i[1] == value:
                        self.__hangul_keyboard.set_active(i[2])
                        break
+           elif name == "HanjaKeys":
+               self.__hanja_key_list_str = value.split(',')
 
     def __read(self, name, v):
         return self.__config.get_value("engine/Hangul", name, v)
diff --git a/setup/setup.ui b/setup/setup.ui
new file mode 100644 (file)
index 0000000..f36acf1
--- /dev/null
@@ -0,0 +1,356 @@
+<?xml version="1.0"?>
+<interface>
+  <!-- interface-requires gtk+ 2.12 -->
+  <!-- interface-naming-policy toplevel-contextual -->
+  <object class="GtkDialog" id="SetupDialog">
+    <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+    <property name="border_width">5</property>
+    <property name="title" translatable="yes">IBusHangul Setup</property>
+    <property name="window_position">center-on-parent</property>
+    <property name="type_hint">dialog</property>
+    <property name="has_separator">False</property>
+    <child internal-child="vbox">
+      <object class="GtkVBox" id="dialog-vbox1">
+        <property name="visible">True</property>
+        <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+        <property name="orientation">vertical</property>
+        <child>
+          <object class="GtkNotebook" id="SetupNotebook">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+            <property name="tab_hborder">4</property>
+            <child>
+              <object class="GtkVBox" id="vbox1">
+                <property name="visible">True</property>
+                <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                <property name="border_width">6</property>
+                <property name="orientation">vertical</property>
+                <child>
+                  <object class="GtkVBox" id="vbox2">
+                    <property name="visible">True</property>
+                    <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                    <property name="orientation">vertical</property>
+                    <child>
+                      <object class="GtkHBox" id="hbox1">
+                        <property name="visible">True</property>
+                        <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                        <property name="spacing">6</property>
+                        <child>
+                          <object class="GtkLabel" id="label1">
+                            <property name="visible">True</property>
+                            <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                            <property name="label" translatable="yes">&lt;b&gt;Keyboard Layout&lt;/b&gt;</property>
+                            <property name="use_markup">True</property>
+                            <property name="width_chars">0</property>
+                          </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="position">0</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <placeholder/>
+                        </child>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkHBox" id="hbox2">
+                        <property name="visible">True</property>
+                        <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                        <child>
+                          <object class="GtkLabel" id="label2">
+                            <property name="visible">True</property>
+                            <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                            <property name="label" translatable="yes">_Hangul keyboard:</property>
+                            <property name="use_underline">True</property>
+                            <property name="mnemonic_widget">HangulKeyboard</property>
+                          </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">False</property>
+                            <property name="padding">12</property>
+                            <property name="position">0</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkComboBox" id="HangulKeyboard">
+                            <property name="visible">True</property>
+                            <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                          </object>
+                          <packing>
+                            <property name="position">1</property>
+                          </packing>
+                        </child>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="position">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <placeholder/>
+                </child>
+              </object>
+            </child>
+            <child type="tab">
+              <object class="GtkLabel" id="NotebookLabel1">
+                <property name="visible">True</property>
+                <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                <property name="label" translatable="yes">Hangul</property>
+              </object>
+              <packing>
+                <property name="tab_fill">False</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkVBox" id="vbox3">
+                <property name="visible">True</property>
+                <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                <property name="border_width">6</property>
+                <property name="orientation">vertical</property>
+                <child>
+                  <object class="GtkVBox" id="vbox4">
+                    <property name="visible">True</property>
+                    <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                    <property name="orientation">vertical</property>
+                    <child>
+                      <object class="GtkHBox" id="hbox3">
+                        <property name="visible">True</property>
+                        <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                        <property name="spacing">6</property>
+                        <child>
+                          <object class="GtkLabel" id="label4">
+                            <property name="visible">True</property>
+                            <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                            <property name="label" translatable="yes">&lt;b&gt;Hanja key&lt;/b&gt;</property>
+                            <property name="use_markup">True</property>
+                            <property name="wrap_mode">word-char</property>
+                          </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="position">0</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <placeholder/>
+                        </child>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkHBox" id="hbox4">
+                        <property name="visible">True</property>
+                        <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                        <child>
+                          <object class="GtkLabel" id="label5">
+                            <property name="visible">True</property>
+                            <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                            <property name="label">    </property>
+                          </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">False</property>
+                            <property name="position">0</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkScrolledWindow" id="scrolledwindow1">
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                            <property name="hscrollbar_policy">automatic</property>
+                            <property name="vscrollbar_policy">automatic</property>
+                            <property name="shadow_type">in</property>
+                            <child>
+                              <object class="GtkTreeView" id="HanjaKeyList">
+                                <property name="visible">True</property>
+                                <property name="can_focus">True</property>
+                                <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                                <property name="headers_visible">False</property>
+                                <property name="headers_clickable">False</property>
+                                <property name="show_expanders">False</property>
+                              </object>
+                            </child>
+                          </object>
+                          <packing>
+                            <property name="position">1</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkVButtonBox" id="vbuttonbox1">
+                            <property name="visible">True</property>
+                            <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                            <property name="border_width">6</property>
+                            <property name="orientation">vertical</property>
+                            <property name="spacing">6</property>
+                            <property name="layout_style">start</property>
+                            <child>
+                              <object class="GtkButton" id="HanjaKeyListAddButton">
+                                <property name="label">gtk-add</property>
+                                <property name="visible">True</property>
+                                <property name="can_focus">True</property>
+                                <property name="receives_default">True</property>
+                                <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                                <property name="use_stock">True</property>
+                              </object>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="fill">False</property>
+                                <property name="position">0</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkButton" id="HanjaKeyListRemoveButton">
+                                <property name="label">gtk-remove</property>
+                                <property name="visible">True</property>
+                                <property name="can_focus">True</property>
+                                <property name="receives_default">True</property>
+                                <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                                <property name="use_stock">True</property>
+                              </object>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="fill">False</property>
+                                <property name="position">1</property>
+                              </packing>
+                            </child>
+                          </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="position">2</property>
+                          </packing>
+                        </child>
+                      </object>
+                      <packing>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="position">0</property>
+                  </packing>
+                </child>
+              </object>
+              <packing>
+                <property name="position">1</property>
+              </packing>
+            </child>
+            <child type="tab">
+              <object class="GtkLabel" id="NotebookLabel2">
+                <property name="visible">True</property>
+                <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                <property name="label" translatable="yes">Hanja</property>
+              </object>
+              <packing>
+                <property name="position">1</property>
+                <property name="tab_fill">False</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkLabel" id="label6">
+                <property name="visible">True</property>
+                <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                <property name="label">&lt;b&gt;Not implemented&lt;/b&gt;</property>
+                <property name="use_markup">True</property>
+              </object>
+              <packing>
+                <property name="position">2</property>
+              </packing>
+            </child>
+            <child type="tab">
+              <object class="GtkLabel" id="NotebookLabel3">
+                <property name="visible">True</property>
+                <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                <property name="label" translatable="yes">Advanced</property>
+              </object>
+              <packing>
+                <property name="position">2</property>
+                <property name="tab_fill">False</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="position">1</property>
+          </packing>
+        </child>
+        <child internal-child="action_area">
+          <object class="GtkHButtonBox" id="dialog-action_area1">
+            <property name="visible">True</property>
+            <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+            <property name="homogeneous">True</property>
+            <property name="layout_style">end</property>
+            <child>
+              <object class="GtkButton" id="button_apply">
+                <property name="label">gtk-apply</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                <property name="use_stock">True</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton" id="button_cancel">
+                <property name="label">gtk-cancel</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                <property name="use_stock">True</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton" id="button_ok">
+                <property name="label">gtk-ok</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                <property name="use_stock">True</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">2</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="pack_type">end</property>
+            <property name="position">1</property>
+          </packing>
+        </child>
+      </object>
+    </child>
+    <action-widgets>
+      <action-widget response="-10">button_apply</action-widget>
+      <action-widget response="-6">button_cancel</action-widget>
+      <action-widget response="-5">button_ok</action-widget>
+    </action-widgets>
+  </object>
+</interface>