diff options
author | Peng Wu <alexepico@gmail.com> | 2014-11-26 16:59:03 +0800 |
---|---|---|
committer | Peng Wu <alexepico@gmail.com> | 2014-11-26 16:59:03 +0800 |
commit | 028425606c60348f25a4d9c9efca5ade89869b27 (patch) | |
tree | 6b95795ca2c0113e48a0a112fba0df9f46a7d8f1 | |
parent | 82b89ae4b01f353664a44e833829f1633ffdfdd2 (diff) | |
download | ibus-libpinyin-028425606c60348f25a4d9c9efca5ade89869b27.tar.gz ibus-libpinyin-028425606c60348f25a4d9c9efca5ade89869b27.tar.xz ibus-libpinyin-028425606c60348f25a4d9c9efca5ade89869b27.zip |
import keyboardshortcut.py
-rw-r--r-- | setup/keyboardshortcut.py | 246 |
1 files changed, 246 insertions, 0 deletions
diff --git a/setup/keyboardshortcut.py b/setup/keyboardshortcut.py new file mode 100644 index 0000000..32b7dc3 --- /dev/null +++ b/setup/keyboardshortcut.py @@ -0,0 +1,246 @@ +# vim:set et sts=4 sw=4: +# +# ibus-libpinyin - Intelligent Pinyin engine based on libpinyin for IBus +# +# Copyright (c) 2007-2014 Peng Huang <shawn.p.huang@gmail.com> +# Copyright (c) 2007-2014 Red Hat, Inc. +# Copyright (c) 2014 Peng Wu <alexepico@gmail.com> +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 +# USA + +__all__ = ( + "KeyboardShortcutSelection", + "KeyboardShortcutSelectionDialog", +); + +import gettext +import locale +import os + +from gi.repository import Gdk +from gi.repository import GObject +from gi.repository import Gtk +from gi.repository import IBus +from gi.repository import Pango + +locale.setlocale(locale.LC_ALL, "") +localedir = os.getenv("IBUS_LOCALEDIR") +pkgdatadir = os.getenv("IBUS_PKGDATADIR") or "." +gettext.install('ibus-libpinyin', localedir) + +class KeyboardShortcutSelection(Gtk.Box): + def __init__(self, shortcut = None): + super(KeyboardShortcutSelection, self).__init__( + orientation=Gtk.Orientation.VERTICAL) + self.__init_ui() + self.set_shortcut(shortcut) + + def __init_ui(self): + # shortcut label + hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL) + label = Gtk.Label(_("Shortcut:")) + label.set_justify(Gtk.Justification.LEFT) + label.set_alignment(0.0, 0.5) + hbox.pack_start(label, False, False, 4) + + self.__accel_label = Gtk.Label("") + self.__accel_label.set_justify(Gtk.Justification.RIGHT) + self.__accel_label.set_alignment(0.0, 0.5) + hbox.pack_start(self.__accel_label, False, False, 4) + self.pack_start(hbox, False, True, 4) + + # key code + hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL) + label = Gtk.Label(label = _("Key code:")) + label.set_justify(Gtk.Justification.LEFT) + label.set_alignment(0.0, 0.5) + hbox.pack_start(label, False, True, 4) + + self.__keycode_entry = Gtk.Entry() + self.__keycode_entry.connect("notify::text", self.__keycode_entry_notify_cb) + hbox.pack_start(self.__keycode_entry, True, True, 4) + self.__keycode_button = Gtk.Button(label = "...") + self.__keycode_button.connect("clicked", self.__keycode_button_clicked_cb) + hbox.pack_start(self.__keycode_button, False, True, 4) + self.pack_start(hbox, False, True, 4) + + # modifiers + hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL) + label = Gtk.Label(label = _("Modifiers:")) + label.set_justify(Gtk.Justification.LEFT) + label.set_alignment(0.0, 0.5) + hbox.pack_start(label, False, True, 4) + + table = Gtk.Table(n_rows = 4, n_columns = 2) + self.__modifier_buttons = [] + self.__modifier_buttons.append(("Control", + Gtk.CheckButton.new_with_mnemonic("_Control"), + Gdk.ModifierType.CONTROL_MASK)) + self.__modifier_buttons.append(("Alt", + Gtk.CheckButton.new_with_mnemonic("A_lt"), + Gdk.ModifierType.MOD1_MASK)) + self.__modifier_buttons.append(("Shift", + Gtk.CheckButton.new_with_mnemonic("_Shift"), + Gdk.ModifierType.SHIFT_MASK)) + self.__modifier_buttons.append(("Meta", + Gtk.CheckButton.new_with_mnemonic("_Meta"), + Gdk.ModifierType.META_MASK)) + self.__modifier_buttons.append(("Super", + Gtk.CheckButton.new_with_mnemonic("S_uper"), + Gdk.ModifierType.SUPER_MASK)) + self.__modifier_buttons.append(("Hyper", + Gtk.CheckButton.new_with_mnemonic("_Hyper"), + Gdk.ModifierType.HYPER_MASK)) + # <CapsLock> is not parsed by gtk_accelerator_parse() + # <Release> is not supported by XIGrabKeycode() + for name, button, mask in self.__modifier_buttons: + button.connect("toggled", self.__modifier_button_toggled_cb, name) + + table.attach(self.__modifier_buttons[0][1], 0, 1, 0, 1) + table.attach(self.__modifier_buttons[1][1], 1, 2, 0, 1) + table.attach(self.__modifier_buttons[2][1], 2, 3, 0, 1) + table.attach(self.__modifier_buttons[3][1], 0, 1, 1, 2) + table.attach(self.__modifier_buttons[4][1], 1, 2, 1, 2) + table.attach(self.__modifier_buttons[5][1], 2, 3, 1, 2) + hbox.pack_start(table, True, True, 4) + self.pack_start(hbox, False, True, 4) + + def set_shortcut(self, shortcut = None): + if shortcut == None: + self.__accel_label.set_label("") + else: + self.__accel_label.set_label(shortcut) + + def get_shortcut(self): + return self.__accel_label.get_label() + + def __get_shortcut_from_buttons(self): + modifiers = [] + keycode = self.__keycode_entry.get_text() + if Gdk.keyval_from_name(keycode) == 0: + return None + + for name, button, mask in self.__modifier_buttons: + if button.get_active(): + modifiers.append(name) + if keycode.startswith("_"): + keycode = keycode[1:] + shortcut = "".join(['<' + m + '>' for m in modifiers]) + shortcut += keycode + return shortcut + + def __set_shortcut_to_buttons(self, shortcut): + (keyval, state) = Gtk.accelerator_parse(shortcut) + if keyval == 0 and state == 0: + return + for name, button, mask in self.__modifier_buttons: + if state & mask: + button.set_active(True) + else: + button.set_active(False) + self.__keycode_entry.set_text(shortcut.rsplit('>', 1)[-1]) + + def __update_accel_label(self): + shortcut = self.__get_shortcut_from_buttons() + can_add = shortcut != None + self.__accel_label.set_label(shortcut) + + def __modifier_button_toggled_cb(self, button, name): + self.__update_accel_label() + + def __keycode_entry_notify_cb(self, entry, arg): + self.__update_accel_label() + + def __keycode_button_clicked_cb(self, button): + out = [] + dlg = Gtk.MessageDialog(transient_for = self.get_toplevel(), + buttons = Gtk.ButtonsType.CLOSE) + message = _("Please press a key (or a key combination).\n" \ + "The dialog will be closed when the key is released.") + dlg.set_markup(message) + dlg.set_title(_("Please press a key (or a key combination)")) + + def __accel_edited_cb(c, path, keyval, state, keycode): + out.append(keyval) + out.append(state) + out.append(keycode) + dlg.response(Gtk.ResponseType.OK) + + model = Gtk.ListStore(GObject.TYPE_INT, + GObject.TYPE_UINT, + GObject.TYPE_UINT) + accel_view = Gtk.TreeView(model) + column = Gtk.TreeViewColumn(_("Shorcut Editor")) + renderer = Gtk.CellRendererAccel(accel_mode=Gtk.CellRendererAccelMode.OTHER, + editable=True) + renderer.connect('accel-edited', __accel_edited_cb) + column.pack_start(renderer, True) + column.add_attribute(renderer, 'accel-mods', 0) + column.add_attribute(renderer, 'accel-key', 1) + column.add_attribute(renderer, 'keycode', 2) + accel_view.append_column(column) + it = model.append(None) + area = dlg.get_message_area() + area.pack_end(accel_view, True, True, 0) + area.show_all() + id = dlg.run() + dlg.destroy() + if id != Gtk.ResponseType.OK or len(out) < 3: + return + keyval = out[0] + state = out[1] + keycode = out[2] + + for name, button, mask in self.__modifier_buttons: + if state & mask: + button.set_active(True) + else: + button.set_active(False) + + shortcut = Gtk.accelerator_name_with_keycode(None, + keyval, + keycode, + state) + shortcut = shortcut.replace('<Primary>', '<Control>') + self.__keycode_entry.set_text(shortcut.rsplit('>', 1)[-1]) + + +class KeyboardShortcutSelectionDialog(Gtk.Dialog): + def __init__(self, title = None, transient_for = None, flags = 0): + super(KeyboardShortcutSelectionDialog, self).__init__( + title = title, transient_for = transient_for, flags = flags) + self.__selection_view = KeyboardShortcutSelection() + self.vbox.pack_start(self.__selection_view, False, True, 0) + self.vbox.show_all() + + def set_shortcut(self, shortcut = None): + self.__selection_view.set_shortcut(shortcut) + + def get_shortcut(self): + return self.__selection_view.get_shortcut() + + + +if __name__ == "__main__": + dlg = KeyboardShortcutSelectionDialog(title = "Select test") + buttons = (_("_Cancel"), Gtk.ResponseType.CANCEL, + _("_OK"), Gtk.ResponseType.OK) + dlg.add_buttons(*buttons) + dlg.set_shortcut("<Shift>") + dlg.set_shortcut(None) + print((dlg.run())) + print((dlg.get_shortcut())) + |