diff --git a/po/zh_TW.po b/po/zh_TW.po index 387ba23..d56e1d6 100644 --- a/po/zh_TW.po +++ b/po/zh_TW.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: ibus-array 0.2.2\n" "Report-Msgid-Bugs-To: https://github.com/lexical/ibus-array/issues\n" -"POT-Creation-Date: 2023-03-28 19:12+0800\n" +"POT-Creation-Date: 2023-03-31 10:28+0800\n" "PO-Revision-Date: 2019-12-10 22:12+0800\n" "Last-Translator: Anthony Fok \n" "Language-Team: Chinese (traditional)\n" @@ -27,15 +27,47 @@ msgstr "行列" msgid "Array 30 Input Method 行列30輸入法" msgstr "行列30輸入法 Array 30 Input Method" -#: src/engine.c:219 +#: src/engine.c:260 src/engine.c:892 +msgid "English mode" +msgstr "英文模式" + +#: src/engine.c:261 src/engine.c:893 +msgid "Chinese mode" +msgstr "中文模式" + +#: src/engine.c:263 src/engine.c:895 +msgid "Switch to Chinese mode" +msgstr "切換到中文模式" + +#: src/engine.c:264 src/engine.c:896 +msgid "Switch to English mode" +msgstr "切換到英文模式" + +#: src/engine.c:270 src/engine.c:917 +msgid "Full width mode" +msgstr "全形字元模式" + +#: src/engine.c:271 src/engine.c:918 +msgid "Half width mode" +msgstr "半形字元模式" + +#: src/engine.c:273 src/engine.c:920 +msgid "Switch to Half width mode" +msgstr "切換到半形字元模式" + +#: src/engine.c:274 src/engine.c:921 +msgid "Switch to Full width mode" +msgstr "切換到全形字元模式" + +#: src/engine.c:279 msgid "Setup" msgstr "設定" -#: src/engine.c:220 +#: src/engine.c:280 msgid "Configure Array 30 engine" msgstr "設定行列輸入法" -#: src/engine.c:504 +#: src/engine.c:566 msgid "" "1.comma 2.bracket 3.symbol 4.math 5.arrow 6.unit 7.table 8.roman 9.greek 0." "bopomo" @@ -56,3 +88,7 @@ msgstr "當有特別碼時,只能用特別碼輸入 (特別碼練習模式)" #: setup/main.py:58 msgid "Convert output to simplified Chinese" msgstr "出字時轉為簡體中文" + +#: setup/main.py:60 +msgid "Use Shift to switch English/Chinese mode" +msgstr "使用 Shift 切換中英文模式" diff --git a/setup/main.py b/setup/main.py index f099d70..b11d3d3 100644 --- a/setup/main.py +++ b/setup/main.py @@ -57,10 +57,13 @@ def __create_ui(self): self.__window.vbox.pack_start(self.__special_only_button, True, True ,10) self.__output_simplified_button = Gtk.CheckButton(label=_("Convert output to simplified Chinese")) self.__window.vbox.pack_start(self.__output_simplified_button, True, True, 10) + self.__use_shift_button = Gtk.CheckButton(label=_("Use Shift to switch English/Chinese mode")) + self.__window.vbox.pack_start(self.__use_shift_button, True, True, 10) current_special_mode = self.__read("SpecialOnly", False) current_special_notify = self.__read("SpecialNotify", False) current_output_simplified = self.__read("OutputSimplified", False) + current_use_shift = self.__read("UseShift", False) if current_special_notify: self.__special_notify_button.set_active(True) @@ -68,6 +71,8 @@ def __create_ui(self): self.__special_only_button.set_active(True) if current_output_simplified: self.__output_simplified_button.set_active(True) + if current_use_shift: + self.__use_shift_button.set_active(True) self.__window.show_all() @@ -81,6 +86,7 @@ def apply(self): select_special_notify = self.__special_notify_button.get_active() select_special_mode = self.__special_only_button.get_active() select_output_simplified = self.__output_simplified_button.get_active() + select_use_shift = self.__use_shift_button.get_active() if select_special_notify: self.__write("SpecialNotify", GLib.Variant.new_boolean(True)) @@ -97,6 +103,11 @@ def apply(self): else: self.__write("OutputSimplified", GLib.Variant.new_boolean(False)) + if select_use_shift: + self.__write("UseShift", GLib.Variant.new_boolean(True)) + else: + self.__write("UseShift", GLib.Variant.new_boolean(False)) + def on_value_changed(self, config, section, name, value, data): if section == 'engine/Array': if name == 'SpecialNotify': @@ -117,6 +128,12 @@ def on_value_changed(self, config, section, name, value, data): else: self.__output_simplified_button.set_active(False) + elif name == 'UseShift': + if value: + self.__use_shift_button.set_active(True) + else: + self.__use_shift_button.set_active(False) + def __read(self, name, v): value = self.__config.get_value("engine/Array", name) if value is None: diff --git a/src/engine.c b/src/engine.c index e8cc454..ed2dccc 100644 --- a/src/engine.c +++ b/src/engine.c @@ -105,12 +105,27 @@ static IBusConfig *config = NULL; static gboolean is_special_notify; static gboolean is_special_only; static gboolean is_output_simplified; +static gboolean is_use_shift; +static gboolean is_english_mode; +static gboolean is_fullwidth_mode; static gboolean is_aux_shown = FALSE; +static gint prev_pressed_key = IBUS_VoidSymbol; static ArrayContext *array_context = NULL; #ifdef HAVE_OPENCC static opencc_t cc_handle = NULL;; #endif +static char *sFullWidthTable[] = { + " ", "!", """, "#", "$", "%", "&", "'", "(", ")", "*", "+", + ",", "-", ".", "/", "0", "1", "2", "3", "4", "5", "6", "7", + "8", "9", ":", ";", "<", "=", ">", "?", "@", "A", "B", "C", + "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", + "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "[", + "\", "]", "^", "_", "`", "a", "b", "c", "d", "e", "f", "g", + "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", + "t", "u", "v", "w", "x", "y", "z", "{", "|", "}", "~", +}; + GType ibus_array_engine_get_type (void) { static GType type = 0; @@ -144,6 +159,9 @@ void ibus_array_init (IBusBus *bus) { is_special_notify = FALSE; is_special_only = FALSE; is_output_simplified = FALSE; + is_use_shift = FALSE; + is_english_mode = FALSE; + is_fullwidth_mode = FALSE; /* load config */ GVariant* value; @@ -160,6 +178,18 @@ void ibus_array_init (IBusBus *bus) { if (value && g_variant_classify(value) == G_VARIANT_CLASS_BOOLEAN) is_output_simplified = g_variant_get_boolean(value); + value = ibus_config_get_value (config, "engine/Array", "UseShift"); + if (value && g_variant_classify(value) == G_VARIANT_CLASS_BOOLEAN) + is_use_shift = g_variant_get_boolean(value); + + value = ibus_config_get_value (config, "engine/Array", "Mode"); + if (value && g_variant_classify(value) == G_VARIANT_CLASS_BOOLEAN) + is_english_mode = g_variant_get_boolean(value); + + value = ibus_config_get_value (config, "engine/Array", "FullWidth"); + if (value && g_variant_classify(value) == G_VARIANT_CLASS_BOOLEAN) + is_fullwidth_mode = g_variant_get_boolean(value); + /* gettext preparation */ setlocale (LC_ALL, ""); bindtextdomain (PACKAGE, LOCALEDIR); @@ -206,6 +236,14 @@ static void ibus_array_engine_class_init (IBusArrayEngineClass *klass) static void ibus_array_engine_init (IBusArrayEngine *arrayeng) { + IBusProperty *mode_prop; + IBusText *mode_label; + IBusText *mode_tooltip; + + IBusProperty *fullwidth_prop; + IBusText *fullwidth_label; + IBusText *fullwidth_tooltip; + IBusProperty *setup_prop; IBusText *setup_label; IBusText *setup_tooltip; @@ -217,6 +255,27 @@ static void ibus_array_engine_init (IBusArrayEngine *arrayeng) arrayeng->table = ibus_lookup_table_new (10, 0, FALSE, TRUE); g_object_ref_sink (arrayeng->table); + + mode_label = is_english_mode ? + ibus_text_new_from_string (_("English mode")): + ibus_text_new_from_string (_("Chinese mode")); + mode_tooltip = is_english_mode ? + ibus_text_new_from_string (_("Switch to Chinese mode")): + ibus_text_new_from_string (_("Switch to English mode")); + mode_prop = ibus_property_new("mode", PROP_TYPE_NORMAL, mode_label, + "gtk-convert", mode_tooltip, TRUE, TRUE, 0, NULL); + g_object_ref_sink (mode_prop); + + fullwidth_label = is_fullwidth_mode ? + ibus_text_new_from_string (_("Full width mode")): + ibus_text_new_from_string (_("Half width mode")); + fullwidth_tooltip = is_fullwidth_mode ? + ibus_text_new_from_string (_("Switch to Half width mode")): + ibus_text_new_from_string (_("Switch to Full width mode")); + fullwidth_prop = ibus_property_new("fullwidth", PROP_TYPE_NORMAL,fullwidth_label, + "gtk-convert", fullwidth_tooltip, TRUE, TRUE, 0, NULL); + g_object_ref_sink (fullwidth_prop); + setup_label = ibus_text_new_from_string (_("Setup")); setup_tooltip = ibus_text_new_from_string (_("Configure Array 30 engine")); setup_prop = ibus_property_new("setup", PROP_TYPE_NORMAL, setup_label, "gtk-preferences", setup_tooltip, TRUE, TRUE, 0, NULL); @@ -225,6 +284,8 @@ static void ibus_array_engine_init (IBusArrayEngine *arrayeng) arrayeng->prop_list = ibus_prop_list_new(); g_object_ref_sink (arrayeng->prop_list); + ibus_prop_list_append(arrayeng->prop_list, mode_prop); + ibus_prop_list_append(arrayeng->prop_list, fullwidth_prop); ibus_prop_list_append(arrayeng->prop_list, setup_prop); g_signal_connect (config, "value-changed", G_CALLBACK(ibus_config_value_changed_cb), NULL); @@ -511,8 +572,35 @@ static gboolean ibus_array_engine_process_key_event (IBusEngine *engine, guint is_aux_shown = FALSE; } - if (modifiers & IBUS_RELEASE_MASK) + if (modifiers & IBUS_RELEASE_MASK) { + gboolean triggered = FALSE; + + /* The keyval must be the same */ + if (prev_pressed_key == keyval) { + if (keyval == IBUS_Shift_L || keyval == IBUS_Shift_R) + triggered = TRUE; + } + + if (triggered) { + if (is_use_shift) { + ibus_array_engine_property_activate((IBusEngine *) engine, + "mode", + PROP_STATE_UNCHECKED); + return TRUE; + } + } + return FALSE; + } + + prev_pressed_key = keyval; + + if ((modifiers & IBUS_SHIFT_MASK) && keyval == IBUS_space) { + ibus_array_engine_property_activate((IBusEngine *) engine, + "fullwidth", + PROP_STATE_UNCHECKED); + return TRUE; + } if (keyval == IBUS_Shift_L || keyval == IBUS_Shift_R) return FALSE; @@ -520,6 +608,17 @@ static gboolean ibus_array_engine_process_key_event (IBusEngine *engine, guint if (modifiers & (IBUS_CONTROL_MASK | IBUS_MOD1_MASK)) return FALSE; + if (is_english_mode) { + if (is_fullwidth_mode) { + if (keyval >= 32 && keyval - 32 < sizeof(sFullWidthTable)) { + IBusText* newtext = ibus_text_new_from_string(sFullWidthTable[keyval - 32]); + ibus_engine_commit_text((IBusEngine*)arrayeng, newtext); + return TRUE; + } + } + + return FALSE; + } switch (keyval) { case IBUS_space: @@ -619,7 +718,7 @@ static gboolean ibus_array_engine_process_key_event (IBusEngine *engine, guint if (arrayeng->preedit->len >= 5) return TRUE; - if (is_wildcard (keyval)) + if (is_wildcard (keyval)) arrayeng->wildcard_char_count ++; g_string_insert_c (arrayeng->preedit, arrayeng->cursor_pos, keyval); @@ -630,6 +729,14 @@ static gboolean ibus_array_engine_process_key_event (IBusEngine *engine, guint return TRUE; } + if (is_fullwidth_mode) { + if (keyval >= 32 && keyval - 32 < sizeof(sFullWidthTable)) { + IBusText* newtext = ibus_text_new_from_string(sFullWidthTable[keyval - 32]); + ibus_engine_commit_text((IBusEngine*)arrayeng, newtext); + return TRUE; + } + } + return FALSE; } @@ -756,6 +863,8 @@ static void ibus_array_engine_show_special_code_for_char (IBusArrayEngine *array } static void ibus_array_engine_property_activate (IBusEngine *engine, const gchar *prop_name, guint prop_state) { + IBusArrayEngine *arrayeng = (IBusArrayEngine*)engine; + if (g_strcmp0(prop_name, "setup") == 0) { GError *error = NULL; gchar *argv[2] = { NULL, }; @@ -772,6 +881,56 @@ static void ibus_array_engine_property_activate (IBusEngine *engine, const gchar g_spawn_async (NULL, argv, NULL, 0, NULL, NULL, NULL, &error); g_free(path); + } else if (g_strcmp0(prop_name, "mode") == 0) { + int i = 0; + IBusProperty *prop; + while ((prop = ibus_prop_list_get (arrayeng->prop_list, i)) != NULL) { + if(g_strcmp0(ibus_property_get_key(prop), prop_name) == 0) { + is_english_mode = !is_english_mode; + + ibus_property_set_label (prop, is_english_mode? + ibus_text_new_from_string (_("English mode")): + ibus_text_new_from_string (_("Chinese mode"))); + ibus_property_set_tooltip (prop, is_english_mode? + ibus_text_new_from_string (_("Switch to Chinese mode")): + ibus_text_new_from_string (_("Switch to English mode"))); + + ibus_engine_update_property(engine, prop); + + ibus_config_set_value (config, "engine/Array", "Mode", + g_variant_new_boolean(is_english_mode)); + + ibus_array_engine_reset((IBusEngine*)arrayeng); + break; + } + + i++; + } + } else if (g_strcmp0(prop_name, "fullwidth") == 0) { + int i = 0; + IBusProperty *prop; + while ((prop = ibus_prop_list_get (arrayeng->prop_list, i)) != NULL) { + if(g_strcmp0(ibus_property_get_key(prop), prop_name) == 0) { + is_fullwidth_mode = !is_fullwidth_mode; + + ibus_property_set_label (prop, is_fullwidth_mode? + ibus_text_new_from_string (_("Full width mode")): + ibus_text_new_from_string (_("Half width mode"))); + ibus_property_set_tooltip (prop, is_fullwidth_mode? + ibus_text_new_from_string (_("Switch to Half width mode")): + ibus_text_new_from_string (_("Switch to Full width mode"))); + + ibus_engine_update_property(engine, prop); + + ibus_config_set_value (config, "engine/Array", "FullWidth", + g_variant_new_boolean(is_fullwidth_mode)); + + ibus_array_engine_reset((IBusEngine*)arrayeng); + break; + } + + i++; + } } } @@ -783,5 +942,7 @@ static void ibus_config_value_changed_cb (IBusConfig *config, const gchar *secti is_special_only = g_variant_get_boolean (value); else if (g_strcmp0(name, "outputsimplified") == 0) is_output_simplified = g_variant_get_boolean (value); + else if (g_strcmp0(name, "useshift") == 0) + is_use_shift = g_variant_get_boolean (value); }