diff options
author | choehwanjin <choe.hwanjin@gmail.com> | 2014-07-21 23:54:41 +0900 |
---|---|---|
committer | choehwanjin <choe.hwanjin@gmail.com> | 2014-07-21 23:54:41 +0900 |
commit | 11224b52477d93e773ffd302fed11996401804f7 (patch) | |
tree | 17d9d3cbf09bf5a6104450dd8af2b457783219e1 | |
parent | 2440e0c0e0abf38348611a27cf0d01684115e6ed (diff) | |
parent | b9ef6d6b57300d3a9aeb121d5bb72e5f418e249e (diff) | |
download | ibus-hangul-11224b52477d93e773ffd302fed11996401804f7.tar.gz |
Merge pull request #18 from ueno/hangul-toggle
Allow hangul mode to be toggled
-rw-r--r-- | setup/main.py | 61 | ||||
-rw-r--r-- | setup/setup.ui | 203 | ||||
-rw-r--r-- | src/engine.c | 134 |
3 files changed, 354 insertions, 44 deletions
diff --git a/setup/main.py b/setup/main.py index ce33db7..eb6525c 100644 --- a/setup/main.py +++ b/setup/main.py @@ -78,6 +78,29 @@ class Setup (): auto_reorder = self.__read("AutoReorder", default).get_boolean() self.__auto_reorder.set_active(auto_reorder) + button = self.__builder.get_object("HangulKeyListAddButton") + button.connect("clicked", self.on_hangul_key_add, None) + + button = self.__builder.get_object("HangulKeyListRemoveButton") + button.connect("clicked", self.on_hangul_key_remove, None) + + model = Gtk.ListStore(str) + + default = GLib.Variant.new_string("Hangul,Shift+space") + keylist_str = self.__read("HangulKeys", default).get_string() + self.__hangul_key_list_str = keylist_str.split(',') + for i in self.__hangul_key_list_str: + model.append([i]) + + self.__hangul_key_list = self.__builder.get_object("HangulKeyList") + self.__hangul_key_list.set_model(model) + column = Gtk.TreeViewColumn() + column.set_title("key") + renderer = Gtk.CellRendererText() + column.pack_start(renderer, True) + column.add_attribute(renderer, "text", 0) + self.__hangul_key_list.append_column(column) + # hanja tab button = self.__builder.get_object("HanjaKeyListAddButton") button.connect("clicked", self.on_hanja_key_add, None) @@ -133,6 +156,18 @@ class Setup (): auto_reorder = self.__auto_reorder.get_active() self.__write("AutoReorder", GLib.Variant.new_boolean(auto_reorder)) + model = self.__hangul_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("HangulKeys", GLib.Variant.new_string(str)) + model = self.__hanja_key_list.get_model() str = "" iter = model.get_iter_first() @@ -155,6 +190,30 @@ class Setup (): def on_ok(self): self.apply() + def on_hangul_key_add(self, widget, data = None): + dialog = KeyCaptureDialog(_("Select Hangul toggle key"), self.__window) + res = dialog.run() + if res == Gtk.ResponseType.OK: + key_str = dialog.get_key_string() + if len(key_str) > 0: + model = self.__hangul_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_hangul_key_remove(self, widget, data = None): + selection = self.__hangul_key_list.get_selection() + (model, iter) = selection.get_selected() + if model and iter: + model.remove(iter) + def on_hanja_key_add(self, widget, data = None): dialog = KeyCaptureDialog(_("Select Hanja key"), self.__window) res = dialog.run() @@ -187,6 +246,8 @@ class Setup (): if i[1] == value: self.__hangul_keyboard.set_active(i[2]) break + elif name == "HangulKeys": + self.__hangul_key_list_str = value.split(',') elif name == "HanjaKeys": self.__hanja_key_list_str = value.split(',') diff --git a/setup/setup.ui b/setup/setup.ui index 6f928b0..2fa8c49 100644 --- a/setup/setup.ui +++ b/setup/setup.ui @@ -1,16 +1,18 @@ -<?xml version="1.0"?> +<?xml version="1.0" encoding="UTF-8"?> +<!-- Generated with glade 3.18.3 --> <interface> - <!-- interface-requires gtk+ 2.12 --> - <!-- interface-naming-policy toplevel-contextual --> + <requires lib="gtk+" version="3.0"/> <object class="GtkDialog" id="SetupDialog"> + <property name="can_focus">False</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">5</property> <property name="title" translatable="yes">IBusHangul Setup</property> <property name="window_position">center-on-parent</property> <property name="type_hint">dialog</property> <child internal-child="vbox"> - <object class="GtkVBox" id="dialog-vbox1"> + <object class="GtkBox" id="dialog-vbox1"> <property name="visible">True</property> + <property name="can_focus">False</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> @@ -18,27 +20,28 @@ <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="can_focus">False</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">12</property> <child> <object class="GtkVBox" id="vbox2"> <property name="visible">True</property> + <property name="can_focus">False</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="can_focus">False</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="can_focus">False</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"><b>Keyboard Layout</b></property> <property name="use_markup">True</property> @@ -46,6 +49,7 @@ </object> <packing> <property name="expand">False</property> + <property name="fill">True</property> <property name="position">0</property> </packing> </child> @@ -55,16 +59,19 @@ </object> <packing> <property name="expand">False</property> + <property name="fill">True</property> <property name="position">0</property> </packing> </child> <child> <object class="GtkHBox" id="hbox2"> <property name="visible">True</property> + <property name="can_focus">False</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="can_focus">False</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> @@ -80,43 +87,51 @@ <child> <object class="GtkComboBox" id="HangulKeyboard"> <property name="visible">True</property> + <property name="can_focus">False</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="expand">True</property> + <property name="fill">True</property> <property name="position">1</property> </packing> </child> </object> <packing> <property name="expand">False</property> + <property name="fill">True</property> <property name="position">1</property> </packing> </child> </object> <packing> <property name="expand">False</property> + <property name="fill">True</property> <property name="position">0</property> </packing> </child> <child> <object class="GtkVBox" id="vbox5"> <property name="visible">True</property> - <property name="orientation">vertical</property> + <property name="can_focus">False</property> <child> <object class="GtkVBox" id="vbox6"> <property name="visible">True</property> - <property name="orientation">vertical</property> + <property name="can_focus">False</property> <child> <object class="GtkHBox" id="hbox5"> <property name="visible">True</property> + <property name="can_focus">False</property> <child> <object class="GtkLabel" id="label3"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="label" translatable="yes"><b>Etc</b></property> <property name="use_markup">True</property> </object> <packing> <property name="expand">False</property> + <property name="fill">True</property> <property name="position">0</property> </packing> </child> @@ -125,12 +140,15 @@ </child> </object> <packing> + <property name="expand">True</property> + <property name="fill">True</property> <property name="position">0</property> </packing> </child> <child> <object class="GtkHBox" id="hbox6"> <property name="visible">True</property> + <property name="can_focus">False</property> <child> <object class="GtkCheckButton" id="WordCommit"> <property name="label" translatable="yes">Commit in _word unit</property> @@ -138,21 +156,27 @@ <property name="can_focus">True</property> <property name="receives_default">False</property> <property name="use_underline">True</property> + <property name="xalign">0.5</property> <property name="draw_indicator">True</property> </object> <packing> + <property name="expand">True</property> + <property name="fill">True</property> <property name="padding">12</property> <property name="position">0</property> </packing> </child> </object> <packing> + <property name="expand">True</property> + <property name="fill">True</property> <property name="position">1</property> </packing> </child> <child> <object class="GtkHBox" id="hbox7"> <property name="visible">True</property> + <property name="can_focus">False</property> <child> <object class="GtkCheckButton" id="AutoReorder"> <property name="label" translatable="yes">Automatic _reordering</property> @@ -160,39 +184,165 @@ <property name="can_focus">True</property> <property name="receives_default">False</property> <property name="use_underline">True</property> + <property name="xalign">0.5</property> <property name="active">True</property> <property name="draw_indicator">True</property> </object> <packing> + <property name="expand">True</property> + <property name="fill">True</property> <property name="padding">12</property> <property name="position">0</property> </packing> </child> </object> <packing> + <property name="expand">True</property> + <property name="fill">True</property> <property name="position">2</property> </packing> </child> </object> <packing> <property name="expand">False</property> + <property name="fill">True</property> <property name="position">0</property> </packing> </child> </object> <packing> <property name="expand">False</property> + <property name="fill">True</property> <property name="position">1</property> </packing> </child> <child> - <placeholder/> + <object class="GtkBox" id="box1"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="orientation">vertical</property> + <child> + <object class="GtkLabel" id="label7"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="halign">start</property> + <property name="label" translatable="yes"><b>Hangul toggle key</b></property> + <property name="use_markup">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkHBox" id="hbox8"> + <property name="visible">True</property> + <property name="can_focus">False</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="label8"> + <property name="visible">True</property> + <property name="can_focus">False</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="scrolledwindow2"> + <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="shadow_type">in</property> + <child> + <object class="GtkTreeView" id="HangulKeyList"> + <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="show_expanders">False</property> + <child internal-child="selection"> + <object class="GtkTreeSelection" id="treeview-selection3"/> + </child> + </object> + </child> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + <child> + <object class="GtkVButtonBox" id="vbuttonbox2"> + <property name="visible">True</property> + <property name="can_focus">False</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="spacing">6</property> + <property name="layout_style">start</property> + <child> + <object class="GtkButton" id="HangulKeyListAddButton"> + <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="HangulKeyListRemoveButton"> + <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="fill">True</property> + <property name="position">2</property> + </packing> + </child> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">2</property> + </packing> </child> </object> </child> <child type="tab"> <object class="GtkLabel" id="NotebookLabel1"> <property name="visible">True</property> + <property name="can_focus">False</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> @@ -203,22 +353,24 @@ <child> <object class="GtkVBox" id="vbox3"> <property name="visible">True</property> + <property name="can_focus">False</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="can_focus">False</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="can_focus">False</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="can_focus">False</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"><b>Hanja key</b></property> <property name="use_markup">True</property> @@ -226,6 +378,7 @@ </object> <packing> <property name="expand">False</property> + <property name="fill">True</property> <property name="position">0</property> </packing> </child> @@ -235,16 +388,19 @@ </object> <packing> <property name="expand">False</property> + <property name="fill">True</property> <property name="position">0</property> </packing> </child> <child> <object class="GtkHBox" id="hbox4"> <property name="visible">True</property> + <property name="can_focus">False</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="can_focus">False</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> @@ -259,8 +415,6 @@ <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"> @@ -270,19 +424,24 @@ <property name="headers_visible">False</property> <property name="headers_clickable">False</property> <property name="show_expanders">False</property> + <child internal-child="selection"> + <object class="GtkTreeSelection" id="treeview-selection1"/> + </child> </object> </child> </object> <packing> + <property name="expand">True</property> + <property name="fill">True</property> <property name="position">1</property> </packing> </child> <child> <object class="GtkVButtonBox" id="vbuttonbox1"> <property name="visible">True</property> + <property name="can_focus">False</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> @@ -318,16 +477,21 @@ </object> <packing> <property name="expand">False</property> + <property name="fill">True</property> <property name="position">2</property> </packing> </child> </object> <packing> + <property name="expand">True</property> + <property name="fill">True</property> <property name="position">1</property> </packing> </child> </object> <packing> + <property name="expand">True</property> + <property name="fill">True</property> <property name="position">0</property> </packing> </child> @@ -339,6 +503,7 @@ <child type="tab"> <object class="GtkLabel" id="NotebookLabel2"> <property name="visible">True</property> + <property name="can_focus">False</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> @@ -350,6 +515,7 @@ <child> <object class="GtkLabel" id="label6"> <property name="visible">True</property> + <property name="can_focus">False</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"><b>Not implemented</b></property> <property name="use_markup">True</property> @@ -361,6 +527,7 @@ <child type="tab"> <object class="GtkLabel" id="NotebookLabel3"> <property name="visible">True</property> + <property name="can_focus">False</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> @@ -371,12 +538,15 @@ </child> </object> <packing> + <property name="expand">False</property> + <property name="fill">True</property> <property name="position">1</property> </packing> </child> <child internal-child="action_area"> - <object class="GtkHButtonBox" id="dialog-action_area1"> + <object class="GtkButtonBox" id="dialog-action_area1"> <property name="visible">True</property> + <property name="can_focus">False</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> @@ -428,6 +598,7 @@ </object> <packing> <property name="expand">False</property> + <property name="fill">True</property> <property name="pack_type">end</property> <property name="position">1</property> </packing> diff --git a/src/engine.c b/src/engine.c index 602f073..161f041 100644 --- a/src/engine.c +++ b/src/engine.c @@ -35,7 +35,7 @@ typedef struct _IBusHangulEngine IBusHangulEngine; typedef struct _IBusHangulEngineClass IBusHangulEngineClass; -typedef struct _HanjaKeyList HanjaKeyList; +typedef struct _HotkeyList HotkeyList; struct _IBusHangulEngine { IBusEngine parent; @@ -50,6 +50,7 @@ struct _IBusHangulEngine { IBusLookupTable *table; + IBusProperty *prop_hangul_mode; IBusProperty *prop_hanja_mode; IBusPropList *prop_list; }; @@ -63,7 +64,7 @@ struct KeyEvent { guint modifiers; }; -struct _HanjaKeyList { +struct _HotkeyList { guint all_modifiers; GArray *keys; }; @@ -159,17 +160,17 @@ static gboolean key_event_list_match (GArray *list, guint keyval, guint modifiers); -static void hanja_key_list_init (HanjaKeyList *list); -static void hanja_key_list_fini (HanjaKeyList *list); -static void hanja_key_list_set_from_string(HanjaKeyList *list, +static void hotkey_list_init (HotkeyList *list); +static void hotkey_list_fini (HotkeyList *list); +static void hotkey_list_set_from_string (HotkeyList *list, const char *str); -static void hanja_key_list_append (HanjaKeyList *list, +static void hotkey_list_append (HotkeyList *list, guint keyval, guint modifiers); -static gboolean hanja_key_list_match (HanjaKeyList *list, +static gboolean hotkey_list_match (HotkeyList *list, guint keyval, guint modifiers); -static gboolean hanja_key_list_has_modifier (HanjaKeyList *list, +static gboolean hotkey_list_has_modifier (HotkeyList *list, guint keyval); static glong ucschar_strlen (const ucschar* str); @@ -179,7 +180,8 @@ static HanjaTable *hanja_table = NULL; static HanjaTable *symbol_table = NULL; static IBusConfig *config = NULL; static GString *hangul_keyboard = NULL; -static HanjaKeyList hanja_keys; +static HotkeyList hangul_keys; +static HotkeyList hanja_keys; static int lookup_table_orientation = 0; static IBusKeymap *keymap = NULL; static gboolean word_commit = FALSE; @@ -243,17 +245,30 @@ ibus_hangul_init (IBusBus *bus) g_variant_unref(value); } - hanja_key_list_init(&hanja_keys); + hotkey_list_init(&hangul_keys); + + value = ibus_config_get_value (config, "engine/Hangul", + "HangulKeys"); + if (value != NULL) { + const gchar* str = g_variant_get_string (value, NULL); + hotkey_list_set_from_string(&hangul_keys, str); + g_variant_unref(value); + } else { + hotkey_list_append(&hangul_keys, IBUS_Hangul, 0); + hotkey_list_append(&hangul_keys, IBUS_space, IBUS_SHIFT_MASK); + } + + hotkey_list_init(&hanja_keys); value = ibus_config_get_value (config, "engine/Hangul", "HanjaKeys"); if (value != NULL) { const gchar* str = g_variant_get_string (value, NULL); - hanja_key_list_set_from_string(&hanja_keys, str); + hotkey_list_set_from_string(&hanja_keys, str); g_variant_unref(value); } else { - hanja_key_list_append(&hanja_keys, IBUS_Hangul_Hanja, 0); - hanja_key_list_append(&hanja_keys, IBUS_F9, 0); + hotkey_list_append(&hanja_keys, IBUS_Hangul_Hanja, 0); + hotkey_list_append(&hanja_keys, IBUS_F9, 0); } value = ibus_config_get_value (config, "engine/Hangul", @@ -280,7 +295,8 @@ ibus_hangul_exit (void) keymap = NULL; } - hanja_key_list_fini(&hanja_keys); + hotkey_list_fini(&hangul_keys); + hotkey_list_fini(&hanja_keys); hanja_table_delete (hanja_table); hanja_table = NULL; @@ -347,6 +363,18 @@ ibus_hangul_engine_init (IBusHangulEngine *hangul) hangul->prop_list = ibus_prop_list_new (); g_object_ref_sink (hangul->prop_list); + label = ibus_text_new_from_string (_("Hangul mode")); + tooltip = ibus_text_new_from_string (_("Enable/Disable Hangul mode")); + prop = ibus_property_new ("hangul_mode", + PROP_TYPE_TOGGLE, + label, + NULL, + tooltip, + TRUE, TRUE, PROP_STATE_UNCHECKED, NULL); + g_object_ref_sink (prop); + ibus_prop_list_append (hangul->prop_list, prop); + hangul->prop_hangul_mode = prop; + label = ibus_text_new_from_string (_("Hanja lock")); tooltip = ibus_text_new_from_string (_("Enable/Disable Hanja mode")); prop = ibus_property_new ("hanja_mode", @@ -394,6 +422,11 @@ ibus_hangul_engine_constructor (GType type, static void ibus_hangul_engine_destroy (IBusHangulEngine *hangul) { + if (hangul->prop_hangul_mode) { + g_object_unref (hangul->prop_hangul_mode); + hangul->prop_hangul_mode = NULL; + } + if (hangul->prop_hanja_mode) { g_object_unref (hangul->prop_hanja_mode); hangul->prop_hanja_mode = NULL; @@ -929,17 +962,39 @@ ibus_hangul_engine_process_key_event (IBusEngine *engine, if (keyval == IBUS_Shift_L || keyval == IBUS_Shift_R) return FALSE; - // If hanja key has any modifiers, we ignore that modifier keyval, - // or we cannot make the hanja key work. + // If a hotkey has any modifiers, we ignore that modifier + // keyval, or we cannot make the hanja key work. // Because when we get the modifier key alone, we commit the // current preedit string. So after that, even if we get the // right hanja key event, we don't have preedit string to be changed // to hanja word. // See this bug: http://code.google.com/p/ibus/issues/detail?id=1036 - if (hanja_key_list_has_modifier(&hanja_keys, keyval)) + if (hotkey_list_has_modifier(&hangul_keys, keyval)) + return FALSE; + + if (hotkey_list_match(&hangul_keys, keyval, modifiers)) { + if (hangul->hangul_mode) + ibus_hangul_engine_flush (hangul); + + hangul->hangul_mode = !hangul->hangul_mode; + if (hangul->hangul_mode) { + ibus_property_set_state (hangul->prop_hangul_mode, + PROP_STATE_CHECKED); + } else { + ibus_property_set_state (hangul->prop_hangul_mode, + PROP_STATE_UNCHECKED); + } + ibus_engine_update_property (engine, hangul->prop_hangul_mode); + return TRUE; + } + + if (!hangul->hangul_mode) + return FALSE; + + if (hotkey_list_has_modifier(&hanja_keys, keyval)) return FALSE; - if (hanja_key_list_match(&hanja_keys, keyval, modifiers)) { + if (hotkey_list_match(&hanja_keys, keyval, modifiers)) { if (hangul->hanja_list == NULL) { ibus_hangul_engine_update_lookup_table (hangul); } else { @@ -1095,6 +1150,12 @@ ibus_hangul_engine_focus_in (IBusEngine *engine) { IBusHangulEngine *hangul = (IBusHangulEngine *) engine; + if (hangul->hangul_mode) { + ibus_property_set_state (hangul->prop_hangul_mode, PROP_STATE_CHECKED); + } else { + ibus_property_set_state (hangul->prop_hangul_mode, PROP_STATE_UNCHECKED); + } + if (hangul->hanja_mode) { ibus_property_set_state (hangul->prop_hanja_mode, PROP_STATE_CHECKED); } else { @@ -1205,6 +1266,20 @@ ibus_hangul_engine_property_activate (IBusEngine *engine, argv[0] = "ibus-setup-hangul"; argv[1] = NULL; g_spawn_async (NULL, argv, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, NULL, &error); + } else if (strcmp(prop_name, "hangul_mode") == 0) { + IBusHangulEngine *hangul = (IBusHangulEngine *) engine; + + hangul->hangul_mode = !hangul->hangul_mode; + if (hangul->hangul_mode) { + ibus_property_set_state (hangul->prop_hangul_mode, + PROP_STATE_CHECKED); + } else { + ibus_property_set_state (hangul->prop_hangul_mode, + PROP_STATE_UNCHECKED); + } + + ibus_engine_update_property (engine, hangul->prop_hangul_mode); + ibus_hangul_engine_flush (hangul); } else if (strcmp(prop_name, "hanja_mode") == 0) { IBusHangulEngine *hangul = (IBusHangulEngine *) engine; @@ -1276,11 +1351,14 @@ ibus_config_value_changed (IBusConfig *config, hangul_ic_select_keyboard (hangul->context, hangul_keyboard->str); } else if (strcmp(name, "HanjaKeys") == 0) { const gchar* str = g_variant_get_string(value, NULL); - hanja_key_list_set_from_string(&hanja_keys, str); + hotkey_list_set_from_string(&hanja_keys, str); } else if (strcmp(name, "WordCommit") == 0) { word_commit = g_variant_get_boolean (value); } else if (strcmp (name, "AutoReorder") == 0) { auto_reorder = g_variant_get_boolean (value); + } else if (strcmp (name, "HangulKeys") == 0) { + const gchar* str = g_variant_get_string(value, NULL); + hotkey_list_set_from_string(&hangul_keys, str); } } else if (strcmp(section, "panel") == 0) { if (strcmp(name, "lookup_table_orientation") == 0) { @@ -1358,20 +1436,20 @@ ibus_hangul_engine_candidate_clicked (IBusEngine *engine, } static void -hanja_key_list_init(HanjaKeyList* list) +hotkey_list_init(HotkeyList* list) { list->all_modifiers = 0; list->keys = g_array_sized_new(FALSE, TRUE, sizeof(struct KeyEvent), 4); } static void -hanja_key_list_fini(HanjaKeyList* list) +hotkey_list_fini(HotkeyList* list) { g_array_free(list->keys, TRUE); } static void -hanja_key_list_append_from_string(HanjaKeyList *list, const char* str) +hotkey_list_append_from_string(HotkeyList *list, const char* str) { guint keyval = 0; guint modifiers = 0; @@ -1379,19 +1457,19 @@ hanja_key_list_append_from_string(HanjaKeyList *list, const char* str) res = ibus_key_event_from_string(str, &keyval, &modifiers); if (res) { - hanja_key_list_append(list, keyval, modifiers); + hotkey_list_append(list, keyval, modifiers); } } static void -hanja_key_list_append(HanjaKeyList *list, guint keyval, guint modifiers) +hotkey_list_append(HotkeyList *list, guint keyval, guint modifiers) { list->all_modifiers |= modifiers; key_event_list_append(list->keys, keyval, modifiers); } static void -hanja_key_list_set_from_string(HanjaKeyList *list, const char* str) +hotkey_list_set_from_string(HotkeyList *list, const char* str) { gchar** items = g_strsplit(str, ",", 0); @@ -1401,20 +1479,20 @@ hanja_key_list_set_from_string(HanjaKeyList *list, const char* str) if (items != NULL) { int i; for (i = 0; items[i] != NULL; ++i) { - hanja_key_list_append_from_string(list, items[i]); + hotkey_list_append_from_string(list, items[i]); } g_strfreev(items); } } static gboolean -hanja_key_list_match(HanjaKeyList* list, guint keyval, guint modifiers) +hotkey_list_match(HotkeyList* list, guint keyval, guint modifiers) { return key_event_list_match(list->keys, keyval, modifiers); } static gboolean -hanja_key_list_has_modifier(HanjaKeyList* list, guint keyval) +hotkey_list_has_modifier(HotkeyList* list, guint keyval) { if (list->all_modifiers & IBUS_CONTROL_MASK) { if (keyval == IBUS_Control_L || keyval == IBUS_Control_R) |